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.
lambda-edgedeploy Lambda needs following permissions:
iam:PassRole permission to pass role for the target Lambda@Edge.Additionally you may want to add following policies to it’s role:
arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole (if you want to see CloudWatch logs of resource handler execution);arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess (if you want more detailed tracing, package is built with X-Ray instrumentor).functionName (required) - stringSpecified 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.
functionDescription - stringFunction description.
roleArn (required) - ARNIAM role ARN.
runtime - stringNode.js runtime to use (keep in mind that Lambda@Edge only supports Node.js runtimes). By default 8.10 is used.
handler (required) - stringEntry point handler for invoking function.
memory (required) - integerMemory (in MBs) allocated for target function.
timeout (required) - integerTimeout (in seconds) for single invocation.
tracingMode - stringX-Ray tracing mode. Can be either PassThrough (default value) or Active.
packageBucket (required) - stringS3 bucket from which your destination Lambda package is located.
packageKey (required) - stringKey, where your target Lambda package is stored in S3.
configFile - stringName under which deployment configuration will be exposed in your package (by default it’s config.json).
config - key-value objectAny 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:
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:
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:::wrzasqpl-repository"
- "arn:aws:s3:::wrzasqpl-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:
Runtime: "java11"
Code:
# put your source bucket
S3Bucket: "your-bucket"
S3Key: "lambda-edgedeploy-1.0.1-standalone.jar"
Handler: "pl.wrzasq.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"