8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub ActionsでAWS Lambdaを簡単かつ爆速でデプロイしよう!【Python編】

Last updated at Posted at 2025-09-05

はじめに

2025年8月にAWS Lambdaのアップデートがあり,デプロイ用のアクションがaws-actionsより提供されるようになりました!
これによって従来の方法よりも簡単にかつ高速にLambda関数をデプロイすることができるようになったのでその方法をまとめました.
次回の記事ではTypescript編を予定しています.

このアップデートの何が嬉しいのか

従来のデプロイ方法

  • AWS CLIを使用してデプロイする
  • SAMなどのIaCを使用してデプロイする

従来はこの2つの方法がありました.しかし,以下のような課題もありました.

従来のデプロイ方法の課題

AWS CLIの課題

  • デプロイ手順をシェルスクリプトにまとめることが可能ではあるが,誰が実行しても同じ結果になる「再現性」に乏しかった.インフラの構成がコードとして管理されているわけじゃないので「現在どのような設定で何がデプロイされているのか」を正確に追跡するのが困難になりがちだった

SAMの課題

  • IaCなので学習コストが高い.
  • 裏側でCloudeFormationが動いている関係上,デプロイ速度がとても遅い

これらの課題があったため,個人開発等の小規模開発ではマネコン上でコードを編集して実装を行うことも珍しくなかったと思います.しかし,マネコンではローカルテストができなかったり,gitを使用したバージョン管理なども癖がありました.また,typescriptでコードを書くこともできません.

今回のアップデートでは,従来のデプロイ方法の課題が解決され,ローカルから簡単かつ爆速でデプロイができるようになりました.

実装

今回はhelloというメッセージが入ったjsonが返ってくるシンプルなLambda関数をデプロイします.

ディレクトリ構成

├── .github
│   └── workflows
│       └── deploy_lambda.yml
└── hello_lambda
    ├── __init__.py
    ├── app.py
    └── requirements.txt

app.pylambda_handlerのあるLambda関数本体です.hello_lambdaディレクトリが1つのLambda関数になります.

IAMユーザーを用意する

Lambda関数をデプロイするには,IAMユーザーのアクセスキーとシークレットアクセスキーを用意する必要があります.
手順を簡単にまとめます.

  1. マネコンにログインし,IAMを開く.

  2. [アクセス管理]メニューから[ポリシー] -> [ポリシーの作成]から,以下のような権限を持つポリシーを作成します.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "LambdaDeployPermissions",
                "Effect": "Allow",
                "Action": [
                    "lambda:GetFunctionConfiguration",
                    "lambda:CreateFunction",
                    "lambda:UpdateFunctionCode",
                    "lambda:UpdateFunctionConfiguration",
                    "lambda:PublishVersion"
                ],
                "Resource": "*"
            },
            {
                "Sid": "PassRolesDefinition",
                "Effect": "Allow",
                "Action": [
                    "iam:PassRole"
                ],
                "Resource": [
                    "*"
                ]
            }
        ]
    }
    
  3. [アクセス管理]メニューから[ユーザー] -> [ユーザーの作成]で,さっきのポリシーをアタッチしたユーザーを作成します.
    ユーザー名などは好きにしてください.この作成したユーザーにはlambda-execution-roleをアタッチしてください.また,このlambda-execution-roleロールのARNをメモしておいてください.

  4. [セキュリティ認証情報] -> [アクセスキーを作成]で,作成したユーザーのアクセスキーを発行してください.
    作成したアクセスキーとシークレットアクセスキーをメモしておいてください.

  5. GitHubのリポジトリを開いて[Setting] -> [Secerts and variables]

  6. [Actions] -> [New repository secret]を3回して,それぞれにメモした文字列を以下のように保存します.

Name Secret
AWS_ACCESS_KEY_ID IAMユーザーのアクセスキー
AWS_SECRET_ACCESS_KEY IAMユーザーのシークレットアクセスキー
LAMBDA_ROLE_ARN IAMロールのARN
  1. AWS公式はアクセスキーの発行よりもOpenIDコネクト(OIDC)での認証を推奨しています.しかし,OIDCの説明をすると本筋とずれるため,今回はより一般的なAWS認証方法であるアクセスキーを使用します.
    OIDCを使用することで,AWS認証情報をGitHubシークレットとして保存しておく必要がなくなります.
  2. Lambda関数がs3やDynamoDBを使用する場合,それらを使用するための権限も付与してください.

ymlファイルを用意する

以下のymlがGitHub Actionsで動作するworkflowです.Deploy Lambdaステップで使用しているaws-actions/aws-lambda-deploy@v1.0.1が今回のアップデートで追加された新機能です.

name: Deploy-Lambda-Python

on:
  push:
    branches:
      - "main"
  pull_request:
    paths:
      - "**/*.py"
      - "**/deploy_lambda.yml"

