Help us understand the problem. What is going on with this article?

AWS Cloud Developement Kit : TypeScript Tutorial編

More than 1 year has passed since last update.

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

https://awslabs.github.io/aws-cdk/tutorial.html

環境

  • 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
f-daiki
主にAWSに関する実験結果を載せていきます。 内容は私個人に帰属し、所属する組織を代表するものではありません。
aws-professional-services
AWSプロフェッショナルサービスは、お客様がクラウドのイノベーティブな活用によりビジネス価値を生み出すことを支援し、加速させるための有償のコンサルティングチームです。Twitterで情報発信しています。https://twitter.com/awscloud_jp
https://aws.amazon.com/jp/careers/teams/professionalservices/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした