1.はじめに
1.1.まえがき
本ブログは以下項目の4つに分かれており、本ブログはその3つ目になります。
※ 本ハンズオンの全コードはこちらのGitHubリポジトリで参照できます。
項番 | ブログタイトル | 概要 |
---|---|---|
1 | 概要とAWS事前準備編 | Lambdaコンテナの仕組みと環境準備 |
2 | アプリケーションとCDK実装編 | LambdaアプリとCDKコードの解説 |
3 | GitHub Actions設定とデプロイ・挙動確認編(本ブログ) | CI/CDパイプライン構築 |
4 | トラブルシューティング集 | ハマりポイントと解決方法まとめ |
1.2.今回の内容
今回は CI/CDパイプライン部分を構築します。
GitHub Actionsの設定から、実際のデプロイ、そして動作確認まで進めていきます。
今回でやること:
- GitHub Actionsワークフローの作成:push時に自動実行されるCI/CDパイプライン
- 実際のデプロイと動作確認:CodeDeployによるカナリアリリースを体験
- GitHubシークレットの設定:安全な認証情報管理
前提条件:
以下が完了していることを前提とします:
2.ハンズオン
2.1.前提
2.1.1.実行環境
- Amazo SageMaker Studio Code Editor(IDE)で実施
Amazon SageMaker Studio Code Editor での 検証環境構築手順で構築済み
2.1.2.全体のファイル構成
- 以下のファイル構成を
Amazo SageMaker Studio Code Editor(IDE)
で構築する
■ 本手順の最終的なファイル構成
your-app/
├── .gitignore #【前回作成】
├── .github/
│ └── workflows/
│ └── deploy.yml #【★今回作成★】GitHub Actions ワークフロー定義
├── app/
│ ├── app.py #【前回作成】
│ └── Dockerfile #【前回作成】
└── cdk/ # AWS CDK アプリケーション (Python)
├── app.py #【前回作成】 CDK エントリーポイント
├── cdk.json #【前回作成】 CDK 設定ファイル
├── requirements.txt #【前回作成】 CDK 依存関係
├── .venv/ # Python 仮想環境
└── pipeline_stack/ # スタック定義を置くディレクトリ
├── __init__.py #【前回作成】
└── pipeline_stack.py #【前回作成】 CDK スタック定義 (Python)
2.1.3.アプリケーションの説明
- 機能: HTTP GETリクエストを受け取ると、事前に設定されたメッセージと、現在実行されているLambda関数のバージョン情報、リクエストIDをJSON形式で返却する。
- CI/CDパイプライン構築が目的のため、アプリケーション自体のロジックは最小限にしている。
2.1.4.インフラの説明
- AWS上にサーバーレスなAPIバックエンドと、そのCI/CDパイプラインを構築する。
■ 利用するリソース
項番 | 提供元 | リソース名 | 概要 |
---|---|---|---|
1 | AWS | AWS Lambda | アプリケーションコード(コンテナイメージ)を実行するコンピューティングサービス。 |
2 | AWS | Amazon ECR | Lambda関数で利用するDockerコンテナイメージを保存・管理するためのプライベートリポジトリです。GitHub Actionsでビルドしたイメージがここにプッシュされる。 |
3 | AWS | Amazon API Gateway | Lambda関数を外部(インターネット)からHTTPリクエストで呼び出すためのエンドポイントを作成 |
4 | AWS | AWS CodeDeploy | Lambda関数の新しいバージョンを安全にデプロイするためのサービスです。今回 カナリアリリース戦略を採用する。 |
5 | AWS | IAM | GitHub ActionsがAWSリソース(ECRへのプッシュ、CDKによるデプロイなど)を操作するため、またLambda関数やCodeDeployが必要な権限で動作するためのロールとポリシーを作成・管理。OIDC (OpenID Connect) を利用してGitHub ActionsとAWS間の安全な認証連携を実現する。 |
6 | AWS | AWS CDK (Cloud Development Kit) | 上記のAWSリソース構成をPythonコードで定義し、CloudFormationスタックとしてプロビジョニング(作成・更新)する。 |
7 | GitHub | GitHub Actions | GitHubリポジトリへのコードプッシュをトリガーとして、アプリケーションのビルド(Dockerイメージ作成)、ECRへのプッシュ、CDKによるAWS環境へのデプロイを自動化するCI/CDパイプラインを構築。 |
2.1.5.本項目での構築箇所
2.2.Github Actions作成
- CI/CDパイプラインの中心となるコード
- GitHubにプッシュされることで自動的に実行され、ビルド – デプロイまでを処理する。
2.2.1.GitHub Actionsワークフローの構成
- このワークフローは大きく以下4つの処理ステップに分かれている。
- 環境セットアップ:Python/Node.js/AWS CDK
- AWS認証:OIDCを使って安全にAWSにアクセス
- コンテナビルド & プッシュ:DockerイメージをECRに配置
- CDKデプロイ:クラウドインフラを自動デプロイ
2.2.3.Qualifierの取得
スタック定義で必要なECRリポジトリ名にはQualifier
が含まれます。
以下のコマンドをCloudShell環境で実行して、自身の環境の値を取得しコード内 # 環境変数定義 の ECR_REPOSITORY
を修正
# CDKが作成したS3バケット名を取得
BUCKET_NAME=$(aws cloudformation describe-stack-resources --stack-name CDKToolkit --query "StackResources[?ResourceType=='AWS::S3::Bucket'].PhysicalResourceId" --output text --region us-east-1)
# Qualifierを抽出(バケット名のパターン:cdk-{QUALIFIER}-...)
YOUR_QUALIFIER=$(echo "$BUCKET_NAME" | cut -d'-' -f2)
# 確認出力
echo $YOUR_QUALIFIER
2.2.4.ワークフローファイルの作成
# ファイル作成
mkdir -p your-app/.github/workflows
# デプロイワークフローの作成
cat > your-app/.github/workflows/deploy.yml << 'EOF'
name: Deploy Lambda Container via CDK (Python)
# トリガー設定:masterブランチプッシュ時に実行
on:
push:
branches:
- master # masterブランチへのプッシュでトリガー
# 権限設定(OIDC認証に必要)
permissions:
id-token: write # OIDC トークンを発行するために必要
contents: read # リポジトリのコンテンツを読み取るために必要
jobs:
deploy:
runs-on: ubuntu-latest
# 環境変数定義
env:
AWS_REGION: us-east-1 # 対象のAWSリージョン
CDK_STACK_NAME: LambdaPipelineStackPy # CDKスタック名 (app.pyのスタックIDと合わせる)
ECR_REPOSITORY: cdk-★★自身の Qualifier★★-container-assets-${{ secrets.AWS_ACCOUNT_ID }}-us-east-1
steps:
# Step 1: ソースコード取得
- name: Checkout code
uses: actions/checkout@v4
# Step 2: 環境セットアップ
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10' # CDKとLambdaで使うPythonバージョン
# Node.js 環境のセットアップ
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
# AWS CDK CLI (npm) のインストール
- name: Install AWS CDK CLI via npm
run: npm install -g aws-cdk
# Step 3: AWS認証(OIDC経由)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/GitHubAction-AssumeRoleWithAction
aws-region: ${{ env.AWS_REGION }}
# Step 4: ECRログイン
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
# Step 5: Python依存関係インストール
- name: Install Python dependencies
working-directory: ./cdk
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
# Step 6: イメージタグ決定(Gitコミットハッシュ使用)
- name: Set Image Tag
id: image_tag
run: echo "tag=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
# Step 7: Dockerイメージビルド & ECRプッシュ
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} # 例: 123456789012.dkr.ecr.us-east-1.amazonaws.com
IMAGE_TAG: ${{ steps.image_tag.outputs.tag }}
run: |
ECR_IMAGE_URI="$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
docker build -t $ECR_IMAGE_URI app
docker push $ECR_IMAGE_URI
echo "ecr_image_uri=$ECR_IMAGE_URI" >> $GITHUB_OUTPUT # 完全なURIを出力
# Step 8: CDKデプロイ実行
- name: Deploy CDK Stack
working-directory: ./cdk
env:
CDK_DEFAULT_REGION: ${{ env.AWS_REGION }}
run: |
echo "--- Running CDK deploy with image URI: ${ECR_IMAGE_URI} ---"
# -c オプションでコンテキストとしてイメージタグを渡す
cdk deploy ${{ env.CDK_STACK_NAME }} --require-approval never -c image_tag=${{ steps.image_tag.outputs.tag }} -vvv
EOF
3.CDKアプリ実行
- 今まで作ったコードを全てGitHubにプッシュすることで、これ以降プッシュされると GitHub Actionsが自動でビルド・デプロイを実行する。
3.1.デプロイの実行
プロジェクトをGitHubにプッシュすると、先ほど作成したGitHub Actionsワークフローが自動で起動します。
# Git初期化(初回のみ)
git init
# 全ファイルを追加
git add .
# コミット(最初のコミット)
git commit -m "Initial commit with Lambda container and CDK setup"
# GitHubリポジトリをリモートに追加 (初回のみ)
# git remote add origin https://github.com/YOUR_GITHUB_USERNAME/YOUR_REPO_NAME.git
# masterブランチにプッシュ(GitHub Actionsがトリガされる)
git push -u origin master # または main
3.2.GitHubでの確認画面への遷移
-
GitHub画面で「Update」の文字が表示される、押下することで「Details」が表示される。
-
「Details」を押下して以下、ビルド・デプロイまでのフローが表示される
3.2.1.カナリアリリースによる挙動の違い
-
CodeDeployのカナリアリリース戦略を用いているため、以下のような挙動をする。
- 1.新バージョンに10%のトラフィックを流す(5分間様子見)
- 2.問題なければ100%切り替え
- 3.エラーがあれば自動ロールバック
-
初回デプロイ: 約2分(リソース作成のみ)
-
2回目以降のデプロイ: 約7分(リソース更新 + CodeDeploy カナリアリリース待機時間 5分設定)
3.3.デプロイ後の動作確認
- デプロイ完了後、実際にAPIエンドポイントに
CloudShell
でアクセスして動作確認を実施します。
3.3.1.APIエンドポイントの確認
# スタック名を変数に設定
STACK_NAME="LambdaPipelineStackPy"
# CloudFormationスタックの出力からApiEndpointの値を取得
API_ENDPOINT=$(aws cloudformation describe-stacks --stack-name $STACK_NAME --query "Stacks[0].Outputs[?OutputKey=='ApiEndpoint'].OutputValue" --output text --region us-east-1)
# 取得したURLを確認
echo "取得した API エンドポイント URL: $API_ENDPOINT"
# エンドポイントへアクセス
curl "$API_ENDPOINT"
# 想定レスポンス:以下のようなレスポンスが Lambdaより返却される
{"message": "Hello from CDK !", "version_id": "3", "aws_request_id": "968a21ba-6f15-4cc7-bc15-a54e1b1a522d"}
3.3.2.設定変更の動作確認
- カナリアリリースを体験するために、アプリケーション設定を変更する。
項目 | 変数名 | 変更前 | 変更後 |
---|---|---|---|
タイムアウト | LAMBDA_TIMEOUT | 30 | 60 |
メッセージ | LAMBDA_MESSAGE | "Hello from CDK !" | Hello from Lambda ! |
your-app/cdk/pipeline_stack/pipeline_stack.py
を編集後、再度Git commitとpushを実行します
# 変更をコミット
git add .
git commit -m "Update Lambda settings: timeout and message"
git push
3.3.3.変更結果の確認
■ タイムアウト確認
# タイムアウト取得
aws lambda list-functions \
--query 'Functions[?contains(FunctionName, `LambdaPipelineStackPy-MyLambdaFunction`)].[Timeout]' \
--output text \
--region us-east-1
# 変更前: 30
# 変更後: 60 ←正しく更新されている!
■ メッセージ確認(カナリアリリース)
version_idも、新バージョンでは1つカウントアップされる
# 継続的にAPIにアクセス
curl "$API_ENDPOINT"
# 最初の5分間:新旧メッセージが混在!
{"message": "Hello from CDK !", "version_id": "3", ...} # 90%の確率
{"message": "Hello from Lambda !", "version_id": "4", ...} # 10%の確率
# 5分経過後:新メッセージのみ
{"message": "Hello from Lambda !", "version_id": "4", ...} # 100%
4.クリーンアップ
- ハンズオンで作成した AWS リソースを手動で削除します。
項番 | リソース | 作業手順 | 注意点 |
---|---|---|---|
1 | CloudFormation: CDKToolkit | マネジメントコンソール > CloudFormation > スタック | 依存リソースがある場合は削除失敗します |
2 | S3: cdk- |
マネジメントコンソール > S3 > バケット | バケット内のオブジェクトも全削除が必要 |
3 | ECR: cdk- |
マネジメントコンソール > ECR > リポジトリ | コンテナイメージ代は日々課金されるため重要 |
4 | IAM: GitHubAction-AssumeRoleWithAction | マネジメントコンソール > IAM > ロール | アタッチ済みポリシーも確認 |
5 | IAM: GitHubAction-AssumeCdkRoles | マネジメントコンソール > IAM > ポリシー | このポリシーを使用中のロールがないか確認 |
6 | IAM: IDプロバイダ token.actions.githubusercontent.com | マネジメントコンソール > IAM > IDプロバイダ | OIDC認証の設定 |
7 | GitHub: シークレット AWS_ACCOUNT_ID | GitHub > リポジトリ > Settings > Secrets | セキュリティ対策として削除 |
5.おわりに
今回は第3回 GitHub Actions設定とデプロイ・挙動確認編を記載しました。
今回実施したことサマリ:
- GitHub Actionsワークフロー作成:自動CI/CDパイプラインを構築
- OIDCベース認証設定:セキュアなAWS認証を実現
- コンテナイメージビルド:DockerコンテナをECRへ自動プッシュ
- CDK自動デプロイ:インフラを自動でプロビジョニング
- CodeDeployカナリアリリース設定:安全な本番更新方法を確認
- 動作確認と設定変更テスト:機能の検証
次回は実際のトラブルシューティング集
で今回発生したエラーについてまとめたいと思います。