permissions:
  id-token: write
  contents: read
defaults:
  run:
    working-directory: "hello_lambda"
env:
  PYTHON_VERSION: 3.13
  function-name: hello_lambda_actions
  lambda-role-arn: ${{ secrets.LAMBDA_ROLE_ARN }}
jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Setup python
        uses: actions/setup-python@v5
        with:
          python-version: "${{ env.PYTHON_VERSION }}"
      - name: Build
        run: pip install -r requirements.txt

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        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 Lambda
        uses: aws-actions/aws-lambda-deploy@v1.0.1
        with:
          function-name: ${{ env.function-name }}
          code-artifacts-dir: ./hello_lambda
          handler: app.lambda_handler
          runtime: python${{ env.PYTHON_VERSION }}
          role: ${{ env.lambda-role-arn }}
          timeout: 30

Deploy Lambdaステップの解説

Deploy Lambdaステップでは,今回アップデートにより提供が開始されたaws-actions/aws-lambda-deploy@v1.0.1を使用しています.このアクションに,以下のような設定をしてデプロイしています.

  1. function-name
    必須です.これが関数名になります.
  2. code-artifacts-dir
    Zip形式でデプロイする場合,どのディレクトリにLambda関数が置かれているかを示すパスです.
  3. handler
    Lambda関数が実行された時に,最初に呼び出す処理を指します.この指定の場合,app.pylambda_handlerという関数が呼び出されることになります.
  4. runtime
    Lambda関数の実行環境です.今回の場合はpython3.13を指定しています.
  5. role
    Lambda関数に与えるロールです.
  6. timeout
    Lambda関数のタイムアウト時間(秒)です.今回は30秒に設定しました.

デプロイする関数を用意する

hello_lambda
    ├── __init__.py      <- 空のファイル
    ├── app.py         <- lambda_hundlerのあるファイル
    └── requirements.txt <- 依存ライブラリを記述しておくファイル

init.py

空のファイルを用意してください

app.py

message: helloを返すだけのシンプルなlambda_handlerです.

import json


def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps(
            {
                "message": "hello",
            }
        ),
    }

requirement.txt

今回のapp.pyでは標準ライブラリしか使用していないので空です.

これで準備は完了です.mainブランチへのpushかプルリクエスト作成時,更新時にLambda関数のデプロイが完了します.デプロイが完了したことにより,マネコンで以下のように確認することができ,[Test]を行うこともできます.

スクリーンショット 2025-08-28 21.40.07.png

付録

より実用的にデプロイを行うため,付録を3つ用意しました.

付録1:環境変数も用意したい

マネコン上の設定で環境変数をぽちぽち設定するのがめんどくさいという人も少なくないと思います.aws-actions/aws-lambda-deploy@v1.0.1では,environmentパラメータをサポートしており,これを使用することによって環境変数の設定を行うことができます.

環境変数を使用するため,変更したDeploy Lambdaステップのみを載せると以下のようになります.

      - name: Deploy Lambda
        uses: aws-actions/aws-lambda-deploy@v1.0.1
        with:
          function-name: ${{ env.function-name }}
          code-artifacts-dir: ./hello_lambda
          handler: app.lambda_handler
          runtime: python${{ env.PYTHON_VERSION }}
          role: ${{ env.lambda-role-arn }}
          timeout: 30
          environment: |
            {
              "YOUR_ENV_VAR_1": "<environment-val1>",
              "YOUR_ENV_VAR_2": "<environment-val2>"
            }

jsonで環境変数を設定することができます.
実用的に使用するためには,アクセスキーやシークレットアクセスキーにしたように,GitHubのsecretに登録しておき,その内容をデプロイするのがいいと思います.そうすれば複数のLambda関数で共通の環境変数を使用する時にとても楽ができます.

付録2:ローカルでも実行したい

Deploy前にそのままローカルで動作を確認したい時はapp.pyにモックと__main__を用意して,以下のようにするとローカルでも動作を確認することができます.
ユニットテストも同様にlambda_handlerを呼び出すことで実装することができます.

import json


def lambda_handler(event, context):
    """
    AWS Lambdaで実行されるメインの関数。
    """
    return {
        "statusCode": 200,
        "body": json.dumps(
            {
                "message": "hello_lambda!",
            }
        ),
    }


def main():
    mock_event = {}
    mock_context = {}

    # lambda_handlerを直接呼び出し、結果を表示
    response = lambda_handler(mock_event, mock_context)
    print("Lambda function response:")
    print(json.dumps(response, indent=4))


# スクリプトが直接実行された場合にmain()を呼び出す
if __name__ == "__main__":
    main()

付録3:外部ライブラリを使用したい

