AWS CDK で環境ごとにパラメータを変えてデプロイを行う

AWS

はじめに

本記事では AWS CDK で環境ごとにパラメータを変えてデプロイを行う方法についてまとめます。
実際のPJでは開発環境と本番環境が存在し、各環境でリソースに設定する値が異なる場合がありますが、そういった場合に本記事で紹介する方法が役立つと思います。

手順

プロジェクトの作成はAWS Cloud Development Kit (CDK) の開始方法 | はじめにを参考に行います。

プロジェクトの作成

  1. CDK がインストールされていることを確認します
$ cdk --version
2.46.0 (build 5a0595e)
  1. 初めて使用するアカウント、リージョンの場合はcdk bootstrap aws://ACCOUNT-NUMBER/REGIONを実行します
$ cdk bootstrap aws://123456789012/ap-northeast-1
  1. CDK プロジェクトを作成します
    本記事では言語は typescript を使用します
PROJECT_NAME=cdk-demo
mkdir $PROJECT_NAME
cd $PROJECT_NAME
cdk init --language typescript

cdk initが完了すると、以下ディレクトリ、ファイルが作成されます。

.
├── bin
│   └── cdk-demo.ts
├── cdk.json
├── jest.config.js
├── lib
│   └── cdk-demo-stack.ts
├── node_modules
│   ├── abab
│   ├── ...
├── package.json
├── package-lock.json
├── README.md
├── test
│   └── cdk-demo.test.ts
└── tsconfig.json

リソースの作成

例として、CodeBuildを作成します。
cdk.json のcontextブロックに環境ごとに異なる値を追加します。

{
  "app": "npx ts-node --prefer-ts-exts bin/cdk-demo.ts",
  "watch": {
    "include": [
      "**"
    ],
    "exclude": [
      "README.md",
      "cdk*.json",
      "**/*.d.ts",
      "**/*.js",
      "tsconfig.json",
      "package*.json",
      "yarn.lock",
      "node_modules",
      "test"
    ]
  },
  "context": {
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
    "@aws-cdk/core:stackRelativeExports": true,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
    "@aws-cdk/aws-lambda:recognizeVersionProps": true,
    "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
    "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
    "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
    "@aws-cdk/core:checkSecretUsage": true,
    "@aws-cdk/aws-iam:minimizePolicies": true,
    "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
    "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
    "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
    "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
    "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
    "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
    "@aws-cdk/core:enablePartitionLiterals": true,
    "@aws-cdk/core:target-partitions": [
      "aws",
      "aws-cn"
    ],
    "dev": {
      "branchName": "develop"
    },
    "prod": {
      "branchName": "production"
    }
  }
}

lib/cdk-demo-stack.ts を編集します。

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as codebuild from 'aws-cdk-lib/aws-codebuild';
import * as iam from 'aws-cdk-lib/aws-iam';

export class CdkDemoStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const env = this.node.tryGetContext('environment')
    const valArray = this.node.tryGetContext(env)


    const codeBuildServiceRole = new iam.Role(this, 'CodeBuildServiceRole', {
      assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'),
      path: '/',
      inlinePolicies: {
        codeBuildServicePolicies: new iam.PolicyDocument({
          statements: [
            new iam.PolicyStatement({
              effect: iam.Effect.ALLOW,
              actions: [
                'ecr:*',
              ],
              resources: [
                '*',
              ],
            }),
          ],
        }),
      },
    });

    new codebuild.Project(this, 'CreateProject', {
      projectName: 'example',
      source: codebuild.Source.gitHubEnterprise({
        httpsCloneUrl: "https://github.xxx.git",
      }),
      role: codeBuildServiceRole,
      buildSpec: codebuild.BuildSpec.fromObject({
        version: '0.2',
        phases: {
          install: {
            'runtime-versions': {
              python: "3.8"
            },
          },
          build: {
            commands: [
              'echo test',
            ]
          },
        },
      }),
      environment: {
        buildImage: codebuild.LinuxBuildImage.STANDARD_5_0,
        environmentVariables: {
          ENV: {
           type: codebuild.BuildEnvironmentVariableType.PLAINTEXT,
           value: env,
         }
        },
      },
    });
  }
}

以下部分で実行時に指定した”environment”パラメータを受け取るようにしています。

const env = this.node.tryGetContext('environment')
const valArray = this.node.tryGetContext(env)

こちらをデプロイします。
cdk diffで作成、変更されるリソースを事前に確認します。-cオプションを使用して、KEY=VALUE形式でコンテキストの値を追加します。

