Purpose of this Lambda is to allow deploying any other package in us-east-1 region (regardless of your current execution region). This allows to use desired package as Lambda@Edge handler in CloudFront. Additionally, during deployment ZIP package it injects additional file with deployment time configuration.
edgedeploy Lambda needs following permissions:
Additionally you may want to add following policies to it’s role:
Specified destination function name.
Note: Even though Lambda is region-scoped, keep in mind that deploying Lambda@Edge always targets us-east-1, which means it’s good idea to use region name (eg. AWS::Region) in function name.
IAM role ARN.
Node.js runtime to use (keep in mind that Lambda@Edge only supports Node.js runtimes). By default 8.10 is used.
Name under which deployment configuration will be exposed in your package (by default it’s config.json).
Any configuration options that should be added at deploy-time to your package.
Deploy handler exposes entire PublishVersionResult object. Most important from it is a FunctionArn property, which refers to a published version of Lambda (which means it includes version classifier). It’s the property that you can use to assign published version as CloudFront association (see example below).
Note: Custom resource physical ID is set as deployed function ARN (master function, not published version).
CloudFrontDistribution: Type: "AWS::CloudFront::Distribution" Properties: DistributionConfig: Origins: - Id: "frontend-service" # origin configuration DefaultCacheBehavior: TargetOriginId: "frontend-service" AllowedMethods: - "DELETE" - "GET" - "HEAD" - "OPTIONS" - "PATCH" - "POST" - "PUT" CachedMethods: - "GET" - "HEAD" - "OPTIONS" Compress: false ViewerProtocolPolicy: "allow-all" LambdaFunctionAssociations: - EventType: "origin-request" # here is the Lambda@Edge integration point LambdaFunctionARN: !GetAtt "EdgeFunction.FunctionArn" Enabled: true # this role will be used by target Lambda - Lambda@Edge EdgeFunctionRole: Type: "AWS::IAM::Role" Properties: RoleName: !Sub "${AWS::Region}.edge" AssumeRolePolicyDocument: Statement: - Action: "sts:AssumeRole" Effect: "Allow" Principal: Service: - "edgelambda.amazonaws.com" - "lambda.amazonaws.com" ManagedPolicyArns: - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" # this role will be used by deploy Lambda EdgeDeployRole: Type: "AWS::IAM::Role" Properties: RoleName: !Sub "${AWS::Region}.edge-deploy" AssumeRolePolicyDocument: Statement: - Action: "sts:AssumeRole" Effect: "Allow" Principal: Service: - "lambda.amazonaws.com" Policies: - PolicyName: "AllowManagingLambdas" PolicyDocument: Version: "2012-10-17" Statement: - Action: - "s3:GetBucketLocation" - "s3:GetObject" - "s3:ListBucket" Effect: "Allow" Resource: # put your source bucket here - "arn:aws:s3:::chilldev-repository" - "arn:aws:s3:::chilldev-repository/*" - PolicyName: "AllowManagingLambdas" PolicyDocument: Version: "2012-10-17" Statement: - Action: - "iam:CreateServiceLinkedRole" - "lambda:CreateFunction" - "lambda:ListTags" - "lambda:TagResource" - "lambda:UntagResource" - "lambda:UpdateFunctionConfiguration" Effect: "Allow" Resource: - !Sub "*" - PolicyName: "AllowManagingEdgeLambdas" PolicyDocument: Version: "2012-10-17" Statement: - Action: - "lambda:AddPermission" - "lambda:CreateAlias" - "lambda:DeleteAlias" - "lambda:DeleteFunction" - "lambda:GetAlias" - "lambda:GetFunction" - "lambda:GetFunctionConfiguration" - "lambda:GetPolicy" - "lambda:ListVersionsByFunction" - "lambda:PublishVersion" - "lambda:RemovePermission" - "lambda:UpdateAlias" - "lambda:UpdateFunctionCode" Effect: "Allow" Resource: - !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:*" - PolicyName: "AllowPassingEdgeRole" PolicyDocument: Version: "2012-10-17" Statement: - Action: - "iam:PassRole" Effect: "Allow" Resource: - !GetAtt "EdgeFunctionRole.Arn" EdgeDeploy: Type: "AWS::Lambda::Function" Properties: FunctionName: "edge-deploy" Runtime: "java8" Code: # put your source bucket S3Bucket: "your-bucket" S3Key: "lambda-edgedeploy-0.0.1-standalone.jar" Handler: "pl.chilldev.lambda.edgedeploy.Handler::handle" MemorySize: 256 Description: "Lambda@Edge deployment." Timeout: 300 TracingConfig: Mode: "Active" Role: !GetAtt "EdgeDeployRole.Arn" EdgeFunction: Type: "AWS::CloudFormation::CustomResource" Properties: # reference to deploy function ServiceToken: !GetAtt "EdgeDeploy.Arn" functionName: !Sub "${AWS::Region}-edge" # reference to destination role roleArn: !GetAtt "EdgeFunctionRole.Arn" handler: "index.handler" memory: 256 timeout: 30 packageBucket: "your-bucket" packageKey: "your/lambda.zip"