1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS Cloud Developement Kit : TypeScript Tutorial編

Last updated at Posted at 2019-01-19

AWS Cloud Development Kit (以下CDK)はプログラミング言語を使用してAWS環境の定義、デプロイができるフレームワークです。CDKのコードは最終的にCloudFormationのテンプレートに変換されてデプロイされるため、宣言型のCloudFormationの持つ冪等性(繰り返し実行しても同じ結果になる)の恩恵を受けつつ、様々なデータ構造や繰り返しなどの制御構造を持つプログラミング言語でインフラストラクチャを記述できるというメリットがあります。2019/1/19時点ではPreviewで、C#/JavaScript/TypeScript/Javaで記述することができます。
前回はCDKのインストールを実施したので今回はTypeScriptを使って公式のTutorialを実施します。

環境

  • OS: macOS Sierra (10.12.6)
  • AWS CDK: 0.21.0
    Node.jsが動く環境であればどの環境でも動作するはずです。

前提条件

以下は予めインストールしておく必要があります。

  • Node.js (>= 8.11.x)
  • AWS CLI
  • git
  • AWS CDK

CDKプロジェクトの初期化

CDKプロジェクトをデフォルトテンプレートから初期化します。

プロジェクトフォルダの作成

コマンド
$ mkdir hello-cdk
$ cd hello-cdk

Tutrialではここでgit initしていますが 、次のcdk initが空のディレクトリでないと実行できませんでした。またcdk initを実行すると自動的に.gitフォルダや.gitignoreファイルが作成されます。

プロジェクトの初期化

コマンド
$ cdk init --language typescript

以下のようなディレクトリ構成となります。

total 208
drwxr-xr-x   13 xxxxx  1896053708    442  1  4 22:10 .
drwxr-xr-x    4 xxxxx  1896053708    136  1  4 22:10 ..
drwxr-xr-x   12 xxxxx  1896053708    408  1  4 22:10 .git
-rw-r--r--    1 xxxxx  1896053708     25  1  4 22:10 .gitignore
-rw-r--r--    1 xxxxx  1896053708     13  1  4 22:10 .npmignore
-rw-r--r--    1 xxxxx  1896053708    320 12 20 22:02 README.md
drwxr-xr-x    3 xxxxx  1896053708    102  1  4 22:10 bin
-rw-r--r--    1 xxxxx  1896053708     37  1  4 22:10 cdk.json
drwxr-xr-x    3 xxxxx  1896053708    102  1  4 22:10 lib
drwxr-xr-x  239 xxxxx  1896053708   8126  1  4 22:10 node_modules
-rw-r--r--    1 xxxxx  1896053708  78741  1  4 22:10 package-lock.json
-rw-r--r--    1 xxxxx  1896053708    345  1  4 22:10 package.json
-rw-r--r--    1 xxxxx  1896053708    558 12 20 22:02 tsconfig.json

サンプルアプリケーションのビルド

デフォルトテンプレートに含まれるサンプルアプリケーションをビルドします。

サンプルコードの確認

cdk initを実行した時点で、サンプルコードが出力されています。以下の前者がCDKアプリケーション、後者はCDKアプリケーションでimportしているHelloCdkStackスタックです。ファイルが分かれているのは単純に再利用性を考慮してのことと思われます。

コマンド
$ cat bin/hello-cdk.ts
bin/hello-cdk.ts
#!/usr/bin/env node
import cdk = require('@aws-cdk/cdk');
import { HelloCdkStack } from '../lib/hello-cdk-stack';

const app = new cdk.App();
new HelloCdkStack(app, 'HelloCdkStack');
app.run();
コマンド
$ cat lib/hello-cdk-stack.ts
lib/hello-cdk-stack.ts
import cdk = require('@aws-cdk/cdk');

export class HelloCdkStack extends cdk.Stack {
  constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
    super(parent, name, props);

    // The code that defines your stack goes here
  }
}

tsファイルのビルド

コマンド
$ npm run build

cdk lsコマンドでStackをリストするとHelloCdkStackが表示されますが、この時点ではAWS環境には何も展開されていません。

コマンド
$ cdk ls -l
Output例
- name: HelloCdkStack
  environment:
    name: xxxxxxxxxxxx/ap-northeast-1
    account: "xxxxxxxxxxxx"
    region: ap-northeast-1

AWSリソースの追加とデプロイ

サンプルスタックにはAWSリソースが定義されていないため、S3バケットを1つ追加します。その後実際にAWS環境にデプロイします。

@aws-cdk/aws-s3パッケージのインストール

