Published on

AWS CDK starter kit by kotlin - 1 - 一先ずリリース

Overview

IaC(Infrastructure as Code)を始める方や既存 CloudFormation や Terraform より IaC をしている方が CDK を用いて IaC が出来ることを目指して構成してみました。

一先ず今記事では Sample の Project を CDK にてリリースしてみましょう! Incremental 的な考えで着実に Production 化出来ることを目指しましょう。

なので用意されている Git Repository を使って CloudWatch を作成してみます。 いざ手を動かすと体験出来るものがあるので、ぜひご自身の Local 環境で実行してみて下さい。

次の要素をみていきます。

前提条件

下記の条件を揃っている方がご活用することを期待しています。

  • Git を使える人
  • JDK11 を開発 Computer に準備している
  • Gradle の実行したことがある
  • AWS CLI を使える
    • AWS Credential(~/.aws/credential)に Profile が準備されていること
  • Linux/Unix 環境の利用者
    • Windows の方は AWS CLI や Environment Variable の使い方を適宜応用して下さい
  • IAM の設定
    • 管理者から IAM 設定をしてもらるか、ご自身で権限付与を行って下さい
    • Test/PoC 環境ならば arn:aws:iam::aws:policy/AdministratorAccess で簡単に試せます
      • 初心者ほど勝手に壊して良い環境でトライしましょう
    • AdministratorAccess が取得が難しければ、ManagedPolicy で下記を取得しましょう
      • arn:aws:iam::aws:policy/AmazonEC2FullAccess
      • arn:aws:iam::aws:policy/CloudWatchFullAccess

Test Scenario

  1. VPC
    1. 既に Deployment された VPC をロードする
    2. 該当 VPC から Availability Zone を Output する
  2. CloudWatch を Deployment する
    1. LogGroup を作成する
    2. LogStream を作成する

CloudFormation と同様に既に Deployment されている AWS Resource もロードして使えるので、ロードした結果を出してみましょう。

Provisioning するために準備がたくさん必要なものはその分時間がかかります。なので比較的早く準備が終わる CloudWatch を Deployment してみます。

まずは結果どうなるのかをみてみる。CDK を実行して CloudFormation を確認

  • AWS Console - CloudFormation
AWS Console - CloudFormation

CloudWatch が生成されていることが分かります。

#SHELL: cdk synthesize SA201-cloudwatch
Resources:
  logtestgroupAB1D42A7:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: log-test-group
      RetentionInDays: 1
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: SA201-cloudwatch/log-test-group/Resource
  debuggingstream4ED54E04:
    Type: AWS::Logs::LogStream
    Properties:
      LogGroupName:
        Ref: logtestgroupAB1D42A7
      LogStreamName: debugging-stream
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Metadata:
      aws:cdk:path: SA201-cloudwatch/debugging-stream/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/zPUM7Q01jNQdEgsL9ZNTsnWr07OL0rVqw4uSUzO1nHOzysuKSpNLtFxTssLSi3OLy1KTq3VAanNyU8v1qv2yU93L8ovLQDJw9lARnBJUWpiLlQUwqmt1fFKLEvUNzTUM9AztFDMKs7M1C0qzSvJzE3VC4LQALirzCCOAAAA
    Metadata:
      aws:cdk:path: SA201-cloudwatch/CDKMetadata/Default
#SHELL: cdk synthesize SA201-infra
Outputs:
  vpcaz:
    Value: ap-northeast-1a, ap-northeast-1c, ap-northeast-1d
    Export:
      Name: vpc-az
Resources:
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/zPUM7Q01jNQdEgsL9ZNTsnWT84vStWrDi5JTM7WCUotzi8tSk7VcU7L8y8tKSgt0XHOzysuKSpNLgGJweRrdbwSyxL1DQ31DPQMLRSzijMzdYtK80oyc1P1giA0AMFTQdJoAAAA
    Metadata:
      aws:cdk:path: SA201-infra/CDKMetadata/Default

これだけみてみると CloudFormation の Yaml ファイル直接書いた方が早くないか?と思うかも知れません。 これだけだとしても、CloudFormation の書き方を勉強するよりは Java Package の Type をみて書いた方が早いと思うし何より Syntax ミスが無くて良いと思います。

Git Repository から Sample Project をダウンロード

CDK と Kotlin を組み合わせる時に必要な Gradle Project を Git Repository にて纏めました。

将来的にもこの Project を Template として活用すれば、業務の Project も初めやすいと思います。

最初にするべき CDK 環境作り

cdk 自体の準備

CDK CLI 自体がまず必要ですよね。私は MAC 環境なので HomeBrew を使います。

$cdk bootstrap

この辺は別の Post にて詳しく扱いますが、CDK が実行されるためには CDKToolkit という AWS Resource が必要になります。

この Stack にて CDK が動作するために必ずひつようなプロセスになります。 Test Environment であれば基本値だけで使えるため、コマンドを一回実行しましょう

cdk bootstrap

エラーになりえるケースとしては AWS_PROFILE 指定が無かったり

  • export AWS_PROFILE=_____
  • cdk bootstrap --profile ____

