AWS Cloud Developement Kit : TypeScript Tutorial編
AWS Cloud Developement Kit : TypeScript Tutorial編:
AWS Cloud Development Kit (以下CDK)はプログラミング言語を使用してAWS環境の定義、デプロイができるフレームワークです。CDKのコードは最終的にCloudFormationのテンプレートに変換されてデプロイされるため、宣言型のCloudFormationの持つ冪等性(繰り返し実行しても同じ結果になる)の恩恵を受けつつ、様々なデータ構造や繰り返しなどの制御構造を持つプログラミング言語でインフラストラクチャを記述できるというメリットがあります。2019/1/4時点ではPreviewで、C#/JavaScript/TypeScript/Javaで記述することができます。
前回はCDKのインストールを実施したので今回はTypeScriptを使って公式のTutorialを実施します。
https://awslabs.github.io/aws-cdk/tutorial.html
以下は予めインストールしておく必要があります。
CDKプロジェクトをデフォルトテンプレートから初期化します。
Tutrialではここで
以下のようなディレクトリ構成となります。
デフォルトテンプレートに含まれるサンプルアプリケーションをビルドします。
サンプルスタックにはAWSリソースが定義されていないため、S3バケットを1つ追加します。その後実際にAWS環境にデプロイします。
S3バケットが定義されています。Logical Nameは
次はS3バケットの設定を変更し、差分をデプロイします。
展開されたスタックをAWS環境から削除します。
各CDKコマンドでCallされたAWS APIです。今回はCloudTrailから取得しておりソースコードを全て読んだわけではないので漏れはあるかも。予想通りCloudFormationのAPIをCallしていました。cdk diffはソースコードも少し見てみましたがchange setを作っているわけではなく、GetTemplateで既存のテンプレートを取得してローカルとの差分を見ているようです。
AWS Cloud Development Kit (以下CDK)はプログラミング言語を使用してAWS環境の定義、デプロイができるフレームワークです。CDKのコードは最終的にCloudFormationのテンプレートに変換されてデプロイされるため、宣言型のCloudFormationの持つ冪等性(繰り返し実行しても同じ結果になる)の恩恵を受けつつ、様々なデータ構造や繰り返しなどの制御構造を持つプログラミング言語でインフラストラクチャを記述できるというメリットがあります。2019/1/4時点では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
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
#!/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
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
- 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
-
lib/hello-cdk-stack.ts
を編集し、S3バケットをスタックに追加します。
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
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.Bucket
オブジェクト作成時の引数MyFirstBucket
の後にランダム文字列が追加されたものとなっています。DeletionPolicy: Retain
のためStackを削除してもバケットが残るようになっています。-
cdk diff
コマンドを実行すると現状のリソースとの差分が表示されます。
$ cdk diff
Resources [+] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
- スタックをデプロイします。
$ cdk deploy
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
{ "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\`]
[ { "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"
{ "Status": "Enabled" }
AWSリソースの変更
次はS3バケットの設定を変更し、差分をデプロイします。-
lib/hello-cdk-stack.ts
を編集し、KMS暗号化を有効にします。
new s3.Bucket(this, 'MyFirstBucket', { versioned: true, //カンマを追加 encryption: s3.BucketEncryption.KmsManaged //追加 });
- ビルドします。
$ npm run build
- 差分を確認します。
$ cdk diff
Resources [~] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501 └─ [+] BucketEncryption └─ {"ServerSideEncryptionConfiguration":[{"ServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms"}}]}
- スタックをデプロイします。
$ cdk deploy
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"
{ "ServerSideEncryptionConfiguration": { "Rules": [ { "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms" } } ] } }
スタックの削除
展開されたスタックをAWS環境から削除します。- プロジェクトフォルダで
cdk destroy
コマンドを実行します。
$ cdk destroy
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" 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 |
コメント
コメントを投稿