コマンド
$ npm install @aws-cdk/aws-s3

S3バケットの追加

lib/hello-cdk-stack.tsを編集し、S3バケットをスタックに追加します。

lib/hello-cdk-stack.ts
import cdk = require('@aws-cdk/cdk');
import s3 = require('@aws-cdk/aws-s3');    //s3パッケージをimport

export class HelloCdkStack extends cdk.Stack {
    constructor(parent: cdk.App, id: string, props?: cdk.StackProps) {
        super(parent, id, props);

        new s3.Bucket(this, 'MyFirstBucket', {    //s3バケットを追加
            versioned: true
        });
    }
}

ビルド

コマンド
$ npm run build

リソースの確認

CDKによって作成されるCloudFormationスタックのテンプレート(Resources)を確認します。

コマンド
$ cdk synth HelloCdkStack
Output例
Resources:
  MyFirstBucketB8884501:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration:
        Status: Enabled
    DeletionPolicy: Retain
    Metadata:
      aws:cdk:path: HelloCdkStack/MyFirstBucket/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Modules: aws-cdk=0.21.0,@aws-cdk/aws-codepipeline-api=0.21.0,@aws-cdk/aws-events=0.21.0,@aws-cdk/aws-iam=0.21.0,@aws-cdk/aws-kms=0.21.0,@aws-cdk/aws-s3=0.21.0,@aws-cdk/aws-s3-notifications=0.21.0,@aws-cdk/cdk=0.21.0,@aws-cdk/cx-api=0.21.0,jsii-runtime=node.js/v10.2.1

S3バケットが定義されています。Logical Nameはs3.Bucketオブジェクト作成時の引数MyFirstBucketの後にランダム文字列が追加されたものとなっています。DeletionPolicy: RetainのためStackを削除してもバケットが残るようになっています。

cdk diffコマンドを実行すると現状のリソースとの差分が表示されます。

コマンド
$ cdk diff
Output例
Resources
[+] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501

スタックのデプロイ

コマンド
$ cdk deploy
Output例
HelloCdkStack: deploying...
HelloCdkStack: creating CloudFormation changeset...
 0/3 | 11:19:16 | REVIEW_IN_PROGRESS   | AWS::CloudFormation::Stack | HelloCdkStack User Initiated
 0/3 | 11:19:21 | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | HelloCdkStack User Initiated
 0/3 | 11:19:26 | CREATE_IN_PROGRESS   | AWS::S3::Bucket    | MyFirstBucket (MyFirstBucketB8884501)
 0/3 | 11:19:26 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata
 0/3 | 11:19:28 | CREATE_IN_PROGRESS   | AWS::S3::Bucket    | MyFirstBucket (MyFirstBucketB8884501) Resource creation Initiated
 0/3 | 11:19:29 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
 1/3 | 11:19:29 | CREATE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata
 2/3 | 11:19:48 | CREATE_COMPLETE      | AWS::S3::Bucket    | MyFirstBucket (MyFirstBucketB8884501)
 3/3 | 11:19:50 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | HelloCdkStack

 ✅  HelloCdkStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/HelloCdkStack/4cf8a750-10
90-11e9-a609-0671757157c6

スタックの確認

作成されたスタックを確認します。

コマンド
$ aws cloudformation describe-stacks \
    --stack-name HelloCdkStack
Output例
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/HelloCdkStack/4cf8a750-1090-11e9-a609-0671757157c6",
            "StackName": "HelloCdkStack",
            "ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:changeSet/CDK-0f39e1e5-0f1b-43fc-9a04-c1570dcd75ff/03917ebe-6886-4123-aa06-e7ef0139be3f",
            "CreationTime": "2019-01-05T02:19:16.463Z",
            "LastUpdatedTime": "2019-01-05T02:19:21.942Z",
            "RollbackConfiguration": {},
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Capabilities": [
                "CAPABILITY_IAM",
                "CAPABILITY_NAMED_IAM"
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

作成されたS3バケットのPhysical ID(バケット名)を確認します。

