とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
読者登録と各種SNSのフォローもよろしくお願いいたします。

はじめてのCDK

AWS CDK使ってますか?私はつい最近はじめたばかりです。IaCといえばTerraformや、そのフォークであるOpenTofu、Ansibleなどがメジャーだと思うんですが、AWS CDKもなかなかよかったのでご紹介します。

AWS CDK

aws.amazon.com

AWS CDKはAWSをプロビジョニングするためのIaCツールです。従来のIaCツールだと、そのツール固有の言語でコードを記述するのが一般的ですが、CDKはTypeScript、JavaScript、Python、JavaC#/.Net、Goなどのプログラミング言語で記述できます。これの何がいいのかというと、例えばTerraformで条件分岐を書こうと思ったら以下のようになります。

resource "aws_vpc" "this" {
  count = create_vpc == true ? 1 : 0
  ...
}

あまり直感的ではないですよね。このようなコードを見慣れている人からすると「ああ、VPCを作るか、作らないか制御してるのね」と、すぐに理解できるかもしれないですが、入門したばかりの方がこれを即座に理解するのは難しいと思います。一方でCDKであれば一般的なプログラミング言語で記述できるため以下のように制御できます。

create_vpc = true;
if create_vpc {
  ...
fi

普段からプログラムを書いている人が見た時に何をしたいのかが即座に理解できます。このようにプログラマーフレンドリーなのがCDKです。

ドキュメント

AWS CDKのドキュメントはこちらのページから見ることができます。このページではデフォルトでNodejsのドキュメントとなっているため、他の言語を使用する場合は右上の赤枠内から選択してください。

お試し

EC2インスタンスを作ってみます。

まずはTerraform

gist.github.com

data.aws_ami.al2023で最新のAmazon Linux 2023を取得して、特定のサブネットにt3.microのインスタンスを起動するコードです。aws_amiの中で指定しているfilterはAWS CLIで指定できるfilterと一緒です。

aws ec2 describe-images --filters Name=architecture,Values=x86_64 Name=name,Values='al2023-ami-2023.*' Name=virtualization-type,Values=hvm --owners amazon

お次はCDK、手順はこちらを参考に進めます。言語はTypescriptを使用します。npmコマンドを実行できるようにしておいてください。

実行環境準備

cdkコマンドを実行できるようにします。環境がmacOSならHomebrewからaws-cdkをインストールしてしまうのが楽です。npm -g aws-cdkでもcdkコマンドをインストールできます。

ブートストラップ

CDKを使用して操作するAWSに必要なリソースを展開します。

$ cdk bootstrap aws://ACCOUNT-NUMBER/REGION

成功するとCloudFormationに「CDKToolkit」というスタックが作成されます。これでCDKを使用する準備が整いました。

init

コード置き場を作りましょう。

$ mkdir cdk-sample
$ cd cdk-sample

コード置き場のディレクトリ中で以下を実行しCDKの雛形を作ります。今回はTypescriptでコードを書いていくので--language typescriptとしました。

$ cdk init app --language typescript
Applying project template app for typescript
# Welcome to your CDK TypeScript project

This is a blank project for CDK development with TypeScript.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

* `npm run build`   compile typescript to js
* `npm run watch`   watch for changes and compile
* `npm run test`    perform the jest unit tests
* `npx cdk deploy`  deploy this stack to your default AWS account/region
* `npx cdk diff`    compare deployed stack with current state
* `npx cdk synth`   emits the synthesized CloudFormation template

Executing npm install...
✅ All done!

コーディング!

ディレクトリの中を見てみると色々なファイルが作られていますが、修正していくファイルはlib/cdk-stack.tsbin/cdk.tsだけです。(少し複雑なことをやろうと思うと他のファイルもいじります)

lib/cdk-stack.ts gist.github.com

bin/cdk.ts gist.github.com

デプロイ

デプロイは簡単です。

$ cdk deploy
[Warning at /CdkStack/subnet-1] No routeTableId was provided to the subnet 'subnet-12345678901234567'. Attempting to read its .routeTable.routeTableId will return null/undefined. (More info: https://github.com/aws/aws-cdk/pull/3171) [ack: @aws-cdk/aws-ec2:noSubnetRouteTableId]

✨  Synthesis time: 4.84s

CdkStack:  start: Building 

...

This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬─────────────────────────┬────────┬────────────────┬───────────────────────────┬───────────┐
│   │ Resource                │ Effect │ Action         │ Principal                 │ Condition │
├───┼─────────────────────────┼────────┼────────────────┼───────────────────────────┼───────────┤
│ + │ ${ec2/InstanceRole.Arn} │ Allow  │ sts:AssumeRole │ Service:ec2.amazonaws.com │           │
└───┴─────────────────────────┴────────┴────────────────┴───────────────────────────┴───────────┘
Security Group Changes
┌───┬──────────────────────────────────────┬─────┬────────────┬─────────────────┐
│   │ Group                                │ Dir │ Protocol   │ Peer            │
├───┼──────────────────────────────────────┼─────┼────────────┼─────────────────┤
│ + │ ${ec2/InstanceSecurityGroup.GroupId} │ Out │ Everything │ Everyone (IPv4) │
└───┴──────────────────────────────────────┴─────┴────────────┴─────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
CdkStack: deploying... [1/1]
CdkStack: creating CloudFormation changeset...

 ✅  CdkStack

✨  Deployment time: 178.61s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CdkStack/XXX-XXX-XXX

✨  Total time: 183.44s

微妙にWarnが出てしまいましが無事スタックが更新されインスタンスが作成されました。

まとめ

Terraformの方が簡単かもしれない・・・です。私の慣れの問題もあると思うので、普段からプログラムを書いている方にとってはCDKの方が馴染みやすいかもしれないですね。個人的にはTerraformでいいやっとなってしまいました。