AWS最大のイベントre:Invent2018に参加しています。
2018年8月に公開されたCloud Development Kit (CDK)について、下記のセッションでも紹介されていたので触ってみました。
DEV327 - Beyond the Basics: Advanced Infrastructure as Code Programming on AWS
AWS CDKとは
AWS CDKはAWS上でInfrastructure as Codeを実現するためのフレームワークでOSS化されています。CloudFormationのようにDeclarativeにではなく、Imperativeにリソースを定義できるのが特徴です。最終的なリソースのプロビジョニングにはCloudFormationテンプレートが使われるため、CloudFormationの機能をラップするようなフレームワークです。
DeclarativeとImperativeの比較はセッションの中でも紹介されていました。
プログラミング言語を使ってリソースを定義できるのが特徴で、執筆時点でサポートしている言語は下記の通りです。
- Java
- Javascript, TypeScript
- .NET
使ってみる
さっそくCDKを使ってリソースのプロビジョニングを行ってみたいと思います。
今回は公式チュートリアルを参考にJavascriptを使ってリソースを定義していきます。
利用開始の準備
まずはCDKのコマンドラインツールキットをインストールします。インストールにはNode.jsとnpmの環境が必要です。
下記のコマンドでCDKをインストールします。
$ npm install -g aws-cdk
$ cdk --version
0.18.1 (build 9f7af21)
執筆時点のCDKのバージョンは0.18.1でした。
続いてCDKを使うためのプロジェクトを作成します。
下記のコマンドを実行して、プロジェクトを初期化します。
$ mkdir reinvent2018-cdk
$ cd reinvent2018-cdk
$ npm init -y
最後にCDKのスタックやアプリを作成するのに必要なCore Library(@aws-cdk/cdk)をインストールします。
$ npm install @aws-cdk/cdk
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN reinvent2018-cdk@1.0.0 No description
npm WARN reinvent2018-cdk@1.0.0 No repository field.
+ @aws-cdk/cdk@0.18.1
added 10 packages from 7 contributors and audited 10 packages in 2.102s
found 0 vulnerabilities
以上で利用開始の準備は完了です。
リソースのプロビジョニング
AWS CDKではリソースをApplication、Stack(s)、Construct(s)の3層で定義します。
さっそくリソースを定義していきます。
Applicationの作成
まずはApplicationを作成していきます。プロジェクトフォルダに bin/reinvent2018-cdk.js ファイルを作成して、下記のようにApplicationの定義をします。
const cdk = require('@aws-cdk/cdk');
class MyApp extends cdk.App {
constructor() {
super();
}
}
new MyApp().run();
AWS CDKで作成するApplicationはcdk.Appクラスを継承して作成するようです。
CDKアプリケーションの実行にはJavascript以外の言語を利用する場合はコンパイルが必要です。今回はJavascriptなのでコンパイル不要です。
続いてCDKのコマンドラインツールが作成したCDK Applicationを実行できるように、プロジェクトフォルダのルートに cdk.json を作成し、下記のように記載します。
{
"app": "node bin/reinvent2018-cdk.js"
}
作成したら、下記のコマンドでApplication内のStackの一覧を取得します。
(ここではAWSのCredentialsの設定が完了しているものとします。)
まだStackを作成していないので、空の配列が返ってきます。
$ cdk ls -l
[]
Stackの作成
続いてApplicationの中にStackを作成します。
先ほど作成した bin/reinvent2018-cdk.js を下記のように更新してStackを定義します。
const cdk = require('@aws-cdk/cdk');
class MyStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
}
}
class MyApp extends cdk.App {
constructor(argv) {
super(argv);
new MyStack(this, 'reinvent2018-cdk');
}
}
new MyApp().run();
Stackは cdk.Stack を継承して作成します。parent、id、props といったパラメータはドキュメントを参照してください。
下記のコマンドを実行してスタックが定義されているか確認します。
$ cdk ls -l
- name: reinvent2018-cdk
environment:
name: <account-id>/ap-northeast-1
account: "<account-id>"
region: ap-northeast-1
うまく行っていれば、定義したスタックが表示されます。
Constructの作成
最後にConstructの作成をします。ここではS3バケットを定義して作成します。
上記で作成した bin/reinvent2018-cdk.js のStack内にS3バケットを定義します。
S3のパッケージをインストールします。
$ npm install @aws-cdk/aws-s3
npm WARN reinvent2018-cdk@1.0.0 No description
npm WARN reinvent2018-cdk@1.0.0 No repository field.
+ @aws-cdk/aws-s3@0.18.1
added 6 packages from 1 contributor and audited 109 packages in 8.412s
found 0 vulnerabilities
bin/reinvent2018-cdk.js を下記のように更新します。
const cdk = require('@aws-cdk/cdk');
const s3 = require('@aws-cdk/aws-s3');
class MyStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
new s3.Bucket(this, 'MyReInventBucket', {
versioned: true,
bucketName: 'reinvent2018-cdk'
});
}
}
class MyApp extends cdk.App {
constructor(argv) {
super(argv);
new MyStack(this, 'reinvent2018-cdk');
}
}
new MyApp().run();
Stackの定義の中にS3バケットのContructを加えました。
リソースのデプロイ
CDKで定義したリソースを下記のコマンドでデプロイします。
$ cdk deploy
reinvent2018-cdk: deploying...
reinvent2018-cdk: creating CloudFormation changeset...
0/3 | 15:48:07 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata
0/3 | 15:48:08 | CREATE_IN_PROGRESS | AWS::S3::Bucket | MyReInventBucket (MyReInventBucket83E9F87D)
0/3 | 15:48:10 | CREATE_IN_PROGRESS | AWS::S3::Bucket | MyReInventBucket (MyReInventBucket83E9F87D) Resource creation Initiated
0/3 | 15:48:10 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
1/3 | 15:48:11 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata
2/3 | 15:48:30 | CREATE_COMPLETE | AWS::S3::Bucket | MyReInventBucket (MyReInventBucket83E9F87D)
✅ reinvent2018-cdk
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:<account-id>:stack/reinvent2018-cdk/xxxxxxxxxxxxxxx
delpoyコマンドはCDKの定義からCloudFormationテンプレートを合成し、CloudFormation経由でリソースの作成を行います。
実際にAWSコンソールを確認するとCloudFormationのスタックとS3バケットが作成できているのが確認できます。
またS3バケットのバージョニングの設定をtrueにしたので、バージョニングも有効化されています。
リソースの更新
一度デプロイしたリソースを更新してみます。
デプロイした bin/reinvent2018-cdk.js の一部を更新し、versioningの機能を無効化します。
const cdk = require('@aws-cdk/cdk');
const s3 = require('@aws-cdk/aws-s3');
class MyStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
new s3.Bucket(this, 'MyReInventBucket', {
versioned: false,
bucketName: 'reinvent2018-cdk'
});
}
}
class MyApp extends cdk.App {
constructor(argv) {
super(argv);
new MyStack(this, 'reinvent2018-cdk');
}
}
new MyApp().run();
更新したら、diff コマンドを使うことでデプロイ済みのリソースとの差分を確認することができます。
$ cdk diff
Resources
[~] AWS::S3::Bucket MyReInventBucket MyReInventBucket83E9F87D
└─ [-] VersioningConfiguration
└─ {"Status":"Enabled"}
再度 deploy コマンドを実行してスタックを更新します。
$ cdk deploy
reinvent2018-cdk: deploying...
reinvent2018-cdk: creating CloudFormation changeset...
0/2 | 15:58:24 | UPDATE_IN_PROGRESS | AWS::S3::Bucket | MyReInventBucket (MyReInventBucket83E9F87D)
1/2 | 15:58:45 | UPDATE_COMPLETE | AWS::S3::Bucket | MyReInventBucket (MyReInventBucket83E9F87D)
1/2 | 15:58:47 | UPDATE_COMPLETE_CLEA | AWS::CloudFormation::Stack | reinvent2018-cdk
2/2 | 15:58:48 | UPDATE_COMPLETE | AWS::CloudFormation::Stack | reinvent2018-cdk
✅ reinvent2018-cdk
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:<account-id>:stack/reinvent2018-cdk/xxxxxxxxxxxxxxx
実際にコンソールからもCloudFormationのスタックとS3のバージョニングの設定が更新されているのが確認できました。
まとめ
馴染みのプログラミング言語を使ってImperativeにInfrastructure as Codeを実現できるAWS CDKを触ってみました。今回は基本の部分しか触れていませんが、プログラミング言語で記載できることからより柔軟なリソース定義ができるようになると思います。執筆時点ではDeveloper Previewですが、これから機能や対応言語が充実してくることが期待できるので楽しみですね。