kakakakakku blog

Weekly Tech Blog: Keep on Learning!

AWS Lambda Deploy GitHub Action: GitHub Actions から Lambda 関数をデプロイしよう

2025年8月7日にリリースされた AWS Lambda Deploy GitHub Action (aws-actions/aws-lambda-deploy) を使うと GitHub Actions から AWS Lambda 関数を直接デプロイできる🎉さっそく試してみた \( 'ω')/

aws.amazon.com

github.com

仕組み

AWS Lambda Deploy GitHub Action は AWS Lambda 関数がなければ作って,既にあったら更新する.

  • CreateFunction
  • UpdateFunctionCode
  • UpdateFunctionConfiguration

そして index.js の実装を確認すると AWS SDK for JavaScript v3 を使った実装になっているため,Terraform や AWS SAM / AWS CloudFormation / AWS CDK のような「状態」を管理する仕組みはなく,AWS SDK で命令型のように管理するイメージになる.あと AWS Lambda 関数を削除する仕組みはなく,不要になった場合は別途マネジメントコンソールなどから削除する必要がある🗑️

準備

AWS Lambda Deploy GitHub Action の管理する範囲は AWS Lambda 関数自体(設定とコード)になるため,たとえば AWS Lambda 関数に設定する IAM Role は自動で作られず,事前に作っておく必要がある.今回は Terraform で IAM Role を作る(最後に試すため AWS X-Ray のポリシーも追加してある).

resource "aws_iam_role" "main" {
  name = "sandbox-aws-lambda-deploy"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "basic" {
  role       = aws_iam_role.main.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_iam_role_policy_attachment" "xray" {
  role       = aws_iam_role.main.name
  policy_arn = "arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess"
}

よって,AWS Lambda Deploy GitHub Action はインフラとアプリケーション(と区別するべきかどうかは別として)で言うと「アプリケーション」に特化したツールと言えそう.もしくは「ライフサイクル」という観点だと「頻繁にデプロイするコードの管理」を GitHub Actions で実現するためのツールと表現することもできそう👀

サンプル

GitHub リポジトリに deploy-lambda-example.yml という GitHub Actions ワークフローのサンプルがあって,シュッと試すならこのワークフローにある環境変数を書き換えれば OK👌

github.com

デプロイ

今回は Python x uv で requests を使って外部 API (Dog API) にアクセスするコードをデプロイする🐍🐕️

ディレクトリ構造

.
├── .github
│   └── workflows
│       └── deploy.yml
├── application
│   ├── pyproject.toml
│   └── src
│       └── app.py
├── infrastructure
│   └── iam.tf
└── README.md

👾 application/src/app.py

import requests


def lambda_handler(event, context):
    print('Hello aws-actions/aws-lambda-deploy😀')

    response = requests.get('https://dog.ceo/api/breeds/image/random')
    print(response.json()['message'])

👾 application/pyproject.toml

[project]
name = "sandbox-aws-lambda-deploy"
version = "0.1.0"
description = "sandbox-aws-lambda-deploy"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "requests==2.32.4",
]

👾 .github/workflows/deploy.yml

GitHub Actions ワークフローのサンプル deploy-lambda-example.yml を参考に Python x uv のステップを追加した👌

name: Deploy to AWS Lambda

on:
  push:
    branches:
      - main

