今回は2023年に公開されたCloudFormation Git Syncを紹介します。
背景
AWS CloudFomationはAWSリソースを対象とするIaCツールです。CloudFormationのコード管理はGitHub / GitLabなどのGitホスティングサービスを利用することが多いですが、CloudFormationコードの開発を終えて動作確認のためデプロイする場合、これまではAWS CLIやマネジメントコンソールなどのインターフェイスにアクセスするか、専用のCI/CDを自前で構築する必要がありました。前者の場合はアクセス先を切り替える必要があり、ここでコンテキストスイッチが発生します。
また、近年ではGitOpsという、Gitリポジトリとデプロイ先の環境を同期することで、デプロイの手間の削減や組織内の責任分界点の設定などを実現する手法が普及しています。
※参考:
ただし現状GitOpsをやろうと思うと、基本的にはGitOpsを実現するソフトウェアを自前で用意する必要があります。またAWS CloudFormationのファイルをGitOpsで扱うとなるとさらに選択肢は限られ、AWS CloudFormation Template Sync Controller for Flux などが必要でした。これらOSSやその基盤となるKubernetesを管理する必要もあり、個人的にCloudFormationでGitOpsを実現するハードルはかなり高いものでした。
CloudFormation Git Syncは、一言でいえば AWS CloudFormationに対するGitOpsを提供するAWSマネージドな機能 であり、対象のGitリポジトリをモニタリングし、Gitで管理するCloudFormationファイルの変更を検知すると、それをCloudFormation Stackに自動的に反映する機能を提供します。
今回CloudFormationがGit Syncに対応したことで、コンテキストスイッチやGitOps導入ハードルといった課題を解消し、CloudFormationのコードの開発速度の向上やCloudFormationを中心に扱うプロジェクトでのGitOpsの実現をサポートすることが期待できます。
なおAWSブログではGitHub Codespaces / GitHub Actions / CloudFormation Linterを使ったモダンな開発環境の例も紹介しています。
検証
ここからCloudFormation Git Syncを実際に検証します。なお今回は以下のような条件で検証をしています。
- Gitサービス:
GitLab
- CloudFormationで扱うAWSリソース:
Amazon S3
事前準備
CloudFormation Git Syncを利用するには、いくつかの条件があります。
- CloudFormationテンプレートを含むGitリポジトリを用意している
- AWS CodeStar Connectionを使ってGitリポジトリと接続可能である
- Git Syncを実行するためのIAMロールが用意されている
- CloudFormationとは別にパラメータを定義したファイルが必要である
Gitリポジトリの用意
1つ目の条件について、今回は cfn-git-test
というGitLabプロジェクトを作成し、以下のようなテンプレートファイルを配置しておきます。
AWSTemplateFormatVersion: "2010-09-09" Parameters: BucketName: Type: String Resources: S3: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName Tags: - Key: Test Value: false
AWS CodeStar Connectionによる接続
2つ目の条件は、AWSマネジメントコンソールにアクセスし、デベロッパー用ツールの画面から 設定
接続
を選択します。
接続を作成
を選択します。
接続先のGitプロバイダを選択します。今回は GitLab
を選択し、接続名も適当なものを入力します。
画面が遷移し、GitLabにログインした状態だと以下のような画面が表示されます。ここではAWSからGitLabに対するアクセス権限を許可してくれるよう申請が出されているので、 Authorize
を選択して許可します。
再びAWSの画面に戻るので 接続
を選択します。
これでAWSとGitLabとの接続が可能になりました。
IAMロールの用意
3つ目の条件ですが、Git Syncを利用する場合はIAMロールを新規に作成することも選択できます。今回は新規に作成するほうを選択しましたが、事前にIAMロールを作成する場合は以下のような権限が必要となります。
cloudformation:CreateChangeSet
cloudformation:DeleteChangeSet
cloudformation:DescribeChangeSet
cloudformation:DescribeStackEvents
cloudformation:DescribeStacks
cloudformation:ExecuteChangeSet
cloudformation:ListChangeSets
cloudformation:ValidateTemplate
events:PutRule
events:PutTargets
deploymentファイルの用意
4つ目の条件ですが、こちらもGit Sync利用時にテンプレートを作成することが可能です。事前に用意する場合は以下のようなファイルをGitリポジトリに格納します。
template-file-path: s3.yaml parameters: BucketName: cfn-git-sync-gitlab-20231228 tags: {}
CloudFomationとGitLabの同期
ここからGit Syncを利用してAmazon S3を作成します。
AWSマネジメントコンソールからCloudFomrationのメニューに移動し、スタックの作成を選択します。メニューの中に Gitから同期
という新しい項目が増えているので、こちらを選択します。
続いてスタックの詳細を設定します。今回スタック名は cfn-git-sync-gitlab
としました。次の デプロイファイルをスタック
というのは、事前準備の4つ目の条件で上げたdeploymentファイルを指します。今回はここでファイルを新規に作成するため 次のパラメータを使用してファイルを作成し、リポジトリに配置します。
を選択します。
テンプレート定義リポジトリ では、アクセス先のリポジトリの情報を設定します。今回は新規にGitリポジトリとの接続を行うため、 Gitリポジトリをリンクする
を選択します。それ以降は使用するCodeStar Connection名やリポジトリ・ブランチなど、必要な値を設定します。
続いてIAMロールの設定です。ここでは事前準備3つ目の条件にあったIAMロールを指定しますが、今回は新規で作成します。
デプロイファイルパラメーターには、CloudFormationの作成で必要なパラメータを指定します。今回は BucketName
というパラメータを設定するため、以下のように設定しました。
次に スタックオプションの設定 ですが、ここでIAMロールを指定する必要があります。ここではスタック操作に使用するIAMロールを指定するため、CloudFormationに対する権限を付与したものを使用しました。
以降はデフォルトのまま進め、スタックの作成を行います。すると以下のように、リポジトリとの同期状態やプロビジョニングステータスが表示されます。
この時リソースを見ると GitSyncSetupWaitCondition
というリソースが作成されています。
ここでGitLabに移動すると、AWSによって作成されたMerge Request (以降MR) が確認できます。
MRの内容はdeploymentファイルをコミットするものです。
ちなみにこのままの状態で再びCloudFormationのほうを見ると、プロビジョニングステータスが失敗していることを確認できます。
これはMRがマージされていないためにdeploymentファイルが見つからないためです。
GitLabプロジェクトに戻ってMRをマージします。
CloudFormationの画面を見るとリポジトリ同期のステータスやプロビジョニングステータスが変化します。
しばらくするとプロビジョニングに成功しました。
同期イベントを見ると、ChangeSetの作成と実行が行われた様子を確認できます。
リソースを見るとS3バケットが作成されたのを確認できます。
テンプレートファイルの変更と実リソースへの反映
続いてGitlab上のテンプレートに修正を加えてみます。今回はバージョニングを有効にする設定を追加しました。今回は横着してmainブランチに直接コミットしていますが、GitLab CI/CD等と組み合わせてMR作成時に構文チェックなどを走らせるのが安全でしょう。
コミットすると再びリポジトリ同期などのステータスが変化します。
しばらくするとプロビジョニングに成功し、変更も反映されているのを確認できました。