はじめに
cdk migrateとは
2023年10月7日にAWS CDK v2.100.0がリリースされました。その中より、cdk migrateについて書かせていただきます。
機能を簡単に
現時点でデプロイされているCloudFormation(以下、CFn)、ローカルのCFnファイルからCDKのソースを作成することが出来る機能です。
やってみる
下準備
まずはCFnをAWS上にデプロイします。構成はVPCの中に1つだけサブネットがあるシンプルなものです。
リソースのタグとCIDRをパラメータとして渡すテンプレートになっています。
テンプレート
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
PJid:
Type: String
Default: "test"
VPCCIDR:
Type: String
Default: "10.0.0.0/16"
PublicSubnetCIDR:
Type: String
Default: "10.0.10.0/24"
Resources:
# VPC
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
InstanceTenancy: default
Tags:
- Key: Name
Value: !Sub "${PJid}-vpc"
# InternetGateway
InternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Sub "${PJid}-igw"
# IGW Attach
InternetGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# Public Subnet
PublicSubnet:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !Ref PublicSubnetCIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJid}-public-subnet-a"
# Public RouteTable
PublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJid}-public-route-a"
# PublicRoute
PublicRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
# PublicRouteTable Associate Subnet
PublicSubnetRouteTablessociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
コマンド実行
デプロイが完了したら早速コマンドを実行してみます。
# 念のためバージョンを確認
% cdk --version
2.100.0 (build e1b5c77)
# 実行していくコマンド
cdk migrate --stack-name {ターゲットのスタック名} --language {CDKの言語} --from-stack
コマンド実行後に以下のような表示があれば成功です。
# 実際の実行結果
% cdk migrate --stack-name cdk-migrate-test --language typescript --from-stack
This is an experimental feature. We make no guarantees about the outcome or stability of the functionality.
⏳ Generating CDK app for cdk-migrate-test...
Applying project template app for typescript
Initializing a new git repository...
Executing npm install...
✅ All done!
成功すると、コマンドを実行したディレクトリ配下にCDKのリソースが --stack-name で指定したスタック名で作成されます。
# 今回の実行結果
% tree ./cdk-migrate-test
.
├── README.md
├── bin
│ └── cdk-migrate-test.ts
├── cdk.json
├── jest.config.js
├── lib
│ └── cdk-migrate-test-stack.ts
├── node_modules
│ ├── @ampproject
│ │ └── remapping
│ │ ├── LICENSE
│ │ ├── README.md
~~ 以下略 ~~
CDKのソースを確認してみる
cdk-migrate-test-stack.tsの中身を見てみると以下のようにコードが生成されていました。
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export interface CdkMigrateTestStackProps extends cdk.StackProps {
/**
* @default 'test'
*/
readonly pJid?: string;
/**
* @default '10.0.0.0/16'
*/
readonly vpccidr?: string;
/**
* @default '10.0.10.0/24'
*/
readonly publicSubnetCidr?: string;
}
export class CdkMigrateTestStack extends cdk.Stack {
public constructor(scope: cdk.App, id: string, props: CdkMigrateTestStackProps = {}) {
super(scope, id, props);
// Applying default props
props = {
...props,
pJid: props.pJid ?? 'test',
vpccidr: props.vpccidr ?? '10.0.0.0/16',
publicSubnetCidr: props.publicSubnetCidr ?? '10.0.10.0/24',
};
// Resources
const internetGateway = new ec2.CfnInternetGateway(this, 'InternetGateway', {
tags: [
{
key: 'Name',
value: `${props.pJid!}-igw`,
},
],
});
const vpc = new ec2.CfnVPC(this, 'VPC', {
cidrBlock: props.vpccidr!,
enableDnsSupport: true,
enableDnsHostnames: true,
instanceTenancy: 'default',
tags: [
{
key: 'Name',
value: `${props.pJid!}-vpc`,
},
],
});
if (internetGateway == null) { throw new Error(`A combination of conditions caused 'internetGateway' to be undefined. Fixit.`); }
if (vpc == null) { throw new Error(`A combination of conditions caused 'vpc' to be undefined. Fixit.`); }
const internetGatewayAttachment = new ec2.CfnVPCGatewayAttachment(this, 'InternetGatewayAttachment', {
internetGatewayId: internetGateway.ref,
vpcId: vpc.ref,
});
if (vpc == null) { throw new Error(`A combination of conditions caused 'vpc' to be undefined. Fixit.`); }
const publicRouteTable = new ec2.CfnRouteTable(this, 'PublicRouteTable', {
vpcId: vpc.ref,
tags: [
{
key: 'Name',
value: `${props.pJid!}-public-route-a`,
},
],
});
if (vpc == null) { throw new Error(`A combination of conditions caused 'vpc' to be undefined. Fixit.`); }
const publicSubnet = new ec2.CfnSubnet(this, 'PublicSubnet', {
availabilityZone: 'ap-northeast-1a',
cidrBlock: props.publicSubnetCidr!,
vpcId: vpc.ref,
tags: [
{
key: 'Name',
value: `${props.pJid!}-public-subnet-a`,
},
],
});
if (internetGateway == null) { throw new Error(`A combination of conditions caused 'internetGateway' to be undefined. Fixit.`); }
if (publicRouteTable == null) { throw new Error(`A combination of conditions caused 'publicRouteTable' to be undefined. Fixit.`); }
const publicRoute = new ec2.CfnRoute(this, 'PublicRoute', {
routeTableId: publicRouteTable.ref,
destinationCidrBlock: '0.0.0.0/0',
gatewayId: internetGateway.ref,
});
if (publicRouteTable == null) { throw new Error(`A combination of conditions caused 'publicRouteTable' to be undefined. Fixit.`); }
if (publicSubnet == null) { throw new Error(`A combination of conditions caused 'publicSubnet' to be undefined. Fixit.`); }
const publicSubnetRouteTablessociation = new ec2.CfnSubnetRouteTableAssociation(this, 'PublicSubnetRouteTablessociation', {
subnetId: publicSubnet.ref,
routeTableId: publicRouteTable.ref,
});
}
}
ちゃんと変数部分まで再現されていることが確認できました!!
このCDKを更新してデプロイすると元々CFnで構築していたリソースが更新されますので試してみてください!
まとめ
CFnで管理していたインフラがコマンド1つでCDKに出来たら最高ですよね。