外部ライブラリrequestsを使用して,pokeAPIを使用したプログラムを作成しました.

import json
import requests


def lambda_handler(event, context):
    """
    PokeAPIを呼び出してポケモンの情報を取得するLambdaハンドラ関数
    """
    pokemon_id = "25"  # ピカチュウのID
    api_url = f"https://pokeapi.co/api/v2/pokemon/{pokemon_id}"

    try:
        # PokeAPIにGETリクエストを送信
        response = requests.get(api_url)

        # レスポンスが成功したかチェック (ステータスコード 200)
        response.raise_for_status()

        # レスポンスのJSONをパース
        data = response.json()
        pokemon_name = data.get("name")

        # 成功レスポンスを返す
        return {
            "statusCode": 200,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps(
                {
                    "message": "Successfully fetched data from PokeAPI!",
                    "pokemonName": pokemon_name,
                }
            ),
        }

    except requests.exceptions.RequestException as e:
        # API呼び出しでエラーが発生した場合
        print(f"Error: {e}")
        return {
            "statusCode": 500,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps({"message": "Failed to fetch data from PokeAPI."}),
        }


# --- ローカルテスト用のコードを追加 ---
if __name__ == "__main__":
    # Lambda関数を直接呼び出し、結果をコンソールに表示する
    # eventとcontext引数にはNoneや空の辞書{}を渡す
    print("--- Running Local Test ---")
    result = lambda_handler({}, None)

    # 見やすいように整形して出力
    print(json.dumps(result, indent=2, ensure_ascii=False))
    print("--- End of Local Test ---")

ローカルでの実行はうまくいきますが,デプロイ後にマネコンでテストを行うと以下のようにエラーになります.
スクリーンショット 2025-08-29 13.47.52.png

ymlファイルのBuildステップでpip install -r requirements.txtを行っていますが,これはランナー環境にインストールするだけなので,Lmabdaが動く環境には存在しないからです.
そのため,Buildステップを以下のようにします.

      - name: Install dependencies to deployment package
        run: |
          pip install -r requirements.txt -t .

pip install-tオブションを使用してLambda関数のフォルダに対してライブラリをインストールするようにしました.

付録4:複数の関数を一斉にデプロイしたい

matrixを用いて,複数のLambda関数をデプロイできるようにしたワークフローが以下です.

name: Deploy-Lambda-Python

on:
  push:
    branches:
      - "main"
  pull_request:
    paths:
      - "**/*.py"
      - "**/deploy_lambda.yml"

permissions:
  id-token: write
  contents: read

env:
  PYTHON_VERSION: 3.13
  lambda-role-arn: ${{ secrets.LAMBDA_ROLE_ARN }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        lambda-function:
          - name: external_library_lambda
            directory: external_library_lambda
          - name: hello_lambda
            directory: hello_lambda
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup python
        uses: actions/setup-python@v5
        with:
          python-version: "${{ env.PYTHON_VERSION }}"

      - name: Install dependencies to deployment package
        working-directory: ${{ matrix.lambda-function.directory }}
        run: |
          pip install -r requirements.txt -t .

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        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 Lambda
        uses: aws-actions/aws-lambda-deploy@v1.0.1
        with:
          function-name: ${{ matrix.lambda-function.name }}
          code-artifacts-dir: ./${{ matrix.lambda-function.directory }}
          handler: app.lambda_handler
          runtime: python${{ env.PYTHON_VERSION }}
          role: ${{ env.lambda-role-arn }}
          timeout: 30
          environment: |
            {
              "YOUR_ENV_VAR_1": "<environment-val1>",
              "YOUR_ENV_VAR_2": "<environment-val2>"
            }

matrixは以下のようになっているため,external_library_lambdahello_lambdaの2つのLambda関数をデプロイしています.

matrix:
        lambda-function:
          - name: external_library_lambda
            directory: external_library_lambda
          - name: hello_lambda
            directory: hello_lambda

おわりに

今回は,2025年8月に新しく提供が開始されたGitHub Actions (aws-actions/aws-lambda-deploy) を使った,AWS Lambdaへのデプロイ方法を紹介しました.

これまでAWS CLIの再現性の問題や,SAMの学習コスト・デプロイ速度といった課題がありましたが,この新しいアクションを使えば、GitHubリポジトリから直接,簡単かつ高速にLambda関数をデプロイできます.これにより、CI/CDパイプラインの構築がこれまで以上に手軽になりました.

特に個人開発や小規模なプロジェクトでは,インフラの管理コストを抑えつつ,コードの変更を即座に反映できるこの方法は非常に強力な選択肢になると思います.ぜひ試してみてください.

冒頭でも触れましたが,次回はTypeScriptでの実装方法について解説する予定です.そちらもぜひご覧ください。

最後までお読みいただき、ありがとうございました.

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?