GitHub Actionsを使ったECSへの自動デプロイ
この記事では、GitHub Actionsを利用してAmazon ECSへのデプロイを自動化する方法について解説します。
参考
- Deploying to Amazon Elastic Container Service
- Configuring OpenID Connect in Amazon Web Services
- Configuring a role for GitHub OIDC identity provider
- GitHub Actions から AWS へアクセスする
前提
- AWSアカウント
- IAM Identity Centerに登録されたユーザー
詳しくはこちらの手順を参照してください。 - GitHubリポジトリ
環境
- Ubuntu 22.04.3 LTS (WSLで起動している)
- Docker Engine 26.0.0
- Laravel 11
デプロイ手順
- プロジェクトをデプロイする
- OIDC IDプロバイダを作成する
- GitHub OIDC IDプロバイダ用のロールを作成する
- リポジトリのシークレットにロールを追加する
- リポジトリ内にタスク定義を作成する
- ワークフローを作成する
- ワークフローを確認する
1. プロジェクトをデプロイする
まず、何かプロジェクトをECSにデプロイします。
詳細はこちらのガイドを参照してください。
2. OIDC IDプロバイダを作成する
AWSの認証にはOpenID Connect(OIDC)を使用します。
このページによると、OpenID Connect (OIDC)を使用すると、GitHub ActionsのワークフローがAWSのリソースにアクセスできるようになり、長期保存のAWS認証情報をGitHubのシークレットとして保存する必要がなくなります。
OpenID Connect (OIDC) allows your GitHub Actions workflows to access resources in Amazon Web Services (AWS), without needing to store the AWS credentials as long-lived GitHub secrets.
OIDC IDプロバイダを作成するには、AWSマネジメントコンソールのIAMを開き、「Identity providers」をクリックします。
「Add provider」をクリックします。
「OpenID Connect」を選択し、以下の情報を入力します(こちらのドキュメント参照)
Provider URL | https://token.actions.githubusercontent.com |
Audience | sts.amazonaws.com |
3. GitHub OIDC IDプロバイダ用のロールを作成する
IAMの「Roles」に移動します。
「Create role」をクリックします。
「Web identity」を選択します。
以下の情報を入力して「Next」をクリックします。
項目 | 説明 |
---|---|
Identity provider | 作成したOIDC IDプロバイダ |
Audience | 設定したAudience |
GitHub organization | GitHubユーザー名 |
GitHub repository | このロールを使用するリポジトリ名。すべてのリポジトリに適用するには * を使用する。 |
GitHub branch | 対象ブランチ。すべてのブランチに適用するには * を使用する。 |
「Add permission」画面でも「Next」をクリックします。
任意のロール名と説明を入力し、「Create role」をクリックします。
次に、必要なポリシー(ECR、ECS、IAMについて)をインラインポリシーとして追加します。
AWSマネジメントコンソール上で、作成したロールをクリックして「Create inline policy」をクリックします。
JSONタブに切り替え、以下のポリシーを入力します。
ECRについて:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:UploadLayerPart",
"ecr:InitiateLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage"
],
"Resource": "arn:aws:ecr:<Your repository region>:<Your Account ID>:repository/<Your repository name>"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
]
}
「Next」をクリックし、任意のポリシー名を入力して「Create policy」をクリックします。
ECSとIAMについても同様に作成します。
ECSについて:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:RegisterTaskDefinition",
"ecs:DescribeServices"
],
"Resource": [
"arn:aws:ecs:<Your cluster region>:<Your Account ID>:service/<Your cluster name>/*",
"arn:aws:ecs:<Your cluster region>:<Your Account ID>:task-definition/<Your task definition name>:*"
]
}
]
}
IAMについて:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::<Your Account ID>:role/<Your task execution role name>"
}
]
}
4. リポジトリのシークレットにロールを追加する
GitHubリポジトリに移動し、「Settings」をクリックします
「Secrets and variables」 > 「Actions」をクリックします。
Click “Secrets and Variables” > “Actions”.
「New repository secret」をクリックします。
名前(例:ROLE_TO_ASSUME
)と、先ほど作成したロールのARNを入力して「Add secret」をクリックします。
5. リポジトリ内にタスク定義を作成する
.aws/task-definition.json
などのファイル名で、タスク定義のJSONファイルをリポジトリ内に保存します。
6. ワークフローを作成する
GitHubリポジトリの「Actions」をクリックします。
「New workflow」をクリックします。
「Deploy to Amazon ECS」の「Configure」を選択します。
このワークフローでは、DockerイメージをビルドしてECRにプッシュし、タスク定義の「image」をプッシュしたものに置き換え、ECSにデプロイします。
YAMLファイル内の環境変数を実際の値に置き換えます。
AWS_REGION: MY_AWS_REGION # 好きなAWSリージョン 例: us-west-1
ECR_REPOSITORY: MY_ECR_REPOSITORY # ECRリポジトリ名
ECS_SERVICE: MY_ECS_SERVICE # ECSサービス名
ECS_CLUSTER: MY_ECS_CLUSTER # ECSクラスター名
ECS_TASK_DEFINITION: MY_ECS_TASK_DEFINITION # GitHubリポジトリのECSタスク定義のパス
# 例: .aws/task-definition.json
CONTAINER_NAME: MY_CONTAINER_NAME # タスク定義の「containerDefinitionsset」にあるコンテナ名
OIDC用に id-token: write
を permissions
に追加します。
permissions:
id-token: write # 追加
contents: read
「Configure AWS credentials」ステップを以下のように修正します。
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ secrets.ROLE_TO_ASSUME }} # 変更
aws-region: ${{ env.AWS_REGION }}
Dockerfile
がルートディレクトリ以外にある場合は -f
オプションでパスを指定します。
例:
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f ./docker/web/Dockerfile .
ファイル名を入力し(例: aws.yml
)、「Commit changes」をクリックします。
このワークフローは main
ブランチに変更がプッシュされたときに実行されるため、上記のコミットで実行されたはずです。
on:
push:
branches: [ "main" ]
7. ワークフローを確認する
GitHubリポジトリの「Actions」をクリックします。
以下のような画面が表示されていればワークフローは正しく完了しています。