Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloud Formation: S3 linked to Lambda gives The ARN is not well formed

I'm trying to use CloudFormation to deploy an S3 bucket that on ObjectCreate invokes a Lambda function.

Here are my resources:

"ExampleFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Handler": "index.lambda_handler",
                "Code": {
                    "S3Bucket": "bucketname",
                    "S3Key": "something.zip"
                },
                "Runtime": "python3.6",
                "Role": {
                    "Fn::GetAtt": [
                        "LambdaExecutionRole",
                        "Arn"
                    ]
                }
            }
        },
        "InputDataBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": "input-data",
                "NotificationConfiguration": {
                    "LambdaConfigurations": [
                        {
                            "Function": {
                                "Ref": "ExampleFunction"
                            },
                            "Event": "s3:ObjectCreated:*",
                            "Filter": {
                                "S3Key": {
                                    "Rules": [
                                        {
                                            "Name": "suffix",
                                            "Value": "zip"
                                        }
                                    ]
                                }
                            }
                        }
                    ]
                }
            }
        },
        "LambdaInvokePermission": {
            "Type": "AWS::Lambda::Permission",
            "Properties": {
                "Action": "lambda:InvokeFunction",
                "FunctionName": {
                    "Fn::GetAtt": [
                        "ExampleFunction",
                        "Arn"
                    ]
                },
                "Principal": "s3.amazonaws.com",
                "SourceAccount": {
                    "Ref": "AWS::AccountId"
                },
                "SourceArn": {
                    "Fn::Join": [
                        ":",
                        [
                            "arn",
                            "aws",
                            "s3",
                            "",
                            "",
                            {
                                "Ref": "InputDataBucket"
                            }
                        ]
                    ]
                }
            }
        }

I've tried to follow the documentation of the Notification Configuration, that says that there can be a circular dependency. However, if I follow the instructions I get the same error. Reference: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-notificationconfig.html

When I try to create the stack, the S3 always breaks it with error "The ARN is not well formed"

I've tried many things, but I always receive this same error.

like image 991
Miika Avatar asked Dec 30 '17 20:12

Miika


People also ask

How do I launch a CloudFormation stack with lambdas3?

To launch a CloudFormation stack with the LambdaS3.template file, use the CloudFormation console or the following AWS CLI command: Important: When you launch your CloudFormation stack, you must pass in your S3 bucket. For example: existing-bucket-for-lambda-notification

How to configure S3 notifications using lambda in AWS CloudFormation?

Create a CloudFormation template called LambdaS3.template that includes the following code. Important: In the following example, you add the S3 notification configuration to the S3NotificationLambdaFunction resource. You use the Lambda function CustomResourceLambdaFunction to add the S3 notification configuration for S3NotificationLambdaFunction.

How does the CloudFormation stack integrate with Amazon S3?

Important: When you launch your CloudFormation stack, you must pass in your S3 bucket. For example: existing-bucket-for-lambda-notification The stack creates a Lambda function and Lambda permissions for Amazon S3.

What is an Arn in AWS Lambda?

The ARN of the AWS Key Management Service (AWS KMS) key that's used to encrypt your function's environment variables. If it's not provided, AWS Lambda uses a default service key. A list of function layers to add to the function's execution environment. Specify each layer by its ARN, including the version.


1 Answers

I can get this to work as long as I know the S3 bucket name in advance (mybucketname below). If you don't know the bucket name in advance, then you can enhance this to request the bucket name as a stack parameter and it should still work. If you need the bucket name to be auto-generated (so you can't predict the name in advance) then this will not work and you'll have to go the create/update route.

Key thing here is to manually create the S3 bucket ARN from the known bucket name, rather than relying on "Ref": "InputDataBucket" to get the bucket name for you.

Also worth reading this support article.

{
    "AWSTemplateFormatVersion": "2010-09-09",

    "Description": "stackoverflow-48037497",

    "Resources" : {
        "ExampleFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Handler": "index.lambda_handler",
                "Code": {
                    "S3Bucket": "bucketname",
                    "S3Key": "something.zip"
                },
                "Runtime": "python3.6",
                "Role": {
                    "Fn::GetAtt": [
                        "LambdaExecutionRole",
                        "Arn"
                    ]
                }
            }
        },
        "LambdaInvokePermission": {
            "Type": "AWS::Lambda::Permission",
            "DependsOn": [ "ExampleFunction" ],
            "Properties": {
                "Action": "lambda:InvokeFunction",
                "FunctionName": {
                    "Fn::GetAtt": [
                        "ExampleFunction",
                        "Arn"
                    ]
                },
                "Principal": "s3.amazonaws.com",
                "SourceAccount": {
                    "Ref": "AWS::AccountId"
                },
                "SourceArn": "arn:aws:s3:::mybucketname"
            }
        },
        "InputDataBucket": {
            "Type": "AWS::S3::Bucket",
            "DependsOn": [ "ExampleFunction", "LambdaInvokePermission" ],
            "Properties": {
                "BucketName": "mybucketname",
                "NotificationConfiguration": {
                    "LambdaConfigurations": [
                        {
                            "Function": { "Fn::GetAtt" : [ "ExampleFunction", "Arn" ] },
                            "Event": "s3:ObjectCreated:*"
                        }
                    ]
                }
            }
        }
    }
}
like image 89
jarmod Avatar answered Sep 23 '22 23:09

jarmod