Help us understand the problem. What is going on with this article?

CloudFormationを使ってCloudWatch Eventsでスケジュール起動されるlambdaをデプロイする

はじめに

以下記事では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のテンプレート記述について以下に抜粋。

template.yaml(抜粋)
  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を紐づけるための設定に関するテンプレート記述は以下の通りである。

template.yaml(抜粋)
  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を追加して完成したテンプレートファイルは以下の通り。

template.yaml
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を使って開発作業を自動化する

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away