ECS on Fargateへ移したWeb環境に、GitHub Actionsによるビルド・検証・本番配信の仕組みを整えました。第2回は、ランタイムとサイトコードの更新を分け、実際の変更が公開サイトへ届くところまで確認した記録です。(2026/09/27作成)
MR-PANDA / Pixabay
AWS CLI参考コードについて:以下は記事の確認内容を再現するための汎用例で、当時の実行ログそのものではありません。AWS CLI v2とBashを想定しています。<…>は自分の環境の値へ置き換え、認証済みのプロファイルと対象APIを利用できる権限を用意してください。同じ記事のコードは、先頭の変数設定を行った同じシェルで実行する想定です。内部のサービス名・ID・認証情報は掲載していません。
参考コード:実行環境の指定
export AWS_PROFILE='<AWS_PROFILE>'
export AWS_DEFAULT_REGION='<AWS_REGION>'
export AWS_PAGER=''
CLUSTER='<ECS_CLUSTER>'
SERVICE='<ECS_SERVICE>'
# 接続先アカウントとロールを確認する
aws sts get-caller-identity
GitHub Actions内で使う場合は、OIDCによるロール引受けを完了した後にAWS CLIを実行します。ローカル用のAWS_PROFILE指定はワークフローへ持ち込まず、認証アクションが設定した一時認証情報を使います。
0.移行後に必要になった更新の仕組み
サーバーを移行できても、その後の変更方法が曖昧なままでは運用しにくくなります。NginxやPHPの設定変更、WordPressのテーマ修正、独自PHPの変更を、それぞれどこへ反映し、何をもって完了とするかを整理しました。
今回の中心はGitHub Actionsです。従来のCodeBuildを中心としたランタイム構築から移行し、コードの差分、検証結果、配信履歴をGitHub側で追えるようにしました。
1.ランタイムとサイトコードを分ける
更新経路は、次の2種類に分けています。
- ランタイム更新:Dockerfile、Nginx、PHP-FPM、起動処理などを変更し、コンテナイメージを作り直してECSへ反映します。
- サイトコード更新:テーマ、プラグイン、独自コードなどの変更を、専用の配信タスクからEFSへ反映します。
サイトのファイルはEFSにあるため、ランタイムイメージを作り直しただけではテーマの変更は反映されません。逆に、テーマを配信しただけではPHPの設定は変わりません。どちらの更新かを最初に分けることで、変更箇所と確認箇所が明確になりました。
2.ランタイムは、検証したイメージを指定して反映する
- GitHub ActionsでARM64イメージをビルドする。
- Nginx・PHP-FPMなどの検証を行う。
- Amazon ECRへイメージを登録する。
- 検証済みイメージのdigestを指定し、ECSへ反映する。
- 期待したタスク定義とイメージが稼働し、ALBと公開サイトが正常であることを確認する。
digestは、イメージを特定する識別値です。今回のランタイム更新は手動で実行するワークフローとし、Gitへpushしただけで本番イメージが切り替わる運用にはしていません。
実際に、本番への反映自体は完了しているのに、ワークフローの最終判定が失敗した場面もありました。GitHubの成功・失敗表示だけで再実行を判断せず、AWS側の状態を確認し、待機・判定処理を修正しています。
参考コード:ECRのdigestを確認する
ビルド済みのタグからdigestを確認します。検証後はrepository URIと「@sha256:…」を組み合わせた参照をタスク定義のimageに設定し、登録済みの新リビジョンを配信対象にします。
ECR_REPOSITORY='<ECR_REPOSITORY>'
IMAGE_TAG='<VERIFIED_IMAGE_TAG>'
aws ecr describe-images \
--repository-name "$ECR_REPOSITORY" \
--image-ids "imageTag=$IMAGE_TAG" \
--query 'imageDetails[].{digest:imageDigest,tags:imageTags,pushedAt:imagePushedAt}'
公式リファレンス:aws ecr describe-images
参考コード:検証済みタスク定義を反映する(変更操作)
以下のupdate-serviceは稼働中のサービスを更新する例です。検証済みimageを指定したタスク定義を事前登録し、対象・影響・直前のリビジョンを確認してから実行します。待機が成功しても、意図したリビジョンへの更新や公開サイトの正常性は別途確認します。
NEW_TASK_DEF='<VERIFIED_TASK_DEFINITION_ARN>'
# 変更前の参照先を記録する
aws ecs describe-services \
--cluster "$CLUSTER" --services "$SERVICE" \
--query 'services[0].taskDefinition' --output text
# ここから変更操作:新しいタスク定義を配信する
aws ecs update-service \
--cluster "$CLUSTER" --service "$SERVICE" \
--task-definition "$NEW_TASK_DEF" \
--query 'service.{taskDefinition:taskDefinition,deployments:deployments}'
# 待機失敗時は自動で再配信せず、イベントや停止理由を調べる
aws ecs wait services-stable \
--cluster "$CLUSTER" --services "$SERVICE"
公式リファレンス:aws ecs update-service
3.サイトコードをGitで管理し、EFSへ差分配信する
まず3つのWordPressサイトからコードを取得し、約6万5千ファイルを非公開リポジトリへ収録しました。投稿画像、ログ、実行時キャッシュ、認証情報を含む設定ファイルなどは、コードとは別に扱っています。投稿やユーザー情報などのデータベースも、今回のGit管理には含めていません。
サイトコードはブランチで変更し、Pull Requestで差分とチェックを確認して、mainへ反映すると配信が始まる構成です。
コード変更 → 差分検査 → 成果物保存 → 専用Fargateタスク → EFSの照合・バックアップ・更新 → 公開確認
AWSへの認証にはOIDCを使い、長期アクセスキーをGitHubへ保存しない構成にしました。ビルド、ランタイム反映、サイトコード配信で権限も分けています。
4.自動配信に入れた確認と保護
自動化で重視したのは、同じ手順で検証し、条件が合わなければ停止できることです。
- 本番の変更前ファイルとGit側の想定が一致するか、ハッシュで照合する。
- 更新前の対象ファイルをバックアップし、保存に失敗したら書き換えない。
- 配信対象のパスを限定し、想定外のファイルを操作しない。
- 複数の配信が同時に走らないようにする。
- 変更後のハッシュ、HTTP応答、HTML本文を確認する。
管理画面などから先に変更されたファイルを、Git側の古い内容で無条件に上書きしないための確認でもあります。WordPress管理画面からの更新とGit経由の更新をどう使い分けるかは、継続して整える必要があります。
参考コード:配信タスクの終了コードを確認する
EFS更新は専用タスク内の照合・バックアップ・配信処理が行います。これは既に起動した配信タスクの確認例であり、AWS CLIだけでEFSのファイル差分を判定するものではありません。STOPPEDは終了状態を表すだけなので、各コンテナのexitCodeと完了ログも確認します。
DEPLOY_TASK_ARN='<DEPLOY_TASK_ARN>'
aws ecs describe-tasks \
--cluster "$CLUSTER" --tasks "$DEPLOY_TASK_ARN" \
--query '{tasks:tasks[].{status:lastStatus,stopCode:stopCode,reason:stoppedReason,containers:containers[].{name:name,exitCode:exitCode,reason:reason}},failures:failures}'
公式リファレンス:aws ecs describe-tasks
5.キャッシュ更新と通知まで含めて実証する
9月16日の初回確認は、全件照合と差分ゼロの配信でした。9月19日には実際にコードを変更し、複数サイトへ反映した内容が通常URLで見えることまで確認しています。
配信後は、WordPress側のローカルキャッシュを更新し、その後にCloudflareの対象ホストまたはURLのキャッシュを削除します。最後に公開URLを確認し、Slackへ結果を通知する順序です。通知が届くことと、配信が成功したことも分けて確認しました。
また、正常な同一ホストへの転送を検証処理がエラーと扱う問題がありました。既知の転送だけを許可するよう修正し、すべての転送を無条件に通す対応は避けています。
参考コード:配信ログを時間・ストリームで絞る
配信タスクに対応するログストリームを指定し、差分照合・バックアップ・キャッシュ更新・公開確認の結果を追います。ログ出力の内容は配信処理の実装によって異なります。
LOG_GROUP='<DEPLOY_LOG_GROUP>'
LOG_STREAM='<DEPLOY_LOG_STREAM>'
aws logs tail "$LOG_GROUP" \
--log-stream-names "$LOG_STREAM" \
--since 1h --format short
公式リファレンス:aws logs tail
6.戻し方と、まだ残っていること
成功したコード変更を戻す場合は、対象コミットをrevertし、同じ検査とバックアップを経て逆差分を配信する方針です。ただし、コードを戻してもデータベースの変更やプラグインの副作用まで元に戻るわけではありません。本番でのロールバック演習は、記録時点では未実施です。
ChatGPT Proとの伴走では、配信処理の実装に加え、失敗時に何を調べるか、何を再実行してよいかを整理しました。9月19日には依存関係を確認したうえで旧CodeBuildと専用権限を整理し、現在の配信に必要なストレージやイメージは残しています。
これで、変更をGitに残し、検証して本番へ届け、公開状態を確認する流れができました。次回は、運用を始めてから見えてきた費用と負荷、そして障害対応についてまとめます。
以上
よしまさのブログをもっと見る
購読すると最新の投稿がメールで送信されます。
