- Create the CloudFormation template.
Resources components specify the AWS resources used. We need two resources for our use case: a role and a Lambda function with that role. The following is the basic structure of our CloudFormation template:
---
AWSTemplateFormatVersion: '2010-09-09'
Description: Building Lambda with AWS CloudFormation
Resources:
IamRoleLambdaExecution:
Type: AWS::IAM::Role
Properties:
# Properties for the role are shown later.
LambdaFunctionWithCF:
Type: AWS::Lambda::Function
Properties:
# Properties for the Lambda are shown later.
DependsOn:
- IamRoleLambdaExecution
I have also defined AWSTemplateFormatVersion and Description as a general practice, but they are optional. Note that properties for the IamRoleLambdaExecution and LambdaFunctionWithCF are not shown here. You may refer to further steps or use the template from the code files.
The role needs a trust relationship policy that allows the lambda to assume that role, and we need to attach a policy to the role that provides CloudWatch logging permissions. The AssumeRolePolicyDocument property specifies the trust relationship policy for the role:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
The policy is specified inline within the Policies property of the role:
Policies:
- PolicyName: 'lambda-with-cf-policy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
We will also define two more properties for the role, namely path and name:
Path: "/"
RoleName: "lambda-with-cf-role"
Our Lambda function will have the following basic configuration:
LambdaFunctionWithCF:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: 'serverless-cookbook'
S3Key: lambda-handler-with-pojos-0.0.1-SNAPSHOT.jar
FunctionName: first-lambda-with-cloud-formation
Handler: tech.heartin.books.serverlesscookbook.MyLambdaHandler::handleRequest
MemorySize: 512
Role:
Fn::GetAtt:
- IamRoleLambdaExecution
- Arn
Runtime: java8
Timeout: 15
DependsOn:
- IamRoleLambdaExecution
We specify the role as a dependency for the Lambda function, and use Fn::GetAtt to retrieve the role dynamically instead of hardcoding the name. Most of the other properties are self-explanatory.
A CloudFormation stack is a collection of AWS resources that you need to manage as a single unit. All the resources in a stack are defined by a CloudFormation template. When you delete the stack, all of its related resources are also deleted.
We can create a CloudFormation stack in different ways, including the following:
-
- Going through the Create Stack option within the CloudFormation service inside AWS Management Console
- Uploading directly from the Template Designer within the CloudFormation service inside AWS Management Console
- AWS CLI
In this recipe, I will use Designer, but in all other recipes I will be using AWS CLI. AWS CLI is the best way to deploy CloudFormation templates. Designer is also a good tool to visualize and validate your scripts.
- Create CloudFormation stack from Designer:
- Log in to AWS and go to CloudFormation service.
- Click on the Design template button to go to Designer. Within designer, you may do the following:
- Choose template language as YAML in the editor. (If you are using a JSON template, use JSON instead.)
- Select the Template tab in the editor.
- Copy and paste your template into the template editor window.
- Click on refresh on the Designer to see the template in the Design view.
- If any changes are required, you can either make changes within the Template tab or use the Components tab.
- If everything looks good, click on the upload button on the top left of the designer to launch the Stack creation wizard with the current template.
- Follow the wizard with defaults, and select the checkbox for I acknowledge that AWS CloudFormation might create IAM resources with custom names. Finally, click on Create Stack.
- Invoke our Lambda with AWS CLI as follows and verify:
aws lambda invoke \
--invocation-type RequestResponse \
--function-name first-lambda-with-cloud-formation \
--log-type Tail \
--payload '{"name":"Heartin"}' \
--profile admin \
outputfile.txt
Output can be viewed in the outputfile.txt file: