Skip to content

Github Actions で AWS Lambda への自動デプロイを実行する

github から AWS へのアクセスするための準備

IAM ID プロバイダの登録

IAM ダッシュボード画面の左にある「ID プロバイダ」を選択
「プロバイダの追加」からプロバイダを追加する
プロバイダのタイプ: OpenID Connect
プロバイダの URL: https://token.actions.githubusercontent.com
対象者: sts.amazonaws.com

自動デプロイ用 IAM ポリシーの作成

IAM ダッシュボード画面の左にある「ポリシー」を選択し「ポリシーの作成」から作成する。

アクション許可では必要な権限を選択する。
今回は Lamda のレイヤの更新・関数の更新・レイヤバージョンと関数の紐づけの修正が必要のため以下を選択 - PublishLayerVersion - UpdateFunctionCode - UpdateFunctionConfiguration - GetLayerVersion (Lambda 関数に新しいレイヤバージョンを適用するときに必要となる)

リソースでは自動デプロイしたい Lambda 関数・レイヤの ARN を指定する

Warning

レイヤのリソース指定ではレイヤ自体の ARN とバージョン付きの ARN の両方を指定する必要がある
最新のレイヤバージョンに対して許可を与える必要がるため、バージョン部分は「*」を使用する

  • arn:aws:lambda:ap-northeast-1:xxxxxxx:layer:layer-name
  • arn:aws:lambda:ap-northeast-1:xxxxxxx:layer:layer-name:*

適当にポリシー名を記載して作成する

自動デプロイ用の IAM ロールの作成

IAM ダッシュボード画面の左にある「ロール」を選択し「ロールを作成」からロールを作成する。
信頼されたエンティティタイプ: カスタム信頼ポリシー
カスタム信頼ポリシー:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "Federated": "<登録したIAM IDプロバイダのARN>"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
                    "token.actions.githubusercontent.com:sub": "repo:<Githubの組織名またはアカウント名>/<リポジトリ名>:ref:refs/heads/<ブランチ名>"
                }
            }
        }
    ]

自動デプロイ用の IAM ポリシーをアタッチする

適当にロール名を記載して作成する

Github Actions

name: Deploy to AWS Lambda

on:
  push:
    branches:
      - main

permissions:
  id-token: write # AWS認証の際にGitHubのOIDCプロバイダーからJWTを要求するために必要
  contents: read # required for actions/checkout

jobs:
  deploy:
    runs-on: ubuntu-latest

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

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.13"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pipenv
          pipenv requirements > requirements.txt

      # --- Lambda Layer 作成用: ライブラリをlayerディレクトリにインストール ---
      # 参考: https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-native-libraries:~:text=Working%20with%20built%20distributions%20(wheels)
      - name: Install requirements for Lambda Layer
        run: |
          mkdir -p layer
          pip install -r requirements.txt -t layer --platform manylinux2014_x86_64 --implementation cp --python-version 3.13 --only-binary=:all: --upgrade

      - name: Zip Lambda Layer
        run: |
          zip -r lambda_layer.zip layer

      # --- Lambda関数用: コードをzip ---
      # 解凍時にsrcフォルダは必要ないので、srcフォルダに移動してからzip化する
      - name: Zip source code
        run: |
          cd src
          zip -r lambda_function.zip *
          mv lambda_function.zip ../lambda_function.zip

      # --- AWS 認証 ---
      # https://zenn.dev/azunyan/articles/072b9644c17be9
      # https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ secrets.AWS_REGION}}

      # --- Lambda Layerのアップロード ---
      - name: Publish Lambda Layer
        id: publish_layer
        run: |
          LAYER_VERSION=$(aws lambda publish-layer-version \
            --layer-name ${{ vars.AWS_LAMBDA_LAYER_NAME}} \
            --zip-file fileb://lambda_layer.zip \
            --compatible-runtimes python3.13 \
            --query 'Version' --output text)
          echo "LAYER_VERSION=$LAYER_VERSION" >> $GITHUB_ENV

      # --- Lambda関数のデプロイ ---
      - name: Deploy to Lambda
        run: |
          aws lambda update-function-code \
            --function-name ${{ vars.AWS_LAMBDA_FUNCTION_NAME}} \
            --zip-file fileb://lambda_function.zip

      # --- Lambda関数にLayerをアタッチ ---
      - name: Update Lambda function to use new Layer
        run: |
          aws lambda update-function-configuration \
            --function-name ${{ vars.AWS_LAMBDA_FUNCTION_NAME}} \
            --layers arn:aws:lambda:${{ secrets.AWS_REGION }}:${{ secrets.AWS_ACCOUNT_ID }}:layer:${{ vars.AWS_LAMBDA_LAYER_NAME}}:$LAYER_VERSION

注意点は以下の通り

AWS への認証情報はハードコーディングしない。GitHub の Secret 機能を利用する

登録したレイヤのバージョンは Lamda 関数に最新レイヤをアタッチするのに必要になる。
そのため Lambda レイヤのアップロード時にレスポンスを --query 'Version' で Version 情報のみに絞り、それを変数 LAYER_VERSION に格納、その後環境変数に登録し、レイヤアタッチ時に参照するようにしている。

AWS Lambda では利用するライブラリはレイヤに登録する必要がある。
Python の場合、純粋に Python のみで書かれたライブラリであればよいが、pandas や numpy のようなライブラリは内部で C/C++ が利用されている。
このようなライブラリの場合は pip によってダウンロードするライブラリを Lambda の実行環境に合わせてあげる必要がある。
そのためレイヤ登録用のライブラリを pip で DL するときはおまじない (--platform manylinux2014_x86_64 --implementation cp --python-version 3.13 --only-binary=:all:) が必要。
詳細は Working with .zip file archives for Python Lambda functions - AWS Lambda

参考

アマゾン ウェブ サービスでの OpenID Connect の構成 - GitHub Docs
Github Actionsを利用してAWS Lambdaに自動デプロイをしてみた | DevelopersIO
Working with .zip file archives for Python Lambda functions - AWS Lambda
【AWS】Lambdaで「No module named 'pydantic_core._pydantic_core'」エラーに遭遇した場合 #Python - Qiita
GitHub Actions で AWS と連携する CI/CD 環境を構築する