Git タグを活用した AWS CodePipeline の統合環境パイプラインの構築

AWS

2025.3.31

Topics

概要

CodePipeline を運用する中で発生した課題を解決するために、Git タグ機能を使ってパイプラインの改修を行いました。

課題

テスト・ステージング・本番の各環境ごとにそれぞれ CodePipeline が存在し、リリースの際には環境ごとにパイプラインを実行します。
そのため、同じ作業が重複して行われているため非効率的であり、各環境間のモジュールのバージョン管理も煩雑となっています。

統合前の構成図

テスト環境、ステージング環境、本番環境の3つの環境に対するCI/CDパイプラインのアーキテクチャ図

統合前構成のポイント

  • 複数のアカウントでテスト環境や本番環境が分かれたパイプライン環境であること
  • CodeCommit リポジトリは一つであり、ブランチで本番環境・テスト環境を区分している
  • EventBridge を用いて、CodeCommit のコミットをトリガーとして CodePipeline を実行している

運用上の課題・要件をまとめると以下の通りです。

  • テスト環境や本番環境など複数の環境に対してそれぞれデプロイ操作を行う必要がある
    • リリースの効率悪化
  • 環境毎のバージョン管理の差分が発生している
    • 環境ごとでモジュールバージョンの整合性が取れなくなる
  • 各環境ごとにデプロイすることもあれば、まとめてデプロイすることもある
    • 個別リリースと統合リリースを行える必要がある

上記の課題を改善するために、パイプラインの改修を試みました。

Git タグソリューションの実装

様々な方法を検討した結果、以下を実装しました。

  • CodeCommit のブランチを共通化して、Git タグを用いてデプロイ先を区分する方法

GitのブランチとタグによるAWS環境へのデプロイ戦略図

Git タグソリューションのメリット

  • リソースの追加削除を最小限に留めることができる
  • 運用手順の変更を最小限に留めることができる
    • Git タグを追加する手順が追加される
  • リリースの効率化&環境毎のバージョン管理を統合
    • 当初の課題を解決することが可能
  • 統合リリースと個別リリースが可能
    • テスト環境だけリリースしたいという要件でも実施可能

統合後の構成図は以下の通りです。
アーキテクチャとしての変更部分はあまりありません。

アップデート後のGitフローの流れの構成図

以下の 3 つのポイントに絞ってより詳細に解説します。

  • CodeCommit:main ブランチで各環境のソースコードをまとめて管理
  • EventBridge:Git タグをトリガーとしてパイプラインを実行
  • CodePipeline:main ブランチからビルドデプロイ

CodeCommit:main ブランチでソースコードを管理

ブランチを各環境で分けて使用していましたが、それを main ブランチに統合しました。

Git操作 タグを付与してプッシュする

ファイルを更新する動作としては以下の流れになります。

  1. ローカルブランチでファイルを更新
  2. 変更をコミット
  3. コミットに対してタグを付与
  4. コミットとタグを合わせてリモートブランチにプッシュ

Git タグを付ける際に、統合リリースか個別リリースかを判別するために、個別のプレフィックスをつけています。

  • 統合リリースの場合:main-*
  • 個別リリースの場合:test-*,stg-*,prod-*

まとめてデプロイしたいときは、統合リリースのタグを、個別でデプロイしたいときは各環境ごとの個別リリースのタグを付与します。

EventBridge:Git タグをトリガーとしてパイプラインを実行

Git タグによって、アクションする CodePipeline の環境を区別します。

CodeCommitの変更をEventBridgeで検知

EventBridge Rule のイベントパターンで Git タグをフィルターします。
そうすることにより、Git タグの値に応じて CodePipeline の実行を制御できます。

  • 統合リリースの場合:main-*
    • 3 つのテスト環境、ステージング環境、本番環境の CodePipeline を実行します
  • 個別リリースの場合:test-*,stg-*,prod-*
    • 各環境の CodePipeline を実行します

統合リリースと個別リリースの本番環境のイベントを検知する EventBridge のルールです。

{
  "source": ["aws.codecommit"],
  "detail-type": ["CodeCommit Repository State Change"],
  "resources": ["${repositoryARN}"],
  "detail": {
    "event": ["referenceCreated", "referenceUpdated"],
    "repositoryName": ["${repositoryName}"],
    "referenceType": ["tag"],
    "referenceName": [
      {
        "prefix": "prod-"
      },
      {
        "prefix": "main-"
      }
    ]
  }
}

CodePipeline:main ブランチからビルドデプロイ

EventBridge によって起動されたパイプラインによって、最新のコミットを取得しビルド・デプロイを実行します。

CodePipelineのパイプライン

CodePipeline のソースステージは、リポジトリとブランチを指定する形式です。
そのため、個別ブランチから統合した main ブランチに切り替えをして、必要なタイミングにのみパイプラインが実行されるようにしました。