$ cdk diff -c environment=dev
Stack CdkDemoStack
current credentials could not be used to assume 'arn:aws:iam::155385059623:role/cdk-hnb659fds-lookup-role-155385059623-ap-northeast-1', but are for the right account. Proceeding anyway.
(To get rid of this warning, please upgrade to bootstrap version >= 8)
current credentials could not be used to assume 'arn:aws:iam::155385059623:role/cdk-hnb659fds-deploy-role-155385059623-ap-northeast-1', but are for the right account. Proceeding anyway.
IAM Statement Changes
┌───┬─────────────────────────────────────────────┬────────┬─────────────────────────────────────────────┬──────────────────────────────────────────────┬───────────┐
│   │ Resource                                    │ Effect │ Action                                      │ Principal                                    │ Condition │
├───┼─────────────────────────────────────────────┼────────┼─────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────┤
│ + │ ${CodeBuildServiceRole.Arn}                 │ Allow  │ sts:AssumeRole                              │ Service:codebuild.amazonaws.com              │           │
├───┼─────────────────────────────────────────────┼────────┼─────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────┤
│ + │ *                                           │ Allow  │ ecr:*                                       │ AWS:${CodeBuildServiceRole}                  │           │
├───┼─────────────────────────────────────────────┼────────┼─────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────┤
│ + │ arn:${AWS::Partition}:codebuild:${AWS::Regi │ Allow  │ codebuild:BatchPutCodeCoverages             │ AWS:${CodeBuildServiceRole}                  │           │
│   │ on}:${AWS::AccountId}:report-group/${Create │        │ codebuild:BatchPutTestCases                 │                                              │           │
│   │ Project3E2616D7}-*                          │        │ codebuild:CreateReport                      │                                              │           │
│   │                                             │        │ codebuild:CreateReportGroup                 │                                              │           │
│   │                                             │        │ codebuild:UpdateReport                      │                                              │           │
├───┼─────────────────────────────────────────────┼────────┼─────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────┤
│ + │ arn:${AWS::Partition}:logs:${AWS::Region}:$ │ Allow  │ logs:CreateLogGroup                         │ AWS:${CodeBuildServiceRole}                  │           │
│   │ {AWS::AccountId}:log-group:/aws/codebuild/$ │        │ logs:CreateLogStream                        │                                              │           │
│   │ {CreateProject3E2616D7}                     │        │ logs:PutLogEvents                           │                                              │           │
│   │ arn:${AWS::Partition}:logs:${AWS::Region}:$ │        │                                             │                                              │           │
│   │ {AWS::AccountId}:log-group:/aws/codebuild/$ │        │                                             │                                              │           │
│   │ {CreateProject3E2616D7}:*                   │        │                                             │                                              │           │
└───┴─────────────────────────────────────────────┴────────┴─────────────────────────────────────────────┴──────────────────────────────────────────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Parameters
[+] Parameter BootstrapVersion BootstrapVersion: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/cdk-bootstrap/hnb659fds/version","Description":"Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"}

Conditions
[+] Condition CDKMetadata/Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"af-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-northwest-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"sa-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-2"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]}]}

Resources
[+] AWS::IAM::Role CodeBuildServiceRole CodeBuildServiceRoleA9C1F6A8
[+] AWS::IAM::Policy CodeBuildServiceRole/DefaultPolicy CodeBuildServiceRoleDefaultPolicyC1569022
[+] AWS::CodeBuild::Project CreateProject CreateProject3E2616D7

Other Changes
[+] Unknown Rules: {"CheckBootstrapVersion":{"Assertions":[{"Assert":{"Fn::Not":[{"Fn::Contains":[["1","2","3","4","5"],{"Ref":"BootstrapVersion"}]}]},"AssertDescription":"CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."}]}}

確認して問題なければcdk deployを実行します。

$ cdk deploy -c environment=dev
(省略)

 ✅  CdkDemoStack

✨  Deployment time: 114.33s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CdkDemoStack/9977fe20-658f-11ed-84cf-0e3fab9bc4d7

✨  Total time: 131.24s

リソースが期待通りに作成できていることを確認します。

実行時に”-c”オプションで指定した通り、環境ごとの値を環境変数に設定できています。

おわりに

本記事では AWS CDK でプロジェクト作成~リソースを作成する流れをまとめました。
この記事がどなたかの参考になれば幸いです。

参考

コメント