GitHub Actions ワークフローで CloudFormation テンプレートを Amazon S3 へアップロードし、クイック作成リンクを作成する

2022.04.28

こんにちは、森田です。

CloudFormationをGitHubで管理する場合、せっかくならpushと同時にAmazon S3へもアップロードし、そのままクイック作成リンクにも反映させたいですよね。

本記事では、実際にS3バケット等の必要なリソース作成から GitHubで管理しているCloudFormationテンプレートをGitHub Actions ワークフローを用いて、Amazon S3へアップロードを行い、クイック作成リンクもうまく更新されているかまで試してみました。

構成図

以下のようなリソース、ワークフローを構築します。

AWSリソースの準備

今回以下のAWSリソースを準備します。

S3バケット

CloudFormationテンプレートを保存するためのS3バケットを作成します。

また、CloudFormationテンプレートを誰でも利用できるようにする場合は、以下の手順でバケットの公開設定を行ってください。

1. パブリックアクセスのブロックをオフにする

2. パブリック読み取りアクセス権を付与するバケットポリシーを付与する

バケットポリシー

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::作成したバケット名/*"
		}
	]
}

 

IAMポリシー

S3へアップロードするためのポリシーを作成します。アップロード時にはaws s3 syncを使用するため、以下のようにポリシーを作成します。

IAMポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::作成したバケット名",
                "arn:aws:s3:::作成したバケット名/*"
            ]
        }
    ]
}

 

IAMユーザ

上記で作成したIAMポリシーをアタッチし、IAMユーザを作成します。

作成した際のアクセスキーID、シークレットアクセスキーは、メモしておきます。

 

GitHubの準備

リポジトリの作成を行った後で、以下の作業を行います。

Secrets 情報の追加

先ほどのIAMユーザ作成時に払い出されたアクセスキーID、シークレットアクセスキーをそれぞれAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYとして保存します。

また、S3を作成したリージョン、バケット名もAWS_DEFAULT_REGIONBUCKET_NAMEとして保存します。

コードの作成

ディレクトリ構成

├── .github
│   └── workflows
│       └── cfn_s3_upload.yml
└── cloudformation
    └── sample.yml

動作確認のため、VPCを1つ作るだけのシンプルなテンプレートを用意し、cloudformationディレクトリ内に配置します。

cloudformation/sample.yml

Description: VPC Create Sample 

Parameters:
  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 10.192.0.0/16

  EnvName:
    Description: An environment name that is prefixed to resource names
    Type: String


Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Ref EnvName

続いて、ワークフローファイルの作成を行います。 configure-aws-credentialsを使用することで簡単にアクセスキーIDなどをAWS CLIに渡すことができます。

.github/workflows/cfn_s3_upload.yml

# This is a basic workflow to help you get started with Actions

name: CloudFormation S3 Deploy

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  push:
    branches: [ master, main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_DEFAULT_REGION }}

      - name: Copy files to the s3 bucket
        env:
          BUCKET_NAME: ${{ secrets.BUCKET_NAME }}
        run: |
          aws s3 sync ./cloudformation s3://${BUCKET_NAME}

やってみる

では、上記の準備ができましたら、実際にpushしてみます。

git add .
git commit -m "dev"
git push origin main

push後、GitHub上でワークフローのログが確認ができ、正常に終了すると以下のようになります。

 

アップロードされたテンプレートを利用してクイック作成リンクでスタック作成

アップロードされたテンプレートのオブジェクト URLを利用し、クイック作成リンクでスタックを作成し、正常に動作するかを確認します。

クイック作成リンク

https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/quickcreate?templateUrl=https://{BUCKET_NAME}.s3.ap-northeast-1.amazonaws.com/sample.yml&stackName=hoge

2回目のpush

以降のpushも反映されるかを確認してみます。以下のようにファイルを変更し、再度pushします。

cloudformation/sample.yml

Description: VPC Create Sample version 2

Parameters:
  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 10.192.0.0/16

  EnvName:
    Description: An environment name that is prefixed to resource names
    Type: String


Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Ref EnvName

push後、ワークフローの成功後に先ほどと同じクイック作成リンクを開きます。

スタックの説明が変更されているため、問題なく更新ができていることが確認できます。

最後に

今回はシンプルにGitHub Actionsワークフローでテンプレートのアップロードのみを行ってみました。

CloudFormation Guardを使用することで、コンプライアンスチェックも行うことができますので、機会があればこのワークフローにも組み込んでみます。