GO言語アプリケーションのCI/CD環境構築
初めに
エンジニアとして働き始めて2年目であり、極力気をつけましたが誤った情報を発信しているかもしれません。
その際はぜひコメントにてご指摘いただければ幸いです。
CI/CDとは
CI/CDとは「Continuos Integration(CI)」と「Continuous Delivery/Deployment(CD)」の略称となります。
CIについて
複数の開発者がコード変更を頻繁にリポジトリに統合(インテグレーション)し、各統合で自動化されたビルドやテストで検証します。
- エラーの早期発見
- 新しいコードが既存のコードと統合される度に、自動的にビルドとテストが実行されるため、失敗した場合バグやエラーの早期発見につながる
- 共同開発の促進
- 様々な開発者が各々ローカルでIDEを使用し、コードを変更を加えるとマージした際、多くの競合(コンフリクト)が発生し得る。コード変更がリポジトリに頻繁にプッシュされることにより、コードの競合を減らす事ができます。
- 自動化されたテストとビルドによるフィードバック
- 自動化されたテストやビルドにより、開発者自身が変更の影響をすぐに知る事ができます。また必要な対応も迅速に行う事ができます。
CDについて
CDは「継続的デリバリー」又は「継続的デプロイメント」を指します。
CIで自動化されたテスト、及びビルドされた検証済みコードを自動的にリリースする事です。
-
継続的デリバリー
- 新しい機能や修正を開発、検証、本番などの環境にデプロイする準備を整える役割を持ちます。
- 開発者によるアプリケーションへの変更に対して、バグがないかを自動的にテストし、リポジトリにアップデートします。
-
継続的デプロイメント
- リポジトリから開発、検証、本番などの環境への開発者による変更のリリースを自動化し、クライアントが利用できるようするというものです。
CI/CDに利用できるツール一覧
1. Jenkins
- 概要: オープンソースの自動化サーバーで、多くのプラグインを利用して自分のニーズに合わせてカスタマイズ可能です。
- 公式サイト: https://www.jenkins.io
2. GitLab CI/CD
- 概要: GitLabリポジトリにネイティブに組み込まれたCI/CDツールで、シンプルな統合と強力な機能を提供します。
- 公式サイト: https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/
3. CircleCI
- 概要: 高性能かつスケーラブルなCI/CDツールで、Dockerサポートや多様な環境へのデプロイが可能です。
- 公式サイト: https://circleci.com
4. GitHub Actions
- 概要: GitHubリポジトリと直接統合可能なCI/CDツールで、コードのすべての段階を自動化するためのワークフローを作成できます。
- 公式サイト: https://github.com/features/actions
5. Travis CI
- 概要: GitHubリポジトリと連携して自動ビルドとテストを行うクラウドベースのCIツールです。オープンソースプロジェクトに特に人気があります。
- 公式サイト: https://travis-ci.org
今回はネットや弊社のナレッジが多く、ランキングサイトにも上位にランク付けされていたGithub Actionsを使用して、CI/CD環境構築していきます。
GitHub Actionsの流れ
1.開発者が VSCode でコードを変更し、GitHub に push する。
2.GitHub Actions が push をトリガーにビルド・テストを実行し、Docker を使ってコンテナイメージを作成する。
3.GitHub Actions が作成したイメージを AWS ECR にプッシュ(アップロード)する。
4.AWS ECS が ECR に保存されたイメージをプル(取得)してコンテナを起動しデプロイが完了する。
CI/CDの必要性
こちら自分なりに書いてたら長くなったので別記事にまとめてみました。
実装コード
CI/CDファイル
name: ci-cd
on:
push:
branches:
- '**'
# 現在は全てのブランチのpushで作動。buildステップはdevelopのみ作動
jobs:
########## CI ##########
######### Lint #########
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
- name: Install golang ci-lint
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5
- name: Run golang ci-lint
run: golangci-lint run --timeout=10m
######### Test #########
test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set environment variables from secrets
run: |
echo "APP_TIMEZONE=${{ secrets.APP_TIMEZONE }}" >> $GITHUB_ENV
echo "DB_HOST=${{ secrets.DB_HOST }}" >> $GITHUB_ENV
echo "DB_PORT=${{ secrets.DB_PORT }}" >> $GITHUB_ENV
echo "DB_USER=${{ secrets.DB_USER }}" >> $GITHUB_ENV
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV
echo "DB_NAME=${{ secrets.DB_NAME }}" >> $GITHUB_ENV
echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
echo "REDMINE_APP_ACCESS_KEY=${{ secrets.REDMINE_APP_ACCESS_KEY }}" >> $GITHUB_ENV
# etc...
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
- name: Cache Go modules
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: Install dependencies
run: go mod tidy
- name: Run unit tests
run: go test -v ./...
########## Build ##########
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test] # lint, testジョブが成功した場合のみ作動
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' # developとmainブランチのみ作動
permissions:
id-token: write
contents: read
outputs:
image-app: ${{ steps.build-app-image.outputs.image }}
image-app2: ${{ steps.build-app2-image.outputs.image }}
steps:
- name: Checkout code
uses: actions/checkout@v4
# github.event.before(前のコミット)とgithub.sha(現在のコミット)の間で変更されたファイルのリストを取得し変更の有無を変数に格納
- name: Detect changes in codebase
id: detect-changes
run: |
app2_changed="false"
app_changed="false"
if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^app2/'; then
app2_changed="true"
else if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^/'; then
app_changed="true"
fi
echo "app2_changed=$app2_changed" >> $GITHUB_ENV
echo "app_changed=$app_changed" >> $GITHUB_ENV
# マルチプラットフォームのビルドを可能にするための設定
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# マルチプラットフォームのDockerイメージビルドをサポート、及びビルドプロセスの最適化
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# AWS credentialsの設定
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
# AWS CLIを使用してECRに対して認証トークンを取得
# 認証トークンを使用してDockerクライアントがECRにログイン
- name: Login to Amazon ECR for app2
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
registry: "123456789011,123456789012" # ECRのレジストリを指定
# Dockerイメージをビルド
- name: Build, tag, and push docker image to Amazon ECR for app
if: env.app_changed == true
id: build-app-image
env:
ECR_REGISTRY: 123456789011.dkr.ecr.ap-northeast-1.amazonaws.com
REPOSITORY: exapmle_repository
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG -f ./docker/app/Dockerfile .
docker push $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG
echo "image-app=$ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG" >> "$GITHUB_OUTPUT"
- name: Build, tag, and push docker image to Amazon ECR for app2
if: env.app2_changed == true
id: build-app2-image
env:
ECR_REGISTRY: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
REPOSITORY: exapmle_repository2
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG -f ./docker/app2/Dockerfile .
docker push $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG
echo "image-app2=$ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG" >> "$GITHUB_OUTPUT"
########## CD ##########
##### Deploy for staging environment #####
deploy-staging:
name: Deploy to Amazon ECS for staging environment
runs-on: ubuntu-latest
environment:
name: STG
needs: [build] # buildジョブが成功した場合のみ作動
if: github.ref == 'refs/heads/develop' # developブランチのみ作動
permissions:
id-token: write
contents: read
steps:
- name: Debug environment variables
run: |
echo "image-app: ${{ needs.build.outputs.image-app }}"
echo "image-app2: ${{ needs.build.outputs.image-app2 }}"
- name: Checkout code
uses: actions/checkout@v4
# AWS credentialsの設定
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
# Amazon ECSタスク定義の新しいイメージIDを埋め込む
- name: Fill in the new image ID in the Amazon ECS task definition for app
id: task-def-app
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ secrets.TASK_DEFINITION_ARN }}
container-name: app
image: ${{ env.image-app}}
- name: Fill in the new image ID in the Amazon ECS task definition for app2
id: task-def-app2
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ steps.task-def-api.outputs.task-definition }}
container-name: app2
image: ${{ env.image-app2 }}
# Amazon ECSタスク定義をデプロイ
- name: Deploy Amazon ECS task definition for app
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def-app.outputs.task-definition }}
service: ${{ secrets.CLUSTER_SERVICE_NAME }}
cluster: ${{ secrets.CLUSTER_NAME }}
wait-for-service-stability: true
- name: Deploy Amazon ECS task definition for app2
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def-app2.outputs.task-definition }}
service: ${{ secrets.CLUSTER_SERVICE_NAME }}
cluster: ${{ secrets.CLUSTER_NAME }}
wait-for-service-stability: true
##### Deploy for production environment #####
deploy-production:
name: Deploy to Amazon ECS for production environment
runs-on: ubuntu-latest
environment:
name: PRD
needs: [ build ] # buildジョブが成功した場合のみ作動
if: github.ref == 'refs/heads/main' # mainブランチのみ作動
permissions:
id-token: write
contents: read
steps:
- name: Debug environment variables
run: |
echo "image-app: ${{ needs.build.outputs.image-app }}"
echo "image-app2: ${{ needs.build.outputs.image-app2 }}"
- name: Checkout code
uses: actions/checkout@v4
# AWS credentialsの設定
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
# Amazon ECSタスク定義の新しいイメージIDを埋め込む
- name: Fill in the new image ID in the Amazon ECS task definition for app
id: task-def-app
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ secrets.TASK_DEFINITION_ARN }}
container-name: app
image: ${{ env.image-app}}
- name: Fill in the new image ID in the Amazon ECS task definition for app2
id: task-def-app2
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ steps.task-def-api.outputs.task-definition }}
container-name: app2
image: ${{ env.image-app2 }}
# Amazon ECSタスク定義をデプロイ
- name: Deploy Amazon ECS task definition for app
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def-app.outputs.task-definition }}
service: ${{ secrets.CLUSTER_SERVICE_NAME }}
cluster: ${{ secrets.CLUSTER_NAME }}
wait-for-service-stability: true
- name: Deploy Amazon ECS task definition for app2
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def-app2.outputs.task-definition }}
service: ${{ secrets.CLUSTER_SERVICE_NAME }}
cluster: ${{ secrets.CLUSTER_NAME }}
wait-for-service-stability: true
CI/CDワークフローの可視化
順を追って解説できればと思います。
CI/CD トリガー
on:
push:
branches:
- '**'
現在は全てのブランチのpushで作動。buildステップはdevelopまたはmainブランチへのpushで作動するようにしています
job1 ~ lint ~
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
- name: Install golang ci-lint
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5
- name: Run golang ci-lint
run: golangci-lint run --timeout=10m
ここはGo言語の代表的なlinterである、golangci-lintを使用しています
Go言語のソースコードを解析して、コーディングスタイルや潜在的なエラーを検出してくれます
job2 ~ test ~
test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set environment variables from secrets
run: |
echo "APP_TIMEZONE=${{ secrets.APP_TIMEZONE }}" >> $GITHUB_ENV
echo "DB_HOST=${{ secrets.DB_HOST }}" >> $GITHUB_ENV
echo "DB_PORT=${{ secrets.DB_PORT }}" >> $GITHUB_ENV
echo "DB_USER=${{ secrets.DB_USER }}" >> $GITHUB_ENV
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV
echo "DB_NAME=${{ secrets.DB_NAME }}" >> $GITHUB_ENV
echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
echo "REDMINE_APP_ACCESS_KEY=${{ secrets.REDMINE_APP_ACCESS_KEY }}" >> $GITHUB_ENV
echo "COGNITO_USER_POOL_ID=${{ secrets.COGNITO_USER_POOL_ID }}" >> $GITHUB_ENV
echo "AWS_S3_REGION=${{ secrets.AWS_S3_REGION }}" >> $GITHUB_ENV
echo "AWS_S3_ENDPOINT=${{ secrets.AWS_S3_ENDPOINT }}" >> $GITHUB_ENV
echo "AWS_S3_ACCESS_KEY_ID=${{ secrets.AWS_S3_ACCESS_KEY_ID }}" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
- name: Cache Go modules
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: Install dependencies
run: go mod tidy
- name: Run unit tests
run: go test -v ./...
ここではソースコードに対して単体テストを行なっています
.env
に記述してある情報はリポジトリー上では参照できないため、単体テストで使用する環境変数はGithub Secrets
から参照しています
Github Secretsについて
様々なymlファイルから参照できるだけでなくセキュリティー的にも良さそうです
job3 ~ build ~
~ build section part1 ~
########## Build ##########
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test] # lint, testジョブが成功した場合のみ作動
if: github.ref == 'refs/heads/develop' # developブランチのみ作動
permissions:
id-token: write
contents: read
outputs:
image-app: ${{ steps.build-app-image.outputs.image }}
image-app2: ${{ steps.build-app2-image.outputs.image }}
steps:
- name: Checkout code
uses: actions/checkout@v4
# github.event.before(前のコミット)とgithub.sha(現在のコミット)の間で変更されたファイルのリストを取得し変更の有無を変数に格納
- name: Detect changes in codebase
id: detect-changes
run: |
app_changed="false"
app2_changed="false"
if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^app2/'; then
app2_changed="true"
else if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^/'; then
app_changed="true"
fi
echo "app2_changed=$app2_changed" >> $GITHUB_ENV
echo "app_changed=$app_changed" >> $GITHUB_ENV
こちらはneeds
にlint
, test
のジョブを設定し、この二つが成功した場合のみbuild
ジョブが動くように設定しています
今回ECRにあるリポジトリーはapp
とapp2
とします。
前のコミットと現在のコミットの差分を比較し、ECRのリポジトリのどちらかまたは両方のビルドを行います
~ build section part2 ~
# マルチプラットフォームのビルドを可能にするための設定
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# マルチプラットフォームのDockerイメージビルドをサポート、及びビルドプロセスの最適化
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# AWS credentialsの設定
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
# AWS CLIを使用してECRに対して認証トークンを取得
# 認証トークンを使用してDockerクライアントがECRにログイン
- name: Login to Amazon ECR for app2
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
registry: "123456789011,123456789012" # ECRのレジストリを指定
Docker Buildsについて
Marketplaceに良さげなコードがあったので今回はDocker buildx
を使用してイメージをビルドしていきたいと思います
AIに聞いたらdocker との主な違いは下記のようです
特長:
- マルチプラットフォームビルド: docker buildx buildコマンドを使用すると、複数のプラットフォーム(例: linux/amd64, linux/arm64)のためのイメージを同時にビルドできます
- 効率的なビルドキャッシュ: BuildKitエンジンを使用することで、効率的なキャッシュの利用とビルドスピードの向上が可能です
- 複数のビルドノード: 分散ビルドがサポートされており、クラスタリングや複数のビルドノードでビルドを行うことができます
- 高度な機能: Buildxは、カスタムコンテントトラスト、ビルドの依存関係管理など、より高度なビルド機能を提供します
利点:
- マルチプラットフォーム: 複数のプラットフォーム向けにコンテナを同時にビルドでき、マルチアーキテクチャのサポートが容易です
- パフォーマンス: BuildKitの効率的なキャッシュ管理と並列ビルドにより、ビルドパフォーマンスが向上します
- 柔軟性: 複雑なビルド要求に対応でき、多くのカスタマイゼーションが可能です
IAM Roleについて
初めはAWSから張り出されたcredentialを参照していたのですが、ベテランエンジニアによるとAWSでIAMロールを作成し使用するのが一般的だそうです
- ID プロパイダを作成
- IAM ロールを作成
- GitHubActionsでOIDCを使用しAWS認証を行う
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
- aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
- aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
IAMロール自体は下記のような構成で作成しております。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS account ID>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:<GitHubユーザー名>/<GitHubリポジトリ名>:*"
}
}
}
]
}
こちらの記事を参考にしました
~ build section part3 ~
# Dockerイメージをビルド
- name: Build, tag, and push docker image to Amazon ECR for app
if: env.app_changed == true
id: build-app-image
env:
ECR_REGISTRY: 123456789011.dkr.ecr.ap-northeast-1.amazonaws.com
REPOSITORY: exapmle_repository
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG -f ./docker/app/Dockerfile .
docker push $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG
echo "image-app=$ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG" >> "$GITHUB_OUTPUT"
- name: Build, tag, and push docker image to Amazon ECR for app2
if: env.app2_changed == true
id: build-app2-image
env:
ECR_REGISTRY: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
REPOSITORY: exapmle_repository2
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG -f ./docker/app2/Dockerfile .
docker push $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG
echo "image-app2=$ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG" >> "$GITHUB_OUTPUT"
build section part1にてapp_changed
とapp2_changed
に対し値を入れていると思います
こちらの変数を利用して差分があるファイルのみイメージをビルドしています
echo "image-app=$ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG" >> "$GITHUB_OUTPUT"
このコマンドはdeployジョブで各ビルド結果のイメージIDをを使用する為変数に格納しています
それぞれappのデプロイにはimage-app
を、app2のデプロイにはimage-app2
を使用します
このように変数に格納することでそれぞれのジョブごとに値の受け渡しをすることが可能です
job4 ~ deploy ~
~ deploy section part1 ~
##### Deploy for staging environment #####
deploy-staging:
name: Deploy to Amazon ECS for staging environment
runs-on: ubuntu-latest
environment:
name: STG
needs: [build] # buildジョブが成功した場合のみ作動
if: github.ref == 'refs/heads/develop' # developブランチのみ作動
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
# AWS credentialsの設定
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
name: STG
これはGithubのSettingsにおいてEnvironmentsという項目があり、そこにステージング環境と本番環境用でそれぞれの変数を定義しています。
ECRのリポジトリはそれぞれ異なるクラスター名やサービス名を持っているためGithubのEnvironmentsを使用して管理しています。
~ deploy section part2 ~
# Amazon ECSタスク定義の新しいイメージIDを埋め込む
- name: Fill in the new image ID in the Amazon ECS task definition for app
id: task-def-app
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ secrets.TASK_DEFINITION_ARN }}
container-name: app
image: ${{ env.image-app}}
- name: Fill in the new image ID in the Amazon ECS task definition for app2
id: task-def-app2
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ steps.task-def-api.outputs.task-definition }}
container-name: app2
image: ${{ env.image-app2 }}
ここでbuild
セクションで定義されたそれぞれのイメージIDが格納してある変数を参照しています
このような手法を取ることでジョブ間の値を受け渡すことができるだけでなく、ビルドとデプロイのステップをまとめなくてもいいので読みやすいコードになったかなと思います
~ deploy section part3 ~
# Amazon ECSタスク定義をデプロイ
- name: Deploy Amazon ECS task definition for app
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def-app.outputs.task-definition }}
service: ${{ secrets.CLUSTER_SERVICE_NAME }}
cluster: ${{ secrets.CLUSTER_NAME }}
wait-for-service-stability: true
- name: Deploy Amazon ECS task definition for app2
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def-app2.outputs.task-definition }}
service: ${{ secrets.CLUSTER_SERVICE_NAME }}
cluster: ${{ secrets.CLUSTER_NAME }}
wait-for-service-stability: true
最後はEnvironmentsに定義してあるクラスターとサービス名を参照し、デプロイ完了です
[引用]
CI/CDについて
- https://www.redhat.com/ja/topics/devops/what-is-ci-cd
- https://about.gitlab.com/ja-jp/topics/ci-cd/
- https://blog.jetbrains.com/teamcity/2023/07/best-ci-tools/
- https://www.qodo.ai/blog/best-ci-cd-tools-for-devops/
GitHub Actionsについて
-
https://docs.github.com/ja/actions (オススメ)
マーケットプレイス - https://github.com/marketplace
- https://docs.github.com/ja/actions/use-cases-and-examples/building-and-testing/building-and-testing-go
- https://github.com/actions/starter-workflows/blob/main/ci/go.yml
- https://zenn.dev/farstep/books/learn-github-actions/viewer/intro (オススメ)
- https://dev.classmethod.jp/articles/github-wf-docer-ecr/
環境変数とシークレット
IAM ロール
GitHub Actionsのセキュリティについて
- https://engineering.mercari.com/blog/entry/20230609-github-actions-guideline/
- https://docs.github.com/ja/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions
CI
-
Build and push Docker image
-
Configure AWS Credentials
-
Amazon ECR "Login" Action for GitHub Actions
CD
- Amazon ECS "Deploy Task Definition" Action for Github Actions
Discussion