Amazon EventBridgeでAWS CodePipelineの手動承認を自動化する方法

Amazon EventBridgeでAWS CodePipelineの手動承認を自動化する方法

Clock Icon2025.03.30

はじめに

AWS CodePipelineを利用したCI/CDパイプラインでは、本番環境へのデプロイ前に手動承認ステップを挿入することで、意図しないデプロイを防止できます。しかし、この手動承認プロセスは通常AWSマネジメントコンソールへのログインが必要となり、運用担当者の負担になることがあります。

本記事では、Amazon EventBridgeを活用してCodePipelineの手動承認を自動化・効率化する方法について解説します。日時を指定して手動承認を実行することで、運用担当者の負担を軽減し、よりスムーズなデプロイプロセスを実現します。

アーキテクチャ

今回実装するソリューションのアーキテクチャは以下のようになります。

  1. Amazon EventBridgeで指定した時間にイベントを発行
  2. イベントに応じてLambda関数が起動
  3. Lambda関数がCodePipelineの承認ステージを自動承認

IAMロールの作成

まずはLambda関数がCodePipelineの承認アクションを実行するためのIAMロールを作成します。

以下のポリシーをJSON形式で保存します(例:lambda-codepipeline-policy.json)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "codepipeline:GetPipelineState"
      ],
      "Resource": "arn:aws:codepipeline:REGION:ACCOUNT_ID:PIPELINE_NAME"
    },
    {
      "Effect": "Allow",
      "Action": [
        "codepipeline:PutApprovalResult"
      ],
      "Resource": "arn:aws:codepipeline:REGION:ACCOUNT_ID:PIPELINE_NAME/STAGE_NAME/ACTION_NAME"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "*"
    }
  ]
}

AWS CLIを使用してロールを作成します。

# ロールの作成
aws iam create-role --role-name LambdaCodePipelineApprovalRole \
  --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]}'

# ポリシーのアタッチ
aws iam put-role-policy --role-name LambdaCodePipelineApprovalRole \
  --policy-name CodePipelineApprovalPolicy \
  --policy-document file://lambda-codepipeline-policy.json

Lambda関数の作成

次に、CodePipelineの承認を実行するためのLambda関数を作成します。以下のPythonコードを使用します。

import json
import os

import boto3


def lambda_handler(event, context):
    # パラメータの取得
    pipeline_name = os.environ.get("PIPELINE_NAME")
    stage_name = os.environ.get("STAGE_NAME")
    action_name = os.environ.get("ACTION_NAME")

    client = boto3.client("codepipeline")

    # パイプラインの状態を取得
    response = client.get_pipeline_state(name=pipeline_name)

    # 指定したステージとアクションの承認トークンを取得
    token = get_approval_token(response, stage_name, action_name)

    if not token:
        return {
            "statusCode": 404,
            "body": json.dumps(
                f"No pending approval found for {pipeline_name}/{stage_name}/{action_name}"
            ),
        }

    # 承認を実行
    response = client.put_approval_result(
        pipelineName=pipeline_name,
        stageName=stage_name,
        actionName=action_name,
        result={
            "summary": "Automatically approved by EventBridge",
            "status": "Approved",
        },
        token=token,
    )

    return {
        "statusCode": 200,
        "body": json.dumps(
            f"Successfully approved {pipeline_name}/{stage_name}/{action_name}"
        ),
    }


def get_approval_token(pipeline_state, stage_name, action_name):
    """承認トークンを見つけて返す関数"""
    for stage in pipeline_state.get("stageStates", []):
        if stage["stageName"] != stage_name:
            continue

        for action in stage.get("actionStates", []):
            if action["actionName"] != action_name:
                continue

            execution = action.get("latestExecution", {})
            return execution.get("token")

    return None

この関数をZIPファイルに圧縮して、AWS CLIでLambda関数を作成します。

zip lambda_function.zip lambda_function.py
aws lambda create-function \
  --function-name CodePipelineAutoApproval \
  --runtime python3.13 \
  --handler lambda_function.lambda_handler \
  --role arn:aws:iam::<ACCOUNT_ID>:role/LambdaCodePipelineApprovalRole \
  --zip-file fileb://lambda_function.zip \
  --timeout 30 \
  --environment Variables="{PIPELINE_NAME=PIPELINE_NAME,STAGE_NAME=STAGE_NAME,ACTION_NAME=ACTION_NAME}"

必要に応じて、環境変数の値を実際のパイプライン名、ステージ名、アクション名に置き換えてください。

EventBridgeルールの設定

次に、Lambda関数を呼び出すEventBridgeルールを作成します。例として、2025年4月1日の12:00JSTに承認を実行するルールを作成します。

aws events put-rule \
  --name EventBridgeCodePipelineApproval \
  --schedule-expression "cron(0 3 1 4 ? 2025)" \
  --state ENABLED

aws events put-targets \
  --rule EventBridgeCodePipelineApproval \
  --targets "Id"="1","Arn"="arn:aws:lambda:<REGION>:<ACCOUNT_ID>:function:CodePipelineAutoApproval"

Lambda関数を呼び出すためのアクセス許可も追加します。

aws lambda add-permission \
  --function-name CodePipelineAutoApproval \
  --statement-id EventBridgeInvoke \
  --action lambda:InvokeFunction \
  --principal events.amazonaws.com \
  --source-arn arn:aws:events:<REGION>:<ACCOUNT_ID>:rule/EventBridgeCodePipelineApproval

実装のテスト

設定が完了したら、Lambda関数を手動で呼び出してテストすることができます。

aws lambda invoke \
  --function-name CodePipelineAutoApproval \
  --payload '{}' \
  response.json

response.jsonファイルを確認して、関数が正常に実行されたことを確認します。また、CodePipelineのコンソールで承認ステージが正常に完了したことも確認してください。

カスタマイズの例

以下に、本ソリューションの拡張例をいくつか紹介します。

  • 複数パイプラインの管理: 単一のLambda関数で複数のパイプラインの承認を管理
  • Slack連携: Slackのボタンアクションから承認を実行する仕組み
  • 条件付き承認: 特定の条件(例:テスト結果が合格の場合のみ)を満たした場合にのみ承認を実行
  • 承認通知: 承認実行後にチーム全体に通知を送信
  • 承認履歴の管理: 承認履歴をDynamoDBに記録し、監査証跡として保存
  • リージョン間デプロイ: 複数リージョンへの段階的なデプロイにおける承認の自動化
  • 時間帯制限: 業務時間内のみ自動承認を実行し、業務時間外は手動承認を要求

これらのカスタマイズを組み合わせることで、組織の要件に最適化されたCI/CDパイプラインを構築することができます。

おわりに

EventBridgeとLambdaを組み合わせることで、CodePipelineの手動承認を自動化・スケジュール化することができます。これにより、開発チームは定期的なデプロイプロセスを効率化し、手作業による負担を軽減できます。また、様々なイベントをトリガーとして承認を実行できるため、より柔軟なCI/CDワークフローを構築できます。

本記事で紹介したソリューションは基本的なものですが、ビジネス要件に合わせてカスタマイズすることで、より強力なデプロイ自動化を実現できるでしょう。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.