CloudFormationのGit同期設定方法

cloudformation_eyecatch

こんにちは、インフラエンジニアの土肥です。

2023年11月に追加されたCloudFormationのGit同期機能を試しながら必要なファイルや設定をまとめていきます。

全体の流れ

  • IAMロールの作成
  • Gitリポジトリとの接続を作成する
  • ファイルの準備
  • スタックの作成
  • スタックの更新(リポジトリの更新)
  • リソースの削除

CloudFormation用IAMロールの作成

ユーザが操作してスタックを作成した場合は、IAMユーザの権限が適用されるのでCloudFormation用のIAMロールは不要(オプション)になっています。

今回はGitリポジトリの変更を検知して自動でスタックを作成・更新するためCloudFormation用のIAMロールが必要になります。

作成するリソースに応じた最小権限が望ましいのですが、今回はadministratorを使います。

信頼ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudformation.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

許可ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}

Gitリポジトリアクセス用のロール作成

CloudFormationがGitリポジトリの変更を検知したり、ソースを取得するためのロールです。

スタック作成画面からもこのロールを作成できますが、今回は事前に準備します。

信頼ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CfnGitSyncTrustPolicy",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudformation.sync.codeconnections.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

許可ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SyncToCloudFormation",
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStacks",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:GetTemplate",
                "cloudformation:ListChangeSets",
                "cloudformation:ListStacks",
                "cloudformation:ValidateTemplate"
            ],
            "Resource": [
                "arn:aws:cloudformation:ap-northeast-1:<AccountId>:stack/",
                "arn:aws:cloudformation:ap-northeast-1:<AccountId>:stack/*"
            ]
        },
        {
            "Sid": "PolicyForManagedRules",
            "Effect": "Allow",
            "Action": [
                "events:PutRule",
                "events:PutTargets"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "events:ManagedBy": [
                        "cloudformation.sync.codeconnections.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Sid": "PolicyForDescribingRule",
            "Effect": "Allow",
            "Action": "events:DescribeRule",
            "Resource": "*"
        }
    ]
}

スタックの作成画面でこのロールを作成すると、SyncToCloudFormationResource部分が以下のようになります。

  "Resource": [
      "arn:aws:cloudformation:ap-northeast-1:<AccountId>:stack/<StackName>",
      "arn:aws:cloudformation:ap-northeast-1:<AccountId>:stack/<StackName>/*"
  ]

他のスタックでも使う場合はご注意ください。

Gitリポジトリとの接続を作成する

本記事では、GitリポジトリにGitHubを利用します。

今回の本筋ではないので手順などは公式のドキュメントを参考にしてください。

GitHub への接続を作成する – デベロッパーツールコンソール

ファイルの準備

CloudFormationでGit同期を行うためには、テンプレートのほかにデプロイファイルを準備する必要があります。

デプロイファイルは、スタックを作成する時に渡すパラメータとスタックのタグを記載するファイルです。

今回は、テックブログ用のリソースであることを示すプレフィックスをパラメータで渡します。

template-file-pathは、リポジトリルートから見たテンプレートファイルのパスを入力する必要がありますので注意してください。(相対パスだとエラーになりました。)

# deployment.yml

template-file-path: cloudformation-template.yml
  parameters:
    Prefix: 'aitp-tech-blog'
  tags:
    Project: 'aitp-tech-blog'

テンプレートファイルにはVPCを作成する記述をしておきます。

# cloudformation-template.yml

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  Prefix:
    Type: String

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '10.1.0.0/16'
      Tags:
        - Key: Name
          Value: !Sub "${Prefix}-vpc"
        - Key: Project
          Value: !Ref Prefix

パラメータ名はテンプレートとデプロイファイルで一致している必要があります。

ファイルが準備できたらGitHubにプッシュして準備完了です。

CloudFormationからスタックを作成

CloudFormationのスタック作成画面から「Gitから同期-新規」を選択します。

cfn-git-sync-01

スタックの詳細を設定

デプロイファイルをスタック

  • 「リポジトリに自分のファイルを提供しています。」を選択

テンプレート定義リポジトリ

  • 「Gitリポジトリをリンクする」を選択
  • 「GitHub」を選択
cfn-git-sync-02

テンプレート定義リポジトリ(続き)

  • 接続を選択
  • リポジトリを選択(aitp-tech-cfn-git-sync)
  • ブランチを選択(mainブランチ)
  • デプロイファイルのパスを選択(deployment.yml)
  • IAMロールを選択(リポジトリ接続用のロール)
cfn-git-sync-03

スタックオプションの設定

CloudFormationが各種リソースを作成するためのロールを指定します。

アクセス許可

  • CloudFormation用IAMロールを選択
cfn-git-sync-04

必要な設定は以上です。

最後まで進んで「送信」をクリックしてください。

スタック作成の確認

「Gitと同期-新規」タブでGitの同期とプロビジョニングが完了していることが確認できます。

「リソース」タブを確認するとVPCが作成されていることが確認できます。

スタックの更新

リポジトリをの対象ブランチにプッシュすることで、対応するスタックを更新することができます。

折角なのでdevelopブランチにプッシュしてマージします。

# cloudformation-template.yml

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  Prefix:
    Type: String

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '10.1.0.0/16'
      Tags:
        - Key: Name
          Value: !Sub "${Prefix}-vpc"
        - Key: Project
          Value: !Ref Prefix

# 以下追加

  Subnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-1a
      CidrBlock: '10.1.0.0/24'
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${Prefix}-subnet-1a"
        - Key: Project
          Value: !Ref Prefix
マージしたプルリクエスト

mainブランチを対象にしているので、マージされたタイミングでスタックの更新が始まります。

リソースにサブネットが追加されました。

以上が作成から更新までの流れです。

スタックの削除

スタックの削除は通常通りコンソールから「削除」をクリックすることで削除可能です。

ただし、スタックを削除しただけではCloudFormationとGitリポジトリの紐付けが残ってしまうのでCLIからリンクを削除する必要があります。

$ aws codestar-connections list-repository-links                                                                                                                    
{
    "RepositoryLinks": [
        {
            "ConnectionArn": "arn:aws:codestar-connections:ap-northeast-1:<AccountId>:connection/e1c491fe-2833-465a-b2b2-33d1fe275b11",
            "OwnerId": "hito-kotaro",
            "ProviderType": "GitHub",
            "RepositoryLinkArn": "arn:aws:codestar-connections:ap-northeast-1:<AccountId>:repository-link/b54d5e3f-ebb8-49e0-b965-d19bf9401ddf",
            "RepositoryLinkId": "<RepositoryLinkId>",
            "RepositoryName": "aitp-tech-cfn-git-sync"
        }
    ]
}


# 削除コマンドにレスポンスはありませんでした。
$ aws codestar-connections delete-repository-link --repository-link-id <RepositoryLinkId>

コマンドのリファレンス

まとめ

ちょっとしたデプロイパイプラインとして利用するのであれば手軽に設定できて使い勝手はそこそこ良さそうですね。

必要なリソースやファイルは以下の通りでしたとなります。

必要なリソース

  • CloudFormation用IAMロール
  • Gitリポジトリ接続用IAMロール
  • Gitリポジトリとの接続
  • Gitリポジトリ(今回はGitHub)

必要なファイル

  • デプロイファイル
  • テンプレートファイル

参考URL

関連するタグ