GitHub ActionsとAWS ECSを組み合わせれば、コードのpushから本番デプロイまで全自動化できます。認証は長期アクセスキーよりOIDC(一時認証)が断然安全。あとはAWS公式アクション4つ(認証→ECRログイン→タスク定義更新→デプロイ)を組むだけで、ヒューマンエラーのない本番運用が実現します。
「毎回手作業でECSにデプロイしていて事故が怖い」——CI/CDを組めばその不安は消えます。本記事ではインフラエンジニアの視点で、OIDCによる安全な認証から、コピペで使えるワークフローの全体像までを解説します。
GitHub Actions×ECSでCI/CDを組むメリット
最大のメリットは「pushするだけで本番に反映される」自動化です。手動のイメージビルドやタスク定義更新がなくなり、デプロイのヒューマンエラーをゼロにできます。
コードが唯一の真実になるGitOps的な運用に近づき、誰がいつ何をデプロイしたかも履歴に残ります。ロールバックもワークフローの再実行で済むため、運用の安心感が段違いです。
認証はアクセスキーよりOIDCが安全
結論から言うと、認証は必ずOIDCを選びましょう。長期有効なアクセスキーをGitHub Secretsに置く方式は、漏洩時のリスクが大きいためです。OIDCならワークフローのたびに一時認証情報を発行し、終了時に自動失効します。
| 方式 | セキュリティ | キーの管理 |
|---|---|---|
| アクセスキー | 中(長期キーを保存) | 手動ローテーションが必要 |
| OIDC(推奨) | 高(一時認証情報) | 自動失効・保存不要 |
AWS側ではGitHubをOIDCプロバイダーとして登録し、信頼ポリシーで「どのリポジトリ・どのブランチからの実行を許可するか」を絞ります。これで万一トークンが漏れても、想定外のリポジトリからは引き受けできません。
ワークフローの作り方(deploy.yml)
ワークフローはAWS公式アクション4つで構成します。configure-aws-credentials(OIDC認証)→amazon-ecr-login→amazon-ecs-render-task-definition(イメージ差し替え)→amazon-ecs-deploy-task-definition(デプロイ)の流れです。
name: Deploy to ECS
on:
push:
branches: [ main ]
permissions:
id-token: write # OIDCに必須
contents: read
env:
AWS_REGION: ap-northeast-1
ECR_REPOSITORY: my-app-repo
ECS_SERVICE: my-app-service
ECS_CLUSTER: my-app-cluster
ECS_TASK_DEFINITION: task-definition.json
CONTAINER_NAME: my-app-container
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# OIDCでIAMロールを引き受け(アクセスキー不要)
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-ecs
aws-region: ${{ env.AWS_REGION }}
- id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
# ビルドしてgit SHAタグでECRへpush
- id: build
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
IMAGE=$REGISTRY/$ECR_REPOSITORY:${{ github.sha }}
docker build -t $IMAGE .
docker push $IMAGE
echo "image=$IMAGE" >> $GITHUB_OUTPUT
# タスク定義のイメージを差し替え
- id: render
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ env.ECS_TASK_DEFINITION }}
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.build.outputs.image }}
# ECSへデプロイ(安定するまで待機)
- uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.render.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true
アクションのバージョンに注意
公式アクションは更新されます。本記事執筆時点では configure-aws-credentials が v6、ecs-deploy-task-definition が v2 が最新です。導入時は各リポジトリで最新版を確認してください。
よくあるエラーとロールバック
最頻出は権限不足とタスク定義の不一致です。デプロイが失敗してもサービスは旧バージョンで動き続けるので、まずは落ち着いて原因を切り分けましょう。
| 症状 | 主な原因と対処 |
|---|---|
| AssumeRoleで失敗 | 信頼ポリシーのリポジトリ/ブランチ条件ミス。permissions: id-token: write の付け忘れも確認 |
| ECR pushで権限エラー | IAMロールにECR Push権限(ECRへのPutImage等)が不足 |
| デプロイが安定しない | ヘルスチェック失敗。コンテナのポート/起動コマンドを確認 |
ロールバックは簡単で、直前まで動いていたコミットでワークフローを再実行すれば、そのイメージのタスク定義で再デプロイされます。wait-for-service-stability: trueを入れておけば、安定しないデプロイは自動で失敗扱いになり被害を最小化できます。こうしたCI/CDやAWSの設計を体系的に身につけたいなら、ハンズオン型の講座が効率的です。
マルチ環境とコスト最適化のコツ
本番運用では、環境ごとのデプロイとコスト削減も意識しましょう。ブランチ戦略と組み合わせれば、dev/staging/prodを安全に運用できます。
すぐ効く3つの最適化
- ブランチ別ワークフロー(develop→staging、main→prod)で誤デプロイを防ぐ
- Fargate Spotを非本番環境に使ってコスト削減
- Docker layer cacheでビルド時間を短縮
まとめ:本番運用できるCI/CDの全体像
GitHub Actions×ECSのCI/CDは、OIDC認証+公式アクション4つで安全に組めます。pushから本番までを自動化すれば、デプロイ事故が激減し、開発のスピードと安心感が両立します。ECSのインフラ自体をコードで管理するならTerraform State Lockの安全な解除手順も押さえておくと安心です。コンテナの実行基盤をどう選ぶか迷うならCloud Run vs Lambdaのコスト比較も参考になります。

コメント