こつつみ

コツコツ積み上げる

Lambda + CloudWatch EventのインフラをCloudFormationでコード化する

はじめに

この記事は、以下の記事にて説明したSlack botのインフラをCloudFormationでコード化したものです。

kotsutsumi.hatenablog.com

Lambda + CloudWatch Event の CloudFormation

作成するリソースはこちらです。

今回のLambdaは、CloudWatch EventのルールによりLambdaを起動します。 Lambdaのコードは、GitHub ActionsでAWS CLIにより直接配置する予定なので、今回はダミーとして超簡単なコードを記載しています。

def lambda_handler(event, context):
    print('dummy')

今回Yamlファイルで書いていますが、Jsonでも書くことができます。 しかし、Json形式ですとコメントが書けないといったデメリットがあります。

自分の書いたCloudFormationに適宜コメントを入れて解説します。

AWSTemplateFormatVersion: 2010-09-09

Description: Lambda for git commit count bot # 書かなくても良い

Parameters:  # 指定する値が無ければ書かなくても良い
  GitHubAccessToken:  # Parametersで定義したものは、Resourcesで使えるようになる
    Type: String  # Parametersの値は、CLIで指定したり、Web上で入力も出来ます
  SlackApiToken:
    Type: String

Resources:
  GitCommitCountBotLambda:  # 任意の名前に変更する
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: git-commit-count-bot  # 任意の名前に変更する
      Handler : lambda_function.lambda_handler  # 自身のコードに合わせて変更する
      Role: !GetAtt LambdaExecutionRole.Arn
      Runtime: python3.9
      Timeout: 10  # デフォルトは3秒だが、今回10秒にしている
      Environment:
        Variables:
          GITHUB_ACCESS_TOKEN: !Ref GitHubAccessToken  # 環境変数を設定できる
          SLACK_API_TOKEN: !Ref SlackApiToken  # !RefでParametersでしたいした値を使用できる
      Code:
        ZipFile: |  # ここでコードを書かなくてもS3に配置するなどでも大丈夫
          def lambda_handler(event, context):
              print('dummy')

  LambdaExecutionRole:   # 任意の名前に変更する
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: git-commit-count-bot-role
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup  # ログを取れるように許可を与える
                  - logs:CreateLogStream  # ログがいらなければRoleがなくても良い
                  - logs:PutLogEvents
                Resource:
                  - '*'

  CloudWatchEventRule:  # 任意の名前に変更する
    Type: AWS::Events::Rule
    Properties:
      Name: schedule-every-day-0am-event  # 任意の名前に変更する
      ScheduleExpression: cron(0 15 * * ? *)  # 日本時間で 0:00
      State: ENABLED
      Targets:
        - Arn: !GetAtt GitCommitCountBotLambda.Arn
          Id: git-commit-count-bot-lambda

  LambdaEventPermission:  # 任意の名前に変更する
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GitCommitCountBotLambda  # Type: AWS::Lambda::Functionで自身がつけた名に変更する
      Principal: events.amazonaws.com
      SourceArn: !GetAtt CloudWatchEventRule.Arn  # CloudWatch Eventと連携させる

番外編: デプロイ

今回AWSに適用する際にはAWS CLIで操作します。もちろんAWSのサイト上でファイルをしてCloudFormationのコードを適用することも出来ます。

自分が使用したコマンドは以下である。自分がハマったエラーとして --capabilities CAPABILITY_NAMED_IAM を指定しなかったことです。

CloudFormationがスタックを作成するために、特定の機能が含まれていることを明示的に示す必要があ理ます。

  • IAMリソースがある場合は、CAPABILITY_IAMかCAPABILITY_NAMED_IAMが必要になる
  • カスタム名のIAMリソースがある場合はCAPABILITY_NAMED_IAMを指定する
  • 指定がないとAWSCloudFormationはInsufficientCapabilitiesエラーを返す

今回、IAM Roleを作成しているので、--capabilitiesで指定する必要があります。 ${{ secrets.~~ }} はGitHub Actionsの指定です。実際には、そこに環境変数の値を入力します。

aws cloudformation deploy --template-file cloudformation/git_commit_count_bot.yml --stack-name git-commit-count-bot-cfn --capabilities CAPABILITY_NAMED_IAM --parameter-overrides GitHubAccessToken=${{ secrets.ACCESS_TOKEN }} SlackApiToken=${{ secrets.SLACK_API_TOKEN }}

ちなみにLambdaにCLIで直接デプロイする方法は以下です。

aws lambda update-function-code --function-name git-commit-count-bot --zip-file fileb://${{ env.ZIP_FILE_NAME }} --publish

自分は上記のことをGitHub Actionsで行っています。参考にコードを置いておきます。

github.com

最後に

今回CloudFormationでコード化に至ったのには、以下の理由からである。

  • AWS初学者を導く体系的な動画学習サービス AWS CloudTech で学んだ
  • 会社でCloudFormationを使うことになった
  • CI/CDを構築したい

自動テストは大体行える環境を作ってはいるが、自動デプロイに関しては無知だったので、とても良い経験になった。 今回CloudFormationを学んだことで、会社でもすんなり実装できて良かった。

CloudFomationは、AWS CloudTechで学んだ。とても分かりやすく初学者にとって有効だった。 自分は、AWS CloudTechに入ってAWS SAAの資格をとって、組み込みエンジニアからWebエンジニアに社内転職した人なので、おすすめします。

aws-cloud-tech.com