LoginSignup
2
2

More than 1 year has passed since last update.

AWS CDK ✖︎ GitHub Actionsで実現するIaCのCI/CD ①

Posted at

はじめに

実務への応用を効かせようとIaCのCI/CDについて学習を進めるべく、手始めに、AWS CDKとサーバーレスアプリケーション(Lambda ✖︎ API Gateway)を使用した構成を実現しました。

また、AWS Codeシリーズを使用したCI/CDも検討しましたが、cdkに記述する内容が多くなってしまう点と、ミニマムかつシンプルに実装できる点からCI/CDにはGithub Actionsを使用しました。

備忘がてら実装の記録を残します!

今回作成したコードは以下のリポジトリにあげています。

開発環境

  • CDK : 2.72.1 (build ddbfac7)
  • TypeScript : typescript@4.9.5

Stack

cdkのinitや最初に必要な手順は省略します。

メインとなるappは以下のようになっています。

lib/cdk-github-actions.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { Construct } from 'constructs';

export class CdkGithubActionsStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    
    // Create a Lambda function with code from the "src/lambda" directory
    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_16_X,
      code: lambda.Code.fromAsset('src/'),
      handler: 'hello.handler',
    });

    // defines an API Gateway REST API resource backed by our "hello" function.
    new apigateway.LambdaRestApi(this, 'GithubActionsEndpoint', {
      handler: hello,
      endpointTypes: [ apigateway.EndpointType.REGIONAL ],
    });

  }
}

CI/CD

CI/CDを検討するにあたり、ブランチ戦略を決めます!

今回は、シンプルさを優先してGithub Flowで実装しました。
(実務ではGit Flowを使用する場合がほとんどだと思いますが)

ざっくりとパイプラインの流れを説明すると・・・

  1. mainブランチから機能ブランチを作成し、プッシュ
  2. github上でpull requestを出すと1つ目のトリガーが起動
  3. cdkのbuildや単体テスト、スナップショットテストが実行
  4. mainブランチへのマージトリガーに2つ目のトリガーが起動
  5. cdkがAWS環境にデプロイされる

スクリーンショット 2023-04-07 23.30.42.png

パイプラインの実行ファイルを作成し、cdk.ymlに内容を記載

$ mkdir .github/workflows && touch cdk.yml
.github/workflows/cdk.yml
name: cdk-github-actions
on:
  push:
    branches:
      - main
  pull_request:
jobs:
  build-test-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js 16.x
        uses: actions/setup-node@v1
        with:
          node-version: 16.x

      - name: Setup dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Unit tests
        if: contains(github.event_name, 'pull_request')
        run: npm run test:app

      - name: CDK Diff Check
        if: contains(github.event_name, 'pull_request')
        run: npm run cdk:diff
        env:
          AWS_DEFAULT_REGION: 'ap-northeast-1'
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Snapshot tests
        if: contains(github.event_name, 'pull_request')
        run: npm run test:snapshot -- -u

      - name: CDK Deploy
        if: contains(github.event_name, 'push')
        run: npm run cdk:deploy
        env:
          AWS_DEFAULT_REGION: 'ap-northeast-1'
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Snapshot Testing

cdkのテスト方法には、Fine-grained testsSnapshot testsがあるが、
ここでは、IaCのCI/CDの実行確認がメインなので、Snapshot Testingを使用して、テンプレートの差分を確認するだけにとどめたいと思います。

Snapshot Testingは、事前に記録されたスナップショット(今回は CloudFormation のテンプレートにあたる)に対して、テスト実行時の実装から作成した CloudFormation のテンプレートを検証(比較)します。ここで、差分がなければテスト結果OK、差分があればテスト結果NG となります。

cdk-githubactions.test.ts
import { App } from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { CdkGithubActionsStack } from '../lib/cdk-github-actions-stack';

test('SnapshotTest', () => {
  const app = new App();
  const stack = new CdkGithubActionsStack(app, 'CdkGithubActionsStack', {});
  const template = Template.fromStack(stack);
  expect(template.toJSON()).toMatchSnapshot();
});

エラーへの対処

tsの型が合わず、thisでエラーになってしまう

スクリーンショット 2023-04-06 23.13.15.png

【結論】

  • packge.jsonのaws-libのバージョンを揃える必要がある

    1.packege.lock.jsonの削除
    2.packege.jsonからバージョンを変更
    3.npm install

スクリーンショット 2023-04-07 8.25.14.png

確認

コードをcommit → push → pull request作成 → mergeし、GithubActionsを確認してみると・・・
それぞれしっかりとパイプラインが実行されています!

  • pull request作成時
    スクリーンショット 2023-04-07 23.56.05.png

  • mainブランチへマージ時
    スクリーンショット 2023-04-07 23.56.42.png

さいごに

IaCのCI/CDについて最もシンプルな構成から実現してみました。

次回はより実運用に近くなるよう、開発環境,Staging環境,本番環境を用意し、複数環境に対するIacのCI/CD方法をやってみたいと思います。

参考

AWS CDK

Github Actions

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2