1

I am using CloudFormation to create a stack but I am currently struggling on the template writing process. This is my JSON template:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "LambdaFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Code": {
                    import json
                    import boto3

                    s3 = boto3.client('s3')

                    def lambda_handler(event, context): # Get bucket name from the S3 event
                    print(event)

                    bucket_name = event['detail']['requestParameters']['bucketName']

                    # Create a bucket policy
                    bucket_policy = json.dumps({
                            s3 = boto3.client('s3')

                            def lambda_handler(event, context): # Get bucket name from the S3 event
                            print(event)

                            bucket_name = event['detail']['requestParameters']['bucketName']

                            # Create a bucket policy
                            bucket_policy = json.dumps({
                                "Version": "2012-10-17",
                                "Statement": [{
                                        "Sid": "MustBeEncryptedAtRest",
                                        "Effect": "Deny",
                                        "Principal": "*",
                                        "Action": "s3:PutObject",
                                        "Resource": [
                                            "arn:aws:s3:::{}".format(bucket_name),
                                            "arn:aws:s3:::{}/*".format(bucket_name)
                                        ],
                                        "Condition": {
                                            "StringNotEquals": {
                                                "s3:x-amz-server-side-encryption": [
                                                    "AES256",
                                                    "aws:kms"
                                                ]
                                            }
                                        }
                                    },
                                    {
                                        "Sid": "MustBeEncryptedInTransit",
                                        "Effect": "Deny",
                                        "Principal": "*",
                                        "Action": "s3:*",
                                        "Resource": [
                                            "arn:aws:s3:::{}".format(bucket_name),
                                            "arn:aws:s3:::{}/*".format(bucket_name)
                                        ],
                                        "Condition": {
                                            "Bool": {
                                                "aws:SecureTransport": "false"
                                            }
                                        }
                                    }
                                ]
                            })
                        }
                        # Set the new policy s3.put_bucket_policy(Bucket = bucket_name, Policy = bucket_policy),
                        "Handler": lambda_handler,
                        "Role": ----
                        "Runtime": python3 .7
                    }
                }

yet I get an error on the "Code": import json line. I have even used different JSON validators yet I cant understand why it isnt well formed according to amazon CloudFormation. Any Ideas?

Chris Williams
  • 32,215
  • 4
  • 30
  • 68
notaproatbash
  • 436
  • 4
  • 13
  • I haven't used CloudFormation, but that sure as heck isn't valid JSON. For valid JSON, the entire value of the `Code` property would need to be in a string. Similarly, your `Handler` and `Runtime` properties are suspect. – T.J. Crowder Jul 14 '20 at 15:38
  • I have tried this already though – notaproatbash Jul 14 '20 at 15:39

1 Answers1

2

You can't use the Lambda function input like this, for JSON instead it should be formatted like the below example for the input.

"LambdaFunction": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": {
            "Fn::Join": [
              "\n",
              [
                "import json",
                "import boto3",
                "",
                "s3 = boto3.client('s3')",
                "",
                "def lambda_handler(event, context):",
                    "print(\"Do something\")"
              ]
            ]
          }
        },
        "Handler": "index.lambda_handler",
        "Role": {
          "Ref": "LambdaRole"
        },
        "Runtime": "python3.7"
      }
    }

Remember that CloudFormation is JSON or YAML which means it must parse, for Lambda you can either specify the function formatted for the language you're using or specify a Zip file instead.

Chris Williams
  • 32,215
  • 4
  • 30
  • 68
  • for some reason I thought wrapping the entire code section was the solution and couldnt figure out why it wasnt working. Thank you chris i can always count on you – notaproatbash Jul 14 '20 at 16:02
  • No problem, glad to help :) – Chris Williams Jul 14 '20 at 16:02
  • 2
    For what it's worth, yaml allows you to use syntax that's _so much nicer_. You can just put `ZipFile: |` and put your code as-is (following proper indentation of course) underneath; see https://stackoverflow.com/a/21699210/5317869 – PMah Jul 14 '20 at 16:11