😽

GitHub ActionsでAWS Lambdaを自動デプロイし、結果をSlackに通知する

2024/02/22に公開

はじめに

こんにちは、Bonです🐈
デプロイの自動化にはさまざまな手段がありますが、今回はGitHub Actionsを使用してAWS Lambdaを自動デプロイする機会があったので、その過程を記事としてまとめておきます。
ついでにSlack通知もやります。

構成

フロー

リポジトリ

|- .github
  |- workflows
    |- lambda_deploy.yaml
    |- slack_notification.yaml
|- lambda_function.py

手順

AWSマネジメントコンソールにログイン

対象アカウントのAWSマネジメントコンソールにログインします。

IAM IDプロバイダの追加

OIDCで、GitHubからAWSのリソースにアクセスするためのIDプロバイダを追加します。

  1. IAM > IDプロバイダを選択し、「プロバイダを追加」をクリックします。
  2. IDプロバイダの追加画面が表示されるので、以下の内容でプロバイダを追加します。
  • プロバイダのタイプ:OpenID Connect
  • プロバイダのURL:https://token.actions.githubusercontent.com
  • 対象者:sts.amazonaws.com

↓具体的な内容はこちら
https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

IAMポリシーの作成

AWS Lambdaに対する情報取得とコードの更新操作を許可をするためのポリシーを作成します。

  1. IAM > ポリシーを選択し、「ポリシーの作成」をクリックします。
  2. アクセス許可を指定 > ポリシーエディタでJSONタブを選択し下記情報を入力しIAMポリシーを作成します。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "lambda:GetFunction", 
                "lambda:UpdateFunctionCode"
            ],
            "Resource": ["<対象のLambda関数のARNを入力>"]
        }
    ]
}

↓JSONポリシー概要はこちら
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies.html#access_policies-json

IAMロールの作成

GitHub ActionsにAWS Lambdaの操作権限を付与するためのロールを作成します。

  1. IAM > ロールを選択し、「ロールを作成」をクリックします。
  2. 信頼されたエンティティを選択画面が表示されるので、以下の内容で次へ行きます。
  • 信頼されたエンティティタイプ:ウェブアイデンティティ
  • ウェブアイデンティティ:
    • アイデンティティプロバイダー:token.actions.githubusercontent.com
    • Audience:sts.amazonaws.com
    • GitHub組織:GitHubの組織名
    • GitHubリポジトリ:GitHubのリポジトリ名
  1. 許可を追加画面で、先ほど登録したIAMポリシーを追加しIAMロールを作成します。

Slackアプリの設定

Slackアプリの設定については、内容が長くなってしまうので手順は省略します🙇
↓以下の記事を参考にさせていただきました
https://qiita.com/seratch/items/28d09eacada09134c96c

GitHubリポジトリ側の設定

GitHub Actionsで使用するシークレット情報を登録します。

  1. 対象のリポジトリ > Settings > Secrets and variables > Actions > Repository secrets > 「New repository secrets」をクリックし、シークレットを登録します。
  • AWS_REGION:Lambda関数のあるリージョン
  • AWS_ROLE_ARN:先ほど作成したIAMロールのARN
  • SLACK_WEBHOOK_URL:slack apiアプリのWebhook URL

GitHub Actionsワークフローの作成

  1. デプロイジョブを実行するワークフローを作成します。
.github/workflows/lambda_deploy.yaml
name: Lambda Deploy

on:
  push:
    branches: 
      - 'develop' # developブランチにpushやmergeされた時をトリガーとしています

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    outputs:
      outcome: ${{ job.status }}

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ${{ secrets.AWS_REGION }}
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          role-session-name: GitHubActions

      - name: Package Lambda Function
        run: zip package.zip lambda_function.py

      - name: Update Lambda Function Code
        run: aws lambda update-function-code --function-name github-actions-test --zip-file fileb://package.zip --publish # Lambda関数のアップデートをしています

      - name: Check Lambda Status
        run: aws lambda wait function-updated-v2 --function-name github-actions-test # Lambda関数が呼び出せる状態か確認し、ジョブ完了としています

  slack_notification:
    if: ${{ always() }}
    needs: deploy
    uses: ./.github/workflows/slack_notification.yaml
    with:
      lambda-function-name: github-actions-test
      commit-id: ${{ github.sha }}
      status: ${{ needs.deploy.outputs.outcome }}
    secrets:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
  1. Slack通知ジョブを作成します。
.github/workflows/slack_notification.yaml
name: Slack Notification

on:
  workflow_call:
    inputs:
      lambda-function-name:
        required: true
        type: string
      commit-id:
        required: true
        type: string
      status:
        required: true
        type: string
    secrets:
      SLACK_WEBHOOK_URL:
        required: true

jobs:
  slack_notification:
    runs-on: ubuntu-latest

    steps:
      - name: Send Github Action trigger data to Slack
        id: slack
        uses: slackapi/slack-github-action@v1.25.0
        with:
          payload: |
            {
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "*デプロイ結果: ${{ inputs.status }}*\nLambda関数名: `${{ inputs.lambda-function-name }}`\nコミットID: `${{ inputs.commit-id }}`"
                  }
                }
              ]
            }
        env:
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

↓ワークフローについてはこちらで
https://docs.github.com/ja/actions/using-workflows/about-workflows

テスト

最後にLambda関数デプロイとSlack通知のテストをします。

  1. lambda_function.pyを適当に修正しプルリクエストを作成して、developブランチにマージします。
  2. Lambda関数が更新されていることを確認します。
  3. Slackに通知がくることを確認します。

これで完了です!

最後に

Slack通知を再利用可能にするためにworkflow_callを使用するところで少し詰まりましたが、シンプルな構成だったので簡単に実装することができました!
複合アクションも気になったので、今後も色々トライしていこうと思います。
https://docs.github.com/ja/actions/creating-actions/creating-a-composite-action

Discussion