environment variable

直接コードに書いても良い内容ですが、他の Region に試したりそもそも AWS Account が分離されていたりするケースが多いので習慣的に Shell の Environment Variable に AWS Account 情報を Load して使うのが個人的に好きな方法です。

.env
CDK_DEPLOY_ACCOUNT=00000000000
CDK_DEPLOY_REGION=ap-northeast-1
AWS_PROFILE=LOCAL_CREDENTIAL_PROFILE

今 Repository には.gitignoreに.env を追加しているので、ファイルを作成しておくと便利だと思います。

また、どの AWS 環境にに AWS Resource を Release するかを宣言することが推奨されているのでここでは CDK_ 系で指定します。

準備出来たら Load します。

source .env

CDK の実行 - $cdk deploy

個人的な経験だと、あんまり個別の Stack を指定するよりは --all Option にて全 Stack をリリースすることが多いです。 CloudFormation の Changeset が無い場合は各段階が早く終ることもあるし、Stack に渡る修正があったりすると個別で指定するのも面倒になってくるからです。

cdk deploy --all --outputs-file ./cdk-outputs.json

BUILD SUCCESSFUL in 412ms
6 actionable tasks: 6 up-to-date

> Task :run


BUILD SUCCESSFUL in 1s
4 actionable tasks: 1 executed, 3 up-to-date

✨  Synthesis time: 2.54s

SA201-cloudwatch
SA201-cloudwatch: deploying... [1/2]
SA201-cloudwatch: creating CloudFormation changeset...

 ✅  SA201-cloudwatch

✨  Deployment time: 29.44s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:00000000000:stack/SA201-cloudwatch/f7f41cf0-ce66-11ed-8638-0aa812a86f13

✨  Total time: 31.98s

SA201-infra
SA201-infra: deploying... [2/2]
SA201-infra: creating CloudFormation changeset...

 ✅  SA201-infra

✨  Deployment time: 18.48s

Outputs:
SA201-infra.vpcaz = ap-northeast-1a, ap-northeast-1c, ap-northeast-1d
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:00000000000:stack/SA201-infra/09e09560-ce67-11ed-bd02-0e6bbe30ba49

検証後 CDK にて片付ける - $cdk destroy

AWS Console にて CloudFormation 自体を削除しても良いですが、Stack を一つずつ Console で削除すると面倒なので Command 一つで簡単ですよね。

cdk destroy --all                                                                                                                                                                            JST Mar-30 4:20:16

BUILD SUCCESSFUL in 438ms
6 actionable tasks: 6 up-to-date

> Task :run


BUILD SUCCESSFUL in 1s
4 actionable tasks: 1 executed, 3 up-to-date
Are you sure you want to delete: SA201-infra, SA201-cloudwatch (y/n)? y

SA201-infra: destroying... [1/2]

 ✅  SA201-infra: destroyed
SA201-cloudwatch: destroying... [2/2]

 ✅  SA201-cloudwatch: destroyed

ちゃんと作られたか実際 CloudWatch の Log を作って検証

  • 前提条件
    • StepByStep しているのであれば、問題無いと思いますが実行にはまった場合は下記を確認下さい
    • cdk-outputs.json の生成
      cat ./cdk-outputs.json
      {
        "SA201-cloudwatch": {
          "logGroupName": "log-test-group",
          "logStream": "debugging-stream",
          "region": "ap-northeast-1"
        },
        "SA201-infra": {
          "vpcaz": "ap-northeast-1a, ap-northeast-1c, ap-northeast-1d"
        }
      }
      
    • AWS_PROFILE の指定
      echo "AWS_PROFILE: $AWS_PROFILE"
      ...
      

準備が整ったので Gradle にて Log を生成して AWS へ転送しましょう

./gradlew cleanTest test

BUILD SUCCESSFUL in 1s
5 actionable tasks: 5 up-to-date
[email protected] ➜  aws-cdk-kotlin-starter git:(main) ✗ ./gradlew cleanTest test                                                                                                                               JST Mar-31 4:11:56

> Task :test

CloudWatchLogTest > clientSetting() STARTED

CloudWatchLogTest > clientSetting() PASSED

CloudWatchLogTest > putLog() STARTED

CloudWatchLogTest > putLog() PASSED

CloudWatchLogTest > waitLog() STARTED

CloudWatchLogTest > waitLog() PASSED

CloudWatchLogTest > checkLog() STARTED

CloudWatchLogTest > checkLog() PASSED

BUILD SUCCESSFUL in 5s
6 actionable tasks: 2 executed, 4 up-to-date

AWS Console からみてみましょう

AWS Console - CloudWatch

AWS 環境によって異なりますが、ap-northeast-1 基準で下記の URL に AWS Console 確認できます。 https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups/log-group/log-test-group/log-events/debugging-stream

続いて Gradle Project の中身を見てみる

本記事で基本的な実行方法を身につけられたと思います。 次からは具体的にどこを修正して活用して行けば良いのかみてみましょう。