「個人開発の効率化」といった場面を目的にしています。ブランチへのプッシュをしたと同時に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にはテンプレートのフォーマットチェックや、更新前後の差分を取得するコマンドなどもあるので、状況に合わせてワークフローをカスタマイズするとさらに幅が広がります。
コメント