GitHub Actionsで「 CloudFormationで構築したLambdaにS3を介さずに自動でデプロイする」を作る
はじめに
以前の記事でLambda + CloudWatch Event でインフラをコード化した。
今回は、GitHubで管理しているLambdaに上げるコードをmasterブランチを更新するたびに、 AWS S3を介さずにデプロイする方法について書く。
CloudFormation
CloudFormationについては以前の記事でも記載したが、再度掲載する。
AWSTemplateFormatVersion: 2010-09-09 Description: Lambda for git commit count bot Parameters: GitHubAccessToken: Type: String 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 Environment: Variables: GITHUB_ACCESS_TOKEN: !Ref GitHubAccessToken SLACK_API_TOKEN: !Ref SlackApiToken Code: ZipFile: | 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 - 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 Principal: events.amazonaws.com SourceArn: !GetAtt CloudWatchEventRule.Arn
GitHub Actions
GitHub Actionsとは?
GitHub Actionsとは、GitHub上でプッシュ・Issue・リリースなどのイベントをトリガーに起動し、対応するアクションを組み合わせてワークフローの自動化が行える。 いわゆるCI/CDツールです。類似のものですと、CircleCIやJenkinsなどがある。
ドキュメントや公開されているActionが多数あるので、これらを活用することで簡単に自動化の実装ができる。また、Github ActionsはYamlファイルを書くだけで良いため1つサンプルを準備すると、 同様の設定をエンジニア以外でも作成することができる。公開されているActionを使うことで自分で作らなくても良いものもある。
CloudFormationで構築したLambdaにS3を介さずに自動でデプロイする
適宜ファイルにコメントをつけて説明する
name: deploy on: push: branches: - master # masterにイベントが発生した場合をトリガーに起動する jobs: lambda-cd: name: Zip the code to be deployed to AWS Lambda runs-on: ubuntu-latest env: ZIP_FILE_NAME: package.zip # jobs全体に適用される環境変数を設定する steps: - name: Checkout uses: actions/checkout@v2 # 公式が提供しているGitHub Actions, イベントがあったブランチを仮想環境上に置く(チェックアウトする) - name: Setup Python uses: actions/setup-python@v2 # 公式が提供しているGitHub Actions, Python環境を準備する with: python-version: 3.9 - name: Zip the code run: | python -m pip install --upgrade pip pip install -r requirements.txt -t ./ # Lambda上でpip installできないので、サードパーティーのライブラリのソースコードを置く zip -r ${{ env.ZIP_FILE_NAME }} ./* # サードパーティーのライブラリのソースコード と 自身のコードをZip化する - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 # こちらもGitHub Actionsで公開されている, AWSの認証を行う with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 - name: deploy to AWS Lambda env: TEMPLATE_FILE: cloudformation/git_commit_count_bot.yml # CloudFormationのYamlファイルのパス STACK_NAME: git-commit-count-bot-cfn LAMBDA_FUNCTION_NAME: git-commit-count-bot run: | aws cloudformation deploy \ --template-file $TEMPLATE_FILE \ --stack-name $STACK_NAME \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides \ GitHubAccessToken=${{ secrets.ACCESS_TOKEN }} \ SlackApiToken=${{ secrets.SLACK_API_TOKEN }} # AWS上に環境を構築する aws lambda update-function-code \ --function-name $LAMBDA_FUNCTION_NAME \ # CloudFormationのYamlファイルに変更がない限り変更コードが反映されない --zip-file fileb://${{ env.ZIP_FILE_NAME }} --publish # そこで毎回Zipファイルを指定してLambdaのコードを更新する
このようにすれば、masterブランチを更新するたびに、AWS S3を介さずにデプロイできる。
最後に
今回はこのようにして行ったが、CloudFormationで AWS::Serverless::Function を用いれば簡単にできるかもしれないと後になって気づいた。 しかし、試していないので今度試してみて出来れば記事にしたいと思う。