Rain × GithubActionsによるCI/CD構築

「個人開発の効率化」といった場面を目的にしています。ブランチへのプッシュをしたと同時にCloudFormationのスタックデプロイが完了することを目指しました。

CloudFormationテンプレート作成やパイプライン構築のポイントは次のとおり。

  • リソースはCloudFormationのネストスタックで作成する。
  • 親となるテンプレートは子スタック用のyamlファイルをs3bucketから参照する。
  • Cloudformationスタックを新規作成する場合だけではなく、更新作業もブランチpushで完了させる。

パイプライン構築

workflowを表すyamlファイルを次のとおり作成。

name: CloudFormation Deploy Workflow

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    env:
      AWS_REGION: "ap-northeast-1"
      PROJECT_NAME: "project"

    steps:
    - name: Set up brew
      run: echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH

    - name: Install Rain
      run: |
        brew install rain
        echo "rain -v"
        rain -v

    - name: Checkout repository
      uses: actions/checkout@v3

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

    - name: Get AWS Account ID
      run: |
        ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
        echo "AWS_ACCOUNT_ID=$ACCOUNT_ID" >> $GITHUB_ENV

    - name: Upload to S3
      run: |
        aws s3 sync ./${{ env.PROJECT_NAME }} s3://cf-${AWS_ACCOUNT_ID}-${{ env.AWS_REGION }}/${{ env.PROJECT_NAME }}

    - name: Deploy CloudFormation stack
      run: |
        rain deploy -y main-template.yaml

このワークフローを実行することで、mainブランチへのpushをトリガーに、CloudFormationスタックのデプロイが完了します。

以下、各ステップの解説です。

・Set up brew

Rainをインストールするためにbrewコマンドが必要なので、$GITHUB_PATHにパスを追加しています。

・Install rain

CLIでCloudFormationスタックのデプロイを完了するためのツール、「Rain」をインストールする。

Rainを使うとスタックの新規作成・更新を同じコマンドで実行できるので便利。

・Checkout repository

リポジトリのコードを取得

・Configure AWS credentials

 AWS認証情報のセット。
※サンプルコードではシークレットからAWSのアクセスキーやシークレットアクセスキーを取得する方法で記述していますが、現在ではOIDCを使用する方法が推奨されています。
参考:https://qiita.com/sigma_devsecops/items/3e2fb50770def1c3a098

・Get AWS Account ID

Account IDを取得する処理。今回はS3バケット名にアカウントIDを使用しているため。

・Upload to S3

ローカルで作成したCloudFormationのテンプレートファイルをS3にアップロードします。
これを行うのは、CloudFormationの親スタックの記述が関係しています。

今回、ネストスタックの親テンプレートのリソースセクションは次のように記載しています。

Resources:
 VPCStack:
   Type: AWS::CloudFormation::Stack
   Properties:
     TemplateURL: !Sub https://s3.amazonaws.com/cf-${AWS::AccountId}-${AWS::Region}/IMDSv1_Vulnerability_Test/vpc-template.yaml

 S3Stack:
   Type: AWS::CloudFormation::Stack
   Properties:
     TemplateURL: !Sub https://s3.amazonaws.com/cf-${AWS::AccountId}-${AWS::Region}/IMDSv1_Vulnerability_Test/s3-template.yaml

 EC2Stack:
   Type: AWS::CloudFormation::Stack
   DependsOn: VPCStack
   Properties:
     TemplateURL: !Sub https://s3.amazonaws.com/cf-${AWS::AccountId}-${AWS::Region}/IMDSv1_Vulnerability_Test/ec2-template.yaml

このように、親スタックはS3バケットから子スタックのテンプレートを参照する記述にしているため、workflowでスタックをS3にアップロードする処理を入れる必要があります。

・Deploy CloudFormation stack

rain deployコマンドを使ってスタックのデプロイを行います。

まとめ

CloudFormationで個人開発をする場合、スタックのデプロイを効率化するのに役立つと思います。

Rainにはテンプレートのフォーマットチェックや、更新前後の差分を取得するコマンドなどもあるので、状況に合わせてワークフローをカスタマイズするとさらに幅が広がります。

コメント

タイトルとURLをコピーしました