コマンド
$ aws cloudformation describe-stack-resources \
    --stack-name HelloCdkStack \
    --query StackResources[?ResourceType==\`AWS::S3::Bucket\`]
Output例
[
    {
        "StackName": "HelloCdkStack",
        "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/HelloCdkStack/4cf8a750-1090-11e9-a609-0671757157c6",
        "LogicalResourceId": "MyFirstBucketB8884501",
        "PhysicalResourceId": "hellocdkstack-myfirstbucketb8884501-sakucck9x6ae",
        "ResourceType": "AWS::S3::Bucket",
        "Timestamp": "2019-01-05T02:19:48.651Z",
        "ResourceStatus": "CREATE_COMPLETE",
        "DriftInformation": {
            "StackResourceDriftStatus": "NOT_CHECKED"
        }
    }
]

hellocdkstack-myfirstbucketb8884501-sakucck9x6aeとなっています。[stack名]-[Logical ID]-[ランダム文字列]のようです。

コード内で指定したS3バケットのバージョニング設定を確認します。

コマンド
aws s3api get-bucket-versioning \
    --bucket "hellocdkstack-myfirstbucketb8884501-sakucck9x6ae"
Output例
{
    "Status": "Enabled"
}

AWSリソースの変更

次はS3バケットの設定を変更し、差分をデプロイします。

コードの編集

lib/hello-cdk-stack.tsを編集し、KMS暗号化を有効にします。

lib/hello-cdk-stack.ts
    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true,                             //カンマを追加
      encryption: s3.BucketEncryption.KmsManaged   //追加
    });

ビルド

コマンド
$ npm run build

差分の確認

コマンド
$ cdk diff
Output例
Resources
[~] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
 └─ [+] BucketEncryption
     └─ {"ServerSideEncryptionConfiguration":[{"ServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms"}}]}

スタックのデプロイ

コマンド
$ cdk deploy
Output例
HelloCdkStack: deploying...
HelloCdkStack: creating CloudFormation changeset...
 0/2 | 11:48:31 | UPDATE_IN_PROGRESS   | AWS::CloudFormation::Stack | HelloCdkStack User Initiated
 0/2 | 11:48:37 | UPDATE_IN_PROGRESS   | AWS::S3::Bucket    | MyFirstBucket (MyFirstBucketB8884501)
 1/2 | 11:48:58 | UPDATE_COMPLETE      | AWS::S3::Bucket    | MyFirstBucket (MyFirstBucketB8884501)
 1/2 | 11:49:00 | UPDATE_COMPLETE_CLEA | AWS::CloudFormation::Stack | HelloCdkStack
 2/2 | 11:49:01 | UPDATE_COMPLETE      | AWS::CloudFormation::Stack | HelloCdkStack

 ✅  HelloCdkStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/HelloCdkStack/4cf8a750-1090-11e9-a609-0671757157c6

設定の確認

S3バケットの暗号化設定を確認します。

コマンド
$ aws s3api get-bucket-encryption \
    --bucket "hellocdkstack-myfirstbucketb8884501-sakucck9x6ae"
Output例
{
    "ServerSideEncryptionConfiguration": {
        "Rules": [
            {
                "ApplyServerSideEncryptionByDefault": {
                    "SSEAlgorithm": "aws:kms"
                }
            }
        ]
    }
}

スタックの削除

展開されたスタックをAWS環境から削除します。
プロジェクトフォルダでcdk destroyコマンドを実行します。

コマンド
$ cdk destroy
Output例
Are you sure you want to delete: HelloCdkStack (y/n)? y
HelloCdkStack: destroying...
   0 | 12:02:25 | DELETE_IN_PROGRESS   | AWS::CloudFormation::Stack | HelloCdkStack User Initiated
   0 | 12:02:27 | DELETE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata
   0 | 12:02:27 | DELETE_SKIPPED       | AWS::S3::Bucket    | MyFirstBucket (MyFirstBucketB8884501)
   1 | 12:02:30 | DELETE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata

 ✅  HelloCdkStack: destroyed

削除されたか確認します。

コマンド
$ aws cloudformation describe-stacks \
      --stack-name "HelloCdkStack" 
Output例
An error occurred (ValidationError) when calling the DescribeStacks operation: Stack with id HelloCdkStack does not exist

#おまけ
各CDKコマンドでCallされたAWS APIです。今回はCloudTrailから取得しておりソースコードを全て読んだわけではないので漏れはあるかも。予想通りCloudFormationのAPIをCallしていました。cdk diffはソースコードも少し見てみましたがchange setを作っているわけではなく、GetTemplateで既存のテンプレートを取得してローカルとの差分を見ているようです。

CDKコマンド サービス アクション
cdk init --language typescript なし なし
cdk ls -l なし なし
cdk diff CloudFormation GetTemplate
cdk deploy CloudFormation DescribeStackEvents
DescribeStacks
ExecuteChangeSet
DescribeChaneSet
CreateChangeSet
GetTemplate
cdk destroy CloudFormation DescribeStackEvents
DescribeStacks
DeleteStack
1
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?