GitHub Actions workflowを使用してLambdaリソースを管理する

2025/02/14に公開

はじめに

AWS上のLambdaに直接ソースコードを入力して運用すると、GitHubのソースコードも適宜修正する必要があり、管理の手間が増します。
こうした課題を解決するのが、GitHub Actionsのワークフローです。
GitHub Actionsを活用すれば、ソースコードの管理をGitHub内で一元化できるだけでなく、CI/CDの自動化などさまざまなメリットを享受できます。

GitHub Actions workflowとは

GitHub Actions Workflow は、GitHub リポジトリ内で 自動化された処理(CI/CDパイプラインなど) を定義し、実行できる機能です。
ビルド・テスト・デプロイなどの作業を、コードのプッシュやプルリクエスト(PR)作成時に 自動実行することができます。

料金

  • パブリックリポジトリの場合
    • 無料で使用できます。
  • プライベートリポジトリの場合

前提

手順の実施前に以下が作成されていることを確認してください。
・GitHubにリポジトリが作成されていること
・GithubからAWSへアクセスするための認証情報(OIDC[OpenID Connect])
https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
・AWS上に管理対象となるLambdaが事前に作成されていること

手順

  1. IAM IDプロバイダの登録
  2. IAMポリシーの登録
  3. IAMロールの登録
  4. GitHub Actionsにシークレットを登録
  5. Yamlファイルの作成
  6. ワークフローの実行

IAM IDプロバイダの登録

GitHub ActionsからAWSへアクセスするためのOIDC認証を設定します。

デプロイ側の環境(AWS)
AWS側でIDプロバイダを作成します。
IAM > IDプロバイダ > プロバイダを追加

プロバイダのタイプ:OpenID Connect
プロバイダのURL:token.actions.githubusercontent.com
対象者:sts.amazonaws.com
上記の通り入力します。

サムプリントを取得してプロバイダを追加します。

IAMポリシーの登録

AWSのコンソールからIAMを開きます。
左タブのアクセス管理>ポリシーから「ポリシーの作成」を押下します。
ポリシーエディタでJSONを選択し下記を貼り付けます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:UpdateFunctionCode"
            ],
            "Resource": "{更新したいLambda関数のARNを指定 ※複数指定可}"
        }
    ]
}

「次へ」を押下し、
ポリシー名を入力後「ポリシーの作成」を押下します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:UpdateFunctionCode"
            ],
            "Resource": [
                "arn:aws:lambda:ap-northeast-1:{ACCOUNT_ID}:function:{ワークフロー名}"
            ]
        }
    ]
}

IAMロールの登録

左タブからロールを開きます。
「ロールの作成」を押下し信頼されたエンティティタイプはカスタム信頼ポリシーを選択します。
下記ステートメントを適宜書き換えてから貼り付けて「次へ」を押下します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::{ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:{対象レポジトリ}:*"
                }
            }
        }
    ]
}

許可ポリシーは作成したIAMポリシーを選択し「次へ」を押下します。
ロール名を入力後、「ロールを作成」を押下します。

GitHub Actionsにシークレットを登録

Githubの対象リポジトリ画面を開き、[Settings] > [Environments] を開きます。
「New Environment」で対象のブランチ名を入力し新しいEnvironmentを作成してください。
対象の「Environment」画面内の[New repository secret]を押下します。「Add Environment secrets」から下記ロールを追加してください。

Name Value
AWS_LAMBDA_WORKFLOW_ROLE_ARN 作成したLambdaのIAMロール名

workflow実行用Yamlファイルの作成

.github/workflows/配下にymlファイルを新規作成します。
下記ソースファイルをコピーし貼り付けてください。
対象パス、対象ブランチ名はご自身の環境に合わせて記載してください。
.github/workflows/lambda-workflow.yml

name: lambda-workflow

# 指定したブランチのプルリクエスト時に、対象パス配下のファイルで変更があったとき、ワークフローが実行
on:
  pull_request:
    types:
      - closed
    paths:
      - '{対象パス}/**'
    branches:
      - {対象ブランチ名}

jobs:
  build_and_deploy_lambda:
    if: ${{ github.event.pull_request.merged == true }}
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    # ブランチ名から環境GitHubの環境変数を指定
    environment: ${{ github.event.pull_request.base.ref }}
    # リポジトリをチェックアウト
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
    # AWS CLI を設定
      - name: Configure AWS CLI
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ secrets.AWS_LAMBDA_WORKFLOW_ROLE_ARN }}
          aws-region: ap-northeast-1
    # 変更があったファイルのディレクトリのみ抽出
      - name: Find Changed Lambda Directories
        id: find_changed_dirs
        run: |
          if [ -z "${{ github.event.pull_request.base.sha }}" ] || [ -z "${{ github.sha }}" ]; then
            echo "Error: Commit SHA is missing."
            exit 1
          fi
          BASE_COMMIT=$(git merge-base "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}")
          echo "Base Commit: $BASE_COMMIT"
          CHANGED_FILES=$(git diff --name-only "$BASE_COMMIT" "${{ github.sha }}")
          CHANGED_DIRS=$(echo "$CHANGED_FILES" | grep '^{対象パス}/' | cut -d'/' -f3 | sort | uniq | tr '\n' ' ')
          CHANGED_DIRS=$(echo "$CHANGED_DIRS" | tr -d '"')
          if [ -z "$CHANGED_DIRS" ]; then
            echo "No Lambda directories changed."
            echo "LAMBDA_DIRS=" >> $GITHUB_ENV
          else
            echo "Changed Lambda Directories: $CHANGED_DIRS"
            echo "LAMBDA_DIRS=$CHANGED_DIRS" >> $GITHUB_ENV
          fi

    # Lambda のデプロイ
      - name: Deploy Changed Lambda Functions
        if: env.LAMBDA_DIRS != ''
        run: |
          echo "Changed Lambda Directories: $LAMBDA_DIRS"
          for dir in $LAMBDA_DIRS; do
            # 変更があったファイルのディレクトリをzip化する
            echo "Processing directory: $dir"
            cd {対象パス}/$dir
            zip -r lambda_function.zip .
            FUNCTION_NAME="$dir"
           # デプロイ前に現在のバージョンを保存する
            echo "Publishing current version for Lambda function: $FUNCTION_NAME"
            aws lambda publish-version --function-name $FUNCTION_NAME
           # zipしたファイルをデプロイする
            echo "Deploying Lambda function: $FUNCTION_NAME"
            aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://lambda_function.zip
            cd - > /dev/null
          done


今回のワークフローで実現できる要件は以下の通りです。
・ワークフローが実行されるのは「対象パス配下でファイルの変更があったとき」かつ「対象ブランチにプルリクエストされたとき」をトリガーとする
・対象パス配下で、変更があったファイルのディレクトリのみデプロイ
・デプロイされる前にAWS上のソースコードを保存

ワークフローの実行

対象パス配下のソースファイルを更新し、作業ブランチにプッシュします。
対象ブランチでプルリクエストしマージが完了すると、Github Actionのワークフローが実行されます。AWSコンソールからLambdaのソースファイルの内容が新しく置き換わっていること、バージョンが発行されデプロイ前のソースコードが保存されていることを確認してください。

まとめ

GitHub Actionsを利用してLambdaへの自動デプロイを実装することができました。
ソースコードをアレンジすれば、他にもさまざまなワークフローの要件を実現できるので、引き続き検証してみようと思います。

株式会社トッカシステムズ

Discussion