env:
  AWS_REGION: ap-northeast-1
  AWS_ROLE_TO_ASSUME: arn:aws:iam::000000000000:role/xxx
  LAMBDA_FUNCTION_NAME: sandbox-aws-lambda-deploy
  LAMBDA_CODE_ARTIFACTS_DIR: application/dist
  LAMBDA_HANDLER: app.lambda_handler
  LAMBDA_RUNTIME: python3.13
  LAMBDA_EXECUTION_ROLE: arn:aws:iam::000000000000:role/sandbox-aws-lambda-deploy

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

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

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        role-to-assume: ${{ env.AWS_ROLE_TO_ASSUME }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Install uv
      uses: astral-sh/setup-uv@v6

    - name: Install Python 3.13
      run: uv python install 3.13

    - name: Build using uv
      working-directory: application
      run: uv pip install . --python 3.13 --target ./dist

    - name: Deploy Lambda Function
      uses: aws-actions/aws-lambda-deploy@v1
      with:
        function-name: ${{ env.LAMBDA_FUNCTION_NAME }}
        code-artifacts-dir: ${{ env.LAMBDA_CODE_ARTIFACTS_DIR }}
        handler: ${{ env.LAMBDA_HANDLER }}
        runtime: ${{ env.LAMBDA_RUNTIME }}
        role: ${{ env.LAMBDA_EXECUTION_ROLE }}

デプロイ確認

AWS Lambda Deploy GitHub Action で AWS Lambda 関数をデプロイできた👏 実行結果も期待通りだった.

GitHub Actions のログを抜粋すると以下のように出力されていた📝

1回目だから Creating new Lambda function も出力されていた.

Creating new Lambda function: sandbox-aws-lambda-deploy
Lambda function created successfully
(中略)
Getting current configuration for function sandbox-aws-lambda-deploy
Updating function configuration for sandbox-aws-lambda-deploy
Waiting for function update to complete. Will wait for 5 minutes
Function update completed successfully
Lambda function deployment completed successfully

デプロイ2回目

今度はコードを書き換えて(v2 のところ)もう一度デプロイして,同じく期待通りだった.

import requests


def lambda_handler(event, context):
    print('Hello aws-actions/aws-lambda-deploy😀v2')

    response = requests.get('https://dog.ceo/api/breeds/image/random')
    print(response.json()['message'])

GitHub Actions のログを抜粋すると以下のように出力されていた📝

2回目だから Creating new Lambda function は出力されていなかった.

Getting current configuration for function sandbox-aws-lambda-deploy
Updating function configuration for sandbox-aws-lambda-deploy
Waiting for function update to complete. Will wait for 5 minutes
Function update completed successfully
Lambda function deployment completed successfully

デプロイ3回目

今度は AWS Lambda 関数の設定を変更する.メモリ (memory-size) とトレーシング (tracing-config) を追加で設定した👌

name: Deploy to AWS Lambda

on:
  push:
    branches:
      - main

env:
  AWS_REGION: ap-northeast-1
  AWS_ROLE_TO_ASSUME: arn:aws:iam::000000000000:role/xxx
  LAMBDA_FUNCTION_NAME: sandbox-aws-lambda-deploy
  LAMBDA_CODE_ARTIFACTS_DIR: application/dist
  LAMBDA_HANDLER: app.lambda_handler
  LAMBDA_RUNTIME: python3.13
  LAMBDA_EXECUTION_ROLE: arn:aws:iam::000000000000:role/sandbox-aws-lambda-deploy
  LAMBDA_MEMORY_SIZE: 256
  LAMBDA_TRACING_CONFIG: Active

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

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

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        role-to-assume: ${{ env.AWS_ROLE_TO_ASSUME }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Install uv
      uses: astral-sh/setup-uv@v6

    - name: Install Python 3.13
      run: uv python install 3.13

    - name: Build using uv
      working-directory: application
      run: uv pip install . --python 3.13 --target ./dist

    - name: Deploy Lambda Function
      uses: aws-actions/aws-lambda-deploy@v1
      with:
        function-name: ${{ env.LAMBDA_FUNCTION_NAME }}
        code-artifacts-dir: ${{ env.LAMBDA_CODE_ARTIFACTS_DIR }}
        handler: ${{ env.LAMBDA_HANDLER }}
        runtime: ${{ env.LAMBDA_RUNTIME }}
        role: ${{ env.LAMBDA_EXECUTION_ROLE }}
        memory-size: ${{ env.LAMBDA_MEMORY_SIZE }}
        tracing-config: '{"Mode": "${{ env.LAMBDA_TRACING_CONFIG }}"}'

もう一度デプロイすると期待通りに AWS Lambda 関数の設定が更新されていた❗️

GitHub Actions のログを抜粋すると以下のように出力されていた📝

今度は Configuration difference detected と出力されていて,既存の設定と差分がある箇所をちゃんと検出できていた.

Getting current configuration for function sandbox-aws-lambda-deploy
Configuration difference detected in MemorySize: 128 -> 256
Configuration difference detected in TracingConfig
Updating function configuration for sandbox-aws-lambda-deploy
Waiting for function update to complete. Will wait for 5 minutes
Function update completed successfully
Lambda function deployment completed successfully

README 修正

AWS Lambda Deploy GitHub Action を試しながら README に1箇所誤りがあることに気付いて修正しておいた✅️

github.com

まとめ

AWS Lambda Deploy GitHub Action を試してみた❗️GitHub Actions から簡単に AWS Lambda 関数をデプロイできて,既存の GitHub Actions ワークフローにすぐ組み込めるのもメリットだと思う.

あくまで個人的な感想だけど,ツールセットを増やしたくなくて,シンプルな AWS Lambda を管理したいという要件であれば選択肢になると思う.逆に Amazon SQS / Amazon EventBridge Scheduler などのトリガー設定も組み合わせたサーバレスアーキテクチャを構築するのであれば AWS SAM / AWS CDK / Terraform を GitHub Actions から実行するような仕組みを最初から選択するかな〜と思ったりもした💡

あとは Terraform で AWS Lambda 関数を "リソースとして" デプロイしつつ,AWS Lambda 関数のコードは AWS Lambda Deploy GitHub Action でデプロイするっていう分割パターンも考えたけど...どうだろう🤔そこまでメリットがあるようには感じないかなぁ.もうちょっと考えてみよう \( 'ω')/

関連ポスト