AWS CDK(TypeScript) 入門: 初期セットアップからVPC構築までの流れ

# はじめに

AWS CDKを使用して、L1レベル（CloudFormation互換レベル）でVPCを構築する方法を説明します。
L1レベルのコンストラクトを使用することで、CloudFormationリソースに直接対応する形でインフラストラクチャを定義できます。

# 手順

## 1. 環境のセットアップ

まず、AWS CDKをグローバルにインストールします。

```bash
npm install -g aws-cdk
```

## 2. プロジェクトの作成

新しいディレクトリを作成し、CDKプロジェクトを初期化します。

```bash
mkdir aws_cdk_typescript
cd aws_cdk_typescript
cdk init app --language typescript
```
下記フォルダ構成で作成されます
```sh
tree -L 1  
.
├── README.md
├── bin
├── cdk.json
├── cdk.out
├── jest.config.js
├── lib
├── node_modules
├── package-lock.json
├── package.json
├── test
└── tsconfig.json
```

## 3. CDK環境のブートストラップ

CDKを使用する前に、AWSアカウントとリージョンの組み合わせごとに一度だけブートストラップを実行する必要があります。

```bash
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

```bash
cdk bootstrap aws://ACCOUNT-NUMBER/ap-northeast-1
 ⏳  Bootstrapping environment aws://ACCOUNT-NUMBER/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
 ✅  Environment aws://ACCOUNT-NUMBER/ap-northeast-1 bootstrapped.
```

（ACCOUNT-NUMBERとREGIONは実際の値に置き換えてください）

CloudFormation Stackが作成されます
![スクリーンショット 2024-09-16 14.33.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/5e2b62ce-fc48-7efd-0753-eb053223cdbe.png)

## 4. VPCの定義

`lib/aws_cdk_typescript-stack.ts` ファイルを開き、以下のコードで置き換えます：

```typescript
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class AwsCdkTypescriptStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // VPCの作成
    const vpc = new cdk.aws_ec2.CfnVPC(this, 'MyVPC', {
      cidrBlock: '10.0.0.0/16',
      enableDnsHostnames: true,
      enableDnsSupport: true,
      instanceTenancy: 'default',
      tags: [{ key: 'Name', value: 'My VPC' }],
    });

    // インターネットゲートウェイの作成
    const igw = new cdk.aws_ec2.CfnInternetGateway(this, 'MyIGW', {
      tags: [{ key: 'Name', value: 'My IGW' }],
    });

    // VPCにインターネットゲートウェイをアタッチ
    new cdk.aws_ec2.CfnVPCGatewayAttachment(this, 'MyVPCGatewayAttachment', {
      vpcId: vpc.ref,
      internetGatewayId: igw.ref,
    });

    // パブリックサブネットの作成
    const publicSubnet = new cdk.aws_ec2.CfnSubnet(this, 'MyPublicSubnet', {
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1c',
      cidrBlock: '10.0.1.0/24',
      mapPublicIpOnLaunch: true,
      tags: [{ key: 'Name', value: 'My Public Subnet' }],
    });

    // パブリックルートテーブルの作成
    const publicRouteTable = new cdk.aws_ec2.CfnRouteTable(this, 'MyPublicRouteTable', {
      vpcId: vpc.ref,
      tags: [{ key: 'Name', value: 'My Public Route Table' }],
    });

    // パブリックルートの追加
    new cdk.aws_ec2.CfnRoute(this, 'MyPublicRoute', {
      routeTableId: publicRouteTable.ref,
      destinationCidrBlock: '0.0.0.0/0',
      gatewayId: igw.ref,
    });

    // サブネットとルートテーブルの関連付け
    new cdk.aws_ec2.CfnSubnetRouteTableAssociation(this, 'MyPublicSubnetRouteTableAssociation', {
      subnetId: publicSubnet.ref,
      routeTableId: publicRouteTable.ref,
    });

    // VPC IDの出力
    new cdk.CfnOutput(this, 'VpcId', {
      value: vpc.ref,
      description: 'VPC ID',
      exportName: 'MyVpcId',
    });
  }
}
```

## 5. デプロイ

以下のコマンドを順番に実行して、VPCをデプロイします。

```sh
# 構文確認
cdk synth

# 差分確認
cdk diff

# デプロイ
cdk deploy
```

`cdk deploy`実行時に変更の確認を求められたら、`y`を入力してデプロイを進めてください。

# コードの説明

このL1レベルのCDKコードでは、以下のリソースを作成しています：

1. VPC: `CfnVPC`を使用して、基本的なVPC設定を定義します
2. インターネットゲートウェイ: `CfnInternetGateway`を作成し、VPCにアタッチします
3. パブリックサブネット: `CfnSubnet`を使用して、VPC内にパブリックサブネットを作成します
4. ルートテーブル: `CfnRouteTable`、`CfnRoute`、`CfnSubnetRouteTableAssociation`を使用して、パブリックサブネットのルーティングを設定します

最後に、作成されたVPCのIDを出力として定義しています。

# まとめ

AWS CDKを使用してL1レベルでVPCを構築する方法を紹介しました。L1レベルのコンストラクトを使用することで、CloudFormationリソースに直接対応する形でインフラストラクチャを定義でき、より詳細な制御が可能になります。

ただし、L1レベルのコードはより冗長になる傾向があるため、より抽象度の高いL2やL3レベルのコンストラクトの使用も検討するとよいでしょう。プロジェクトの要件に応じて、適切な抽象化レベルを選択することが重要です。