Skip to content

Instantly share code, notes, and snippets.

@chinchalinchin
Last active January 22, 2023 14:53
Show Gist options
  • Save chinchalinchin/60bfb548fc4f24cf905b0931a0ca5905 to your computer and use it in GitHub Desktop.
Save chinchalinchin/60bfb548fc4f24cf905b0931a0ca5905 to your computer and use it in GitHub Desktop.
CloudFormation Template - AWS Lambda With ECR, Secrets and VPC access
Description: A stack containing resources for an AWS Serverless Lambda function deployed through an AWS ECR. The Lambda will be given a role that grants it permission to access resources in a VPC. The IDs of the security group and subnet of the VPC resource must be specified as parameters. An optional parameter allows the application name to be set so resources will be tagged appropriately. In addition, secrets are delivered to the Lambda environment. These secrets must exist in the SecretManager store before this template can be spun up.
Parameters:
applicationName:
Type: String
Default: my-lambdas
Description: Name of the application
securityGroupID:
Type: String
Description: ID of the security group allowing ingress into the VPC resource Lambda is accessing.
subnetId:
Type: String
Description: ID of the subnet in which the VPC resource is deployed.
Resources:
LambdaECR:
Type: AWS::ECR::Repository
Description: ECR to hold image of Lambda function
Properties:
ImageScanningConfiguration:
ScanOnPush: true
RepositoryName: !Sub "${applicationName}-lambda"
RepositoryPolicyText:
Version: "2012-10-17"
Statement:
- Sid: ECRLambdaPolicy
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- "ecr:BatchGetImage"
- "ecr:GetDownloadUrlForLayer"
Tags:
- Key: Name
Value: !Sub ${application}-lambda-ecr
LambdaExecutor:
Type: AWS::IAM::Role
Description: Role to allow Lambda to basic access to VPC
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- "sts:AssumeRole"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
RoleName: !Sub ${applicationName}-lambda-executor
Lambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub ${applicationName}-lambda
Code:
ImageUri: !GetAtt LambdaECR.RepositoryUri
PackageType: Image
Role: !GetAtt LambdaExecutor.Arn
VpcConfig:
SecurityGroupIds:
- !Ref securityGroupID
SubnetIds:
- !Ref subnetID
Environment:
Variables:
# replace the following with appropriate secrets.
# this template assumes the Lambda is accessing an RDS.
RDS_DB: !Ref applicationName
RDS_HOST: !Sub '{{resolve:secretsmanager:${applicationName}-dbHost:SecretString}}'
RDS_USER: !Sub '{{resolve:secretsmanager:${applicationName}-dbUsername:SecretString}}'
RDS_PASSWORD: !Sub '{{resolve:secretsmanager:${applicationName}-dbPassword:SecretString}}'
Timeout: 90
Tags:
- Key: Name
Value: !Sub ${applicationName}-lambda
Outputs:
ECRUri:
Value: !GetAtt LambdaECR.RepositoryURi
Export:
Name: !Sub ${applicationName}-ECRUri
LambdaArn:
Value: !GetAtt Lambda.Arn
Export:
Name: !Sub ${applicationName}-LambdaArn
@cavalle
Copy link

cavalle commented Dec 15, 2022

@chinchalinchin thanks for the snippet! But… doesn't it fail when you run it for the first time because the ECR repo is empty and the Lambda function cannot fetch the image from it? Is there a way to workaround this?

@chinchalinchin
Copy link
Author

chinchalinchin commented Dec 15, 2022

@chinchalinchin thanks for the snippet! But… doesn't it fail when you run it for the first time because the ECR repo is empty and the Lambda function cannot fetch the image from it? Is there a way to workaround this?

You are correct. You could theoretically use something like AWSUtility::CloudFormation::CommandRunner to build and push the image to the ECR, and then add a DependsOn to the Lamba Function. I haven't tried this, though. CommandRunner scripts execute on an EC2, not locally, so there may be some setup for enabling Docker in the instance. Not sure.

@cavalle
Copy link

cavalle commented Dec 15, 2022

Excellent! Thanks for your response

@chinchalinchin
Copy link
Author

chinchalinchin commented Jan 22, 2023

Excellent! Thanks for your response

It randomly occured to me you could also use CodeBuild and make the Lambda dependent on a signal from the pipeline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment