はじめに
以下記事ではCloudFormationを使ってlambda単体をデプロイする方法について記載した。
CloudFormationを使ってlambda(node.js)環境を構築する
ただlambdaを使う上で単体で、つまり手動で実行するケースは少ない。ほとんどの場合、lambdaを実行させるためのトリガーとセットで使うことになる。そのため本記事ではトリガーとして、CloudWatchEventsを指定してlambda本体と合わせてデプロイする方法について説明する。
Lambdaをスケジュール起動するためのテンプレート記述
lambdaをスケジュール起動するための、CloudFormationのテンプレート記述は以下2つが必要になる。
- AWS::Events::Rule
- AWS::Lambda::Permission
AWS::Events::Ruleは、CloudWatchEventsの設定であり、AWS::Lambda::Permissionは実行したいlambdaとCloudWatchEventsを紐づけるための設定である。
以下、それぞれのテンプレート記述について説明し、最後に全体のテンプレートファイルを示す。
AWS::Events::Rule
CloudWatchEventsのテンプレート記述について以下に抜粋。
LambdaScheduleEvent:
Type: AWS::Events::Rule
Properties:
Description: ’schedule event for lambda’
ScheduleExpression: 'cron(0/1 * * * ? *)'
State: ENABLED
Targets:
- Arn: !GetAtt HelloworldLambdaFunction.Arn
Id: ScheduleEvent1Target
1分おきにHelloworldLambdaFunctionというlambdaを実行するCloudWatchEventsである。なおHelloworldLambdaFunctionは、同じテンプレートファイル内で定義したlambdaを設定する任意の名前である。
GetAttとはテンプレートファイル内で使用できる組み込み関数の1つであり、テンプレートファイル内で定義されたリソースとリソースの属性を指定して、その値を取得することができる。
GetAttの公式ドキュメントの説明は以下参照。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
またAWS::Events::Ruleのテンプレート記述のリファレンスは以下参照。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html
AWS::Lambda::Permission
lambdaとCloudWatchEventsを紐づけるための設定に関するテンプレート記述は以下の通りである。
LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref HelloworldLambdaFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt LambdaScheduleEvent.Arn
Lambdaの呼び出し元は、CloudWatchEvents(events.amazonaws.com)として同一テンプレート内で定義したLambdaScheduleEventのARNを指定する。また、起動するlambda(FunctionName)は組み込み関数の1つであるRef関数を使い、同一テンプレート内で定義したlambdaを取得する。
AWS::Lambda::Permissionの公式リファレンスは以下参照
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html
テンプレートファイル全体
上記、AWS::Events::Rule、AWS::Lambda::Permissionを追加して完成したテンプレートファイルは以下の通り。
AWSTemplateFormatVersion: 2010-09-09
Resources:
HelloWorldLambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: lambda-function-name
Handler: index.handler
Role: arn:aws:iam::1234567890:role/LambdaRole
Runtime: nodejs8.10
Timeout: 10
Code:
S3Bucket: bucket-name
S3Key: app/deploy/lambda.zip
Tags:
-
Key: COST
Value: app-lambda
LambdaScheduleEvent:
Type: AWS::Events::Rule
Properties:
Description: ’schedule event for lambda’
ScheduleExpression: 'cron(0/1 * * * ? *)'
State: ENABLED
Targets:
- Arn: !GetAtt HelloworldLambdaFunction.Arn
Id: ScheduleEvent1Target
LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref HelloworldLambdaFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt LambdaScheduleEvent.Arn
本テンプレートファイルでCloudFormationでスタックを作成(デプロイ)すると、1分ごとに起動されるlambdaが立ち上がる。
CodeBuldからaws cliを使ってCloudFormationを実行する場合
参考までに、もしCodeBuildからaws cli経由でCloudFormationを実行して、本記事の構成でデプロイする場合、CodeBuildに以下ポリシーを付けたRoleを付与する必要がある。
- CloudWatchEventsFullAccess
- lambda:* (カスタムポリシー)
- AmazonS3FullAccess
- iam:PassRole (カスタムポリシー)
- cloudformation:CreateStack (カスタムポリシー)
- cloudformation:DeleteStack (カスタムポリシー)
- cloudformation:UpdateStack (カスタムポリシー)
- cloudformation:DescribeStacks (カスタムポリシー)
なおCodeBuildを使ったデプロイについては以下記事に記載している。
aws CodeBuildを使ってlambda(node.js)環境をテスト→デプロイする
以上、参考まで。
まとめ
本記事ではCloudFormationを使ってスケジュール起動するlambdaのデプロイする方法について記載した。
awsで開発作業を自動化するのまとめ記事
本記事はawsで開発作業を自動化するシリーズの1つです。その他の記事については以下を参照ください。
aws環境でnode.js、lambda、CodeCommit、CodeBuild、CloudFormation、CodePipelineを使って開発作業を自動化する