AWS CDK(L2)で作成したサブネットのCIDRを指定する方法

2022.07.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、八木です。

AWS CDK L2は少ないコードでAWSリソースを作ることができ、非常に便利です。

一方で、現状ではVPCの作成の際、細かい設定を指定することができません。
例えば、サブネットのCIDRを指定などです。feature requestも上がっていますが、現在では対応されていません。

L1オブジェクトを使えば、サブネットのCIDRまで指定することができます。しかしコードの記述量が増えてしまうため、可能な限りL2オブジェクトを使いたいです。

ということで、今回はL2ライブラリでサブネットのCIDRを指定する方法をご紹介します。

サブネットのCIDRの指定方法

以下のようなテンプレートでは、サブネットのCIDRは自動で付与されます。

import { Stack, StackProps } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as ec2 from 'aws-cdk-lib/aws-ec2'

export class SpecifySubnetCiderStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    const vpc = new ec2.Vpc(this, 'VPC', {
      cidr: '10.1.0.0/16',
      maxAzs: 2,
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'public',
          subnetType: ec2.SubnetType.PUBLIC,
        },
        {
          cidrMask: 24,
          name: 'private',
          subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
        },
      ],
    })
  }
}

サブネットのCIDRは小さい値から付与されるため、以下のような構成になります。

では、この構成のサブネットのCIDRを変更するには、どうしたら良いでしょうか?
現状では、L2オブジェクトのオプションによる設定はできないため、エスケープハッチを使います。

import { Stack, StackProps } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as ec2 from 'aws-cdk-lib/aws-ec2'

export class SpecifySubnetCiderStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    const vpc = new ec2.Vpc(this, 'VPC', {
      cidr: '10.1.0.0/16',
      maxAzs: 2,
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'public',
          subnetType: ec2.SubnetType.PUBLIC,
        },
        {
          cidrMask: 24,
          name: 'private',
          subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
        },
      ],
    })

    const cfnPublicSubnet1 = vpc.publicSubnets[0].node.defaultChild as ec2.CfnSubnet
    cfnPublicSubnet1.addPropertyOverride('CidrBlock', `10.1.10.0/24`)
    const cfnPublicSubnet2 = vpc.publicSubnets[1].node.defaultChild as ec2.CfnSubnet
    cfnPublicSubnet2.addPropertyOverride('CidrBlock', `10.1.20.0/24`)
  }
}

このようにL1オブジェクト(CfnXXX)へアサーションし、addPropertyOverrideメソッドでCloudformationのプロパティを上書きします。
L2オブジェクトはL1オブジェクトのラッパーになっています。1このため、対応するL1オブジェクトへアサーションし、編集することで値を上書くことができます。

これでCIDRの指定ができました。

デプロイすると、以下のようにCIDRの指定ができていることがわかります。

注意点

今回はCDK L2で作成したリソースを、エスケープハッチを使うことにより、編集しました。
エスケープハッチは強力ですが、L2のオブジェクトメソッドで変更できる場合はそちらを使いましょう。

先に紹介したfeature requestのコメントでも注意されていますが、addPropertyOverrideメソッドで変更したプロパティは、元のオブジェクトには反映されません。

const cfnPublicSubnet1 = vpc.publicSubnets[0].node.defaultChild as ec2.CfnSubnet
cfnPublicSubnet1.addPropertyOverride('CidrBlock', `10.1.10.0/24`)
const cfnPublicSubnet2 = vpc.publicSubnets[1].node.defaultChild as ec2.CfnSubnet
cfnPublicSubnet2.addPropertyOverride('CidrBlock', `10.1.20.0/24`)
vpc.publicSubnets[0].ipv4CidrBlock // '10.1.0.0/24'が返る

以降のコードでvpc.publicSubnets[0].ipv4CidrBlockを参照する場合は、間違った値が返ります。ご注意ください。

それでは良いCDKライフを!