パイプラインの改修方法を検討中の課題

パイプラインの改修を検討する中でぶつかった課題を色々と簡潔にまとめました。

  • CodePipeline の CodeCommit ソースがブランチ固定であること
    • CodePipeline の設定上、ブランチを事前に指定するため、ブランチの統合が必要
    • ソースブランチすべての環境分設定することも可能ですが、その場合は変更箇所や条件分岐など作業量が増えるため断念
  • EventBridge では、どのブランチのタグなのかは検知できない
    • コミットしたイベントとタグを付与したイベントが別で発火されるため AND 条件ができない
    • ブランチを間違えて Git タグを付与した場合でも CodePipeline が起動する
    • main ブランチではないブランチ上での操作は、Git タグをつけない運用ルールに決定
  • コミットメッセージでの分岐は不具合により見送り
    • Git タグ以外にも、コミットメッセージでの分岐を検討
    • 検証した結果、意図した結果にならないため AWS サポートへ問い合わせ
    • 改行を含む場合正しい判定ができない旨の回答のため利用を断念

様々な方法を検証・検討した結果「Git タグ」を活用する方法になりました。

ソリューションの展開

では、ここからは実際にデプロイを行う場合の流れと手順になります。
ここでは、以下 2 つで検証を行います。

  • 統合リリースの場合
    • main の Git タグをつけて、すべての環境でデプロイが行われるかを確認
  • 個別リリースの場合
    • prod の Git タグをつけて、本番環境のみデプロイが行われるかを確認

なお、別途検証用の環境として作成した構成で作業しているため、シングルアカウント内に各リソースを作成していますが、マルチアカウントにした場合でも動作としては変わりません。

統合リリースの場合

main ブランチで作業をします。

C:\Users\cold-airflow-git-tag>git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main

ファイルを変更したのでコミットします。

C:\Users\cold-airflow-git-tag>git add .

C:\Users\cold-airflow-git-tag>git commit -m "commit main"
[main 53828be] commit main
 1 file changed, 1 insertion(+), 1 deletion(-)

リモートブランチにプッシュします。

C:\Users\cold-airflow-git-tag>git push origin
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 328 bytes | 328.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Validating objects: 100%
To codecommit::us-east-1://cold-airflow-git-tag
   01b6fc3..53828be  main -> main

次に、Git タグをつけてプッシュします。
統合リリースのため「main-」から始まるタグを設定します。

C:\Users\cold-airflow-git-tag>git tag main-1.0

C:\Users\cold-airflow-git-tag>git push origin main-1.0
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To codecommit::us-east-1://cold-airflow-git-tag
 * [new tag]         main-1.0 -> main-1.0

では、パイプラインを見ていきます。

タグが作成されています。

CodeCommit リポジトリのタグが作成された画面

統合リリースのため、テスト環境用のパイプラインと本番環境用のパイプラインがどちらも起動しています。

テスト環境用のパイプラインと本番環境用のパイプラインがどちらも起動

デプロイが完了しイメージが作成されています。

テスト環境用 ECR リポジトリ

テスト環境のECRイメージ画面

本番環境用 ECR リポジトリ

本番環境のECRイメージ画面

個別リリースの場合

では、続いて個別リリースとして本番環境にのみデプロイをしてみます。
内容は先程とほぼ同じです。

C:\Users\cold-airflow-git-tag>git add .

C:\Users\cold-airflow-git-tag>git commit -m "commit prod"
[main 33a40e7] commit prod
 1 file changed, 2 insertions(+), 2 deletions(-)

C:\Users\cold-airflow-git-tag>git push origin
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 352 bytes | 352.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Validating objects: 100%
To codecommit::us-east-1://cold-airflow-git-tag
   53828be..33a40e7  main -> main

Git タグをつける際に、「prod-」から始まる名前にします。

C:\Users\cold-airflow-git-tag>git tag prod-1.0

C:\Users\cold-airflow-git-tag>git push origin prod-1.0
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To codecommit::us-east-1://cold-airflow-git-tag
 * [new tag]         prod-1.0 -> prod-1.0

プッシュし、本番環境用のパイプラインのみが実行されていることが確認できました。

prodタグで本番用のパイプラインのみ起動

ECR イメージも作成されています。

ECRイメージが作成されていることを確認

タグ一覧

Gitタグの一覧

まとめ

環境やサービスの制約を考慮しつつ最適な方法を模索した結果をまとめました。
運用の仕方によって、方法は異なると思いますが、同じような課題にあたったときは参考にしてみてください。

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

Cold-Airflow

2021年新卒入社。インフラエンジニアです。RDBが三度の飯より好きです。 主にデータベースやAWSのサーバレスについて書く予定です。あと寒いのは苦手です。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら