6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ECSの自動デプロイをGitHubActionsで実装してみた

Last updated at Posted at 2023-09-11

今回は、GitHub ActionsでECSに自動デプロイする方法を紹介します。

ECSにデプロイするまでの話も記事にしています。

今回は、GitHubActionsの細かい話しません。ECRとECSにデプロイする流れを説明して、コードを紹介します。

GitHubActionsとは?

GitHub Actionsは、GitHub上でCI/CDを簡単に実行できるサービスです。この機能を使うことで、コードをプッシュしたり、プルリクエストをマージした際に、テストやビルド、デプロイなどの一連のタスクを自動で行えます。

Circle CIやAWSのcodeシリーズなど、同じようなサービスは複数ありますが、GitHubActionsがコスト(工数、費用)が少いのでおすすめです。
privateレポジトリでもある程度は無料で使えます。

【参照】

実装について

今回は、ECSに対してローリングアップデートで実装します。
ローリングアップデートかBlue/Greenデプロイのいずれかを採用することが多いと思います。
一長一短ですが、シンプルで安価に実装できるローリングデプロイとしています。

【参照】

全体の流れ

下記のような感じです。非常にシンプルですね。
ECRにDocker imageをpushして、ECS Serviceを更新するような流れです。

image.png

ECSのサービス定義で、必要なタスク2、最小実行タスク100%、最大実行タスク200%の設定を前提としています。
image.png

ポイント

ECRにimageをpushする際に、タグ付けができます。
基本的には、LATESTタグを付与して、ECSでLATESTタグのイメージを使えば、常に最新版で運用できるのでいいかと思います。
ただ、問題発生時にどのイメージで問題が起こっているのか追跡できるようにするために、今回はLATESTタグに加えて、gitコミットハッシュ値を持たせておきます。

ECRのイメージにコミットハッシュをタグとしてつけることで、追跡性、一意性、ロールバックの容易さなど、多くの利点を享受できます。

そもそもLATEST運用がアンチパターンという意見もあるみたいなので、
プロダクトによってご検討ください。

では、実装を見ていきます。
「# 変更してください」という記述の部分は、環境変数的なところなので、
ご自身で設定してください。

ディレクトリ構成

cd-workflow.ymlで実装していきます。

── .github
│   ├── pull_request_template.md
│   └── workflows
│       ├── cd-workflow.yml

### 流れ

  1. マシーンを起動、ソースコードを取得
  2. OIDCでAWS認証をする
  3. docker build, tagを付与し、ECRにプッシュする
  4. ECSを更新する
  5. おしまい

実際のコード

下記ですね。細かい説明は後述します。

cd-workflow.yml
name: push image to ECR and deploy to ECS
on:
  pull_request:
    branches:
      - main
    types: [closed]

jobs:
  push:
    name: push image to ECR and deploy to ECS
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v3

      # - name: Set AWS CLI Debug Output (if needed for debugging)
      #   run: |
      #     echo "AWS_DEFAULT_OUTPUT=text" >> $GITHUB_ENV
      #     echo "AWS_PAGER=" >> $GITHUB_ENV
      #     # echo "AWS_DEBUG=true" >> $GITHUB_ENV

      - uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-region: 'ap-northeast-1' #変更してください リージョン名
          role-to-assume: 'arn:aws:iam::hogehogehoge:role/oidc-role' #変更してください ロール名

      - uses: aws-actions/amazon-ecr-login@v1
        id: login-ecr

      - name: Build, tag, and push docker image to ECR
        env:
          REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          REPOSITORY: "twitter-clone" #変更してください ECRのリポジトリ名
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build . --tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
          docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
          docker tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest
          docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest

      - name: Force new deployment and wait for services stability in ECS
        env:
          CLUSTER_NAME: "ProjectA-ecs-cluster" #変更してください クラスター名
          SERVICE_NAME: "ProjectA-esc-service4" #変更してください サービス名
        run: |
          aws ecs update-service --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }} --force-new-deployment
          aws ecs wait services-stable --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}
          aws ecs describe-services --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}

1.マシーンを起動、ソースコードを取得

この辺りは、GithubActionsを触ったことがある人ならすぐにわかると思いますが、GitHubActionsでgithub上のソースコードを使うためのお約束的なのです。

  • mainブランチへのマージをトリガーにしています。
  • マシーンは、ubuntu-latest
  • timeout-minutesは、バグった時に、GithubActionsの無駄使いしないように設定しています。
  • permissionsは、後述のOIDC認証した時に、AWSリソースを扱うために必要な記述です。
  • uses: actions/checkout@v3で、ソースコードを取得できます。
cd-workflow.yml
name: push image to ECR and deploy to ECS
on:
  pull_request:
    branches:
      - main
    types: [closed]

jobs:
  push:
    name: push image to ECR and deploy to ECS
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v3

2.OIDCでAWS認証をする

AWSの認証**: AWSのリソースにアクセスするためには、適切な権限を持ったIAMロールをGitHub Actionsに付与する必要があります。これを簡単に行うためのアクションがaws-actions/configure-aws-credentials@v1です。

設定方法など、下記の記事がめっちゃわかりやすいので、見てください。

【参照】

cd-workflow.yml
- uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-region: 'ap-northeast-1'
    role-to-assume: 'arn:aws:iam::925173743335:role/oidc-role'

3.docker build, tagを付与し、ECRにプッシュする

まず、ECRへのログインが必要です。これはaws-actions/amazon-ecr-login@v1を使用して簡単に行えます。
ockerイメージのビルド、タグ付け、プッシュ: リポジトリに変更があった場合、Dockerイメージをビルドし、それをECRにプッシュします。
タグには、gitコミットのハッシュ値と、最新のイメージとしてlatestタグを追加します。

cd-workflow.yml
      - uses: aws-actions/amazon-ecr-login@v1
        id: login-ecr

      - name: Build, tag, and push docker image to ECR
        env:
          REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          REPOSITORY: "twitter-clone"
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build . --tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
          docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
          docker tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest
          docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest

4.ECSを更新する

  1. ECSのサービスを更新して新しいタスクを起動します。
  2. ECSのサービスが安定するまで待機します。
  3. そして、最後にログを出力してくれます。

2,3はおまけみたいなもので処理に結構時間がかかるので、1だけでもOKです。

cd-workflow.yml
      - name: Force new deployment and wait for services stability in ECS
        env:
          CLUSTER_NAME: "ProjectA-ecs-cluster"
          SERVICE_NAME: "ProjectA-esc-service4"
        run: |
          aws ecs update-service --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }} --force-new-deployment
          aws ecs wait services-stable --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}
          aws ecs describe-services --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}

まとめ

GitHub Actionsを使用することで、ソースコードの変更を簡単にAWSのECSサービスにデプロイすることができました。これにより、開発のサイクルが速くなり、リリースの頻度を上げることが可能となります。

お楽しみに!

下記、関連記事も書いているので、よかったら見てください。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?