はじめに
この記事は、以下の記事にて説明したSlack botのインフラをCloudFormationでコード化したものです。
Lambda + CloudWatch Event の CloudFormation
作成するリソースはこちらです。
- Lambda
- Lambdaロール
- Lambdaパーミッション
- CloudWatch Eventのルール
今回の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で行っています。参考にコードを置いておきます。
最後に
今回CloudFormationでコード化に至ったのには、以下の理由からである。
自動テストは大体行える環境を作ってはいるが、自動デプロイに関しては無知だったので、とても良い経験になった。 今回CloudFormationを学んだことで、会社でもすんなり実装できて良かった。
CloudFomationは、AWS CloudTechで学んだ。とても分かりやすく初学者にとって有効だった。 自分は、AWS CloudTechに入ってAWS SAAの資格をとって、組み込みエンジニアからWebエンジニアに社内転職した人なので、おすすめします。