In this project we are going to using a Cloud Formation template to orchestrate a AWS::Event::Rule
that triggers a lambda execution role, that runs a lambda function every minute.
Scaffolding our project
You will need sam installed on your computer.
We will be using sam to create our project. We will do this by running sam init
.
You will be presented with an interactive terminal. I aim to make this post language agnostic but I chose the hello world template, using the go1.* runtime.
You will then have a skeleton project that looks something like;
drwxr-xr-x 9 some_user some_user_group 288B 3 Jul 11:07 .
drwxr-xr-x 29 some_user some_user_group 928B 3 Jul 14:19 ..
drwxr-xr-x 3 some_user some_user_group 96B 3 Jul 11:13 .aws-sam
-rw-r--r-- 1 some_user some_user_group 170B 2 Jul 15:41 Makefile
-rw-r--r-- 1 some_user some_user_group 5.3K 2 Jul 15:27 README.md
-rw-r--r-- 1 some_user some_user_group 55B 2 Jul 15:38 env.json
drwxr-xr-x 5 some_user some_user_group 160B 3 Jul 11:13 hello-world
-rw-r--r-- 1 some_user some_user_group 1.7K 3 Jul 11:07 template.yaml
The template.yaml file
We will need to make changes to the template.yaml file to create the resources need above.
Resources
We are going to need three resources; the lambda, the role to execute the lambda, and the schedule trigger.
The Lambda function
Nothing much to see here, but suffice to say that this is the lambda that we will be deploying. We will be watching the output in Cloudwatch.
package main
import (
"fmt"
"os"
"github.com/aws/aws-lambda-go/lambda"
)
func handler() {
fmt.Printf("hello %s", os.Getenv("LOCATION"))
}
func main() {
lambda.Start(handler)
}
The code below will create a lambda function, the function code lives in the ./hello_world dir, the lambda will be created with one environment variable named Location
with a value of World
.
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: hello-world
Runtime: go1.x
Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
LOCATION: World
The Event Trigger
We will need to create the trigger for the lambda. This particular trigger is configured using the cron syntax, and will run every minute. Note the target is the lambda function that we have configured above
HelloWorldFunctionEventTrigger:
Type: AWS::Events::Rule
Properties:
Description: Trigger lambda ever minute
ScheduleExpression: 'cron(* * * * ? *)'
State: ENABLED
Targets:
-
Arn: !GetAtt HelloWorldFunction.Arn
Id: HelloWorldFunctionEventTrigger
### The Permission
Finally we need to give the AWS::Events::Rule permission to run the AWS::Serverless::Function
PermissionForEventsToInvokeLambda:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt HelloWorldFunction.Arn
Action: "lambda:InvokeFunction"
Principal: "events.amazonaws.com"
SourceArn: !GetAtt HelloWorldFunctionEventTrigger.Arn
The full file
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
hello-world-lambda
Sample SAM Template for hello-world-lambda
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: hello-world
Runtime: go1.x
Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
LOCATION: World
PermissionForEventsToInvokeLambda:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt HelloWorldFunction.Arn
Action: "lambda:InvokeFunction"
Principal: "events.amazonaws.com"
SourceArn: !GetAtt HelloWorldFunctionEventTrigger.Arn
HelloWorldFunctionEventTrigger:
Type: AWS::Events::Rule
Properties:
Description: Trigger lambda ever minute
ScheduleExpression: 'cron(* * * * ? *)'
State: ENABLED
Targets:
-
Arn: !GetAtt HelloWorldFunction.Arn
Id: HelloWorldFunctionEventTrigger
Outputs:
HelloWorldFunction:
Description: "First Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
Building…
To build our project run sam build
.
Building function 'HelloWorldFunction'
Running GoModulesBuilder:Build
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
Gotcha: You must run the build command to propagate changes to deploy
Deploying…
sam deploy --region eu-west-1 --capabilities=CAPABILITY_IAM --stack-name hello-world-lambda --s3-bucket lambdas