AWS Cloud Development Kit (AWS CDK) L3/L2 コンストラクトと AWS CloudFormation の間にギャップがある場合に、リソースプロパティの値を変更したいです。
簡単な説明
場合によっては、上位レベルのコンストラクト (L3 と L2) には変更できないリソースプロパティがあります。この問題を回避するには、AWS CDK エスケープハッチを使用してより低い抽象レベルに移動し、リソースプロパティ値を変更します。
AWS CDK Python を使用する Amazon 仮想プライベートクラウド (Amazon VPC) の例:
vpc = ec2.Vpc(self, "MyCDKVPC",
max_azs=2,
cidr='60.0.0.0/16',
subnet_configuration=[
ec2.SubnetConfiguration(
name="public",
subnet_type=ec2.SubnetType.PUBLIC,
cidr_mask=24,
),
ec2.SubnetConfiguration(
name="private",
subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT,
cidr_mask=24,
)
]
)
前述の例では、Amazon VPC は L2 コンストラクト [aws_cdk.aws_ec2.Vpc] を使用して定義されています。このコンストラクトには、[CIDRBlock] が [60.0.0.0/16] に設定された 2 つのアベイラビリティーゾーン (AZ) があります。この例の Amazon VPC には、2 つの AZ にまたがる 2 つの [PublicSubnets] と 2 つの [PrivateSubnets] も含まれています。
CloudFormation を生成して AWS::EC2::Subnet リソースをチェックする場合、[CIDRBlock] は最初の IP 範囲 [60.0.0.0/24] から開始され、変更することはできません。
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: 60.0.0.0/24
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: 60.0.1.0/24
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: 60.0.2.0/24
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: 60.0.3.0/24
この問題を解決するには、次の手順を実行してください。
- Amazon VPC 内で生成されたサブネット (L2 [PublicSubnet] コンストラクトと L2 [PrivateSubnet] コンストラクト) を取得します。
- L2 コンストラクトに AWS CDK エスケープハッチ [node.default_child] を使用し、それを L1 [CFNSubnet] リソースとしてキャストします。
- [cidr_block] を直接変更するか、未処理のオーバーライドを使用して変更します。
- CloudFormation テンプレートで [cidr_block] の更新を確認します。
解決策
AWS CDK エスケープハッチを使用して [Public Subnets] または [PrivateSubnets] の下位抽象化レイヤーの [CidrBlock] 値を変更するには、次の手順を実行します。
重要: 以下の手順は [PublicSubnets] に適用されます。[PrivateSubnets] に適用するには、[PublicSubnet] のすべてのインスタンスを [PrivateSubnet]に置き換えます。
1. vpc.public_subnets 属性を使用して、Amazon VPC 内の [PublicSubnets] のリストを取得します。
public_subnets = vpc.public_subnets
**メモ:**生成されたリスト内の各要素は L2 [PublicSubnet] コンストラクトです。次のプリントアウトの例を参照してください。
########## confirm public_subnets is a L2 construct ##########
print(public_subnets)
# printout: [<aws_cdk.aws_ec2.PublicSubnet object at 0x7f3f48acb490>, <aws_cdk.aws_ec2.PublicSubnet object at 0x7f3f48acb050
2. 目的の L2 コンストラクト (この例では**aws_cdk.aws_ec2.PublicSubnet) に [node.default_child] 属性を使用します。次に、それを L1 [CFNSubnet] リソースとしてキャストします (この例ではaws_cdk.aws_ec2.CfnSubnet**)。
########## confirm cfn_public_subnet is a L1 construct ##########
for public_subnet in public_subnets:
cfn_public_subnet = public_subnet.node.default_child
print(cfn_public_subnet)
# printout: <aws_cdk.aws_ec2.CfnSubnet object at 0x7f3f48acb710>
# printout: <aws_cdk.aws_ec2.CfnSubnet object at 0x7f3f48acb950>
3. L1 [CFNSubnet] リソースにアクセスしたら、次のいずれかの方法を使用して L1 [CFNSubnet] コンストラクトの [CidrBlock] を変更します。
- [cidr_block] を直接変更します
- 未加工のオーバーライドを使用して [cidr_block] を修正します
[cidr_block] を直接、または未加工のオーバーライドを使用して変更する例:
public_subnets = vpc.public_subnets
public_subnet_index = 0
for public_subnet in public_subnets:
cfn_public_subnet = public_subnet.node.default_child
########### 1) modify the cidr_block property directly ###########
cfn_public_subnet.cidr_block = "60.0." + str(public_subnet_index + example_start_value) + ".0/24")
########### 2) modify the cidr_block by using raw overrides ###########
cfn_public_subnet.add_property_override("CidrBlock", "60.0." + str(public_subnet_index + example_start_value) + ".0/24")
public_subnet_index += 1
重要:[example_start_value] は必ず指定した値に置き換えてください。たとえば、[public_subnet] を [60.0.100.0/24] から開始するように変更する場合は、[example_start_value] を [100] に設定します。
4. [cdk synth] コマンドを実行して、新しく生成された CloudFormation テンプレートの AWS::EC2::Subnet リソース内の [CidrBlock] の更新を確認します。
cdk synth
出力例:
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: 60.0.100.0/24 <---
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: 60.0.101.0/24
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: <example_custom_value>/24
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
...
CidrBlock: <example_custom_value>/24
関連情報
PrivateSubnet
vpc.private_subnets