はじめに
AWS CDKは、L1/L2/L3コンストラクトという概念があり、異なる抽象化のレベルでAWSリソースを扱うことが出来ます。
L1はCloudFormation templateの定義そのものに対応しており、L2/L3はより抽象化されたものとなっています。
通常はL2/L3のものを用いるのが良いですが、L2ではサポートされていないプロパティがある場合、L1のレベルでの操作が必要となります。
特に、RDS関連のL2コンストラクトはきめ細かなプロパティが制御できないため、適宜L1コンストラクトのオブジェクトを扱うこととなります。
本稿ではその方法を簡単に説明します。
概要
L2オブジェクトは node
プロパティを持っており、ここから対応するL1オブジェクトを取得することが出来ます。
L1オブジェクトを取得することが出来れば、L2コンストラクトでは指定できないプロパティを指定することが可能になります。
Raw overrides// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild as s3.CfnBucket; // Use dot notation to address inside the resource template fragment cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status'); // use index (0 here) to address an element of a list cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue'); cfnBucket.addDeletionOverride('Properties.Tags.0'); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status'); cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue'); cfnBucket.addPropertyDeletionOverride('Tags.0');
上記公式ドキュメントにもありますように {L2オブジェクト}.node.defaultChild
プロパティで、L1オブジェクトを取得することが出来ます。
これを利用して、RDSのL2オブジェクトである DatabaseCluster
から、
L1オブジェクトである CfnDBCluster
および CfnDBInstance
オブジェクトを取り出すことが出来ます。
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.DatabaseCluster.html#node
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.CfnDBCluster.html
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.CfnDBInstance.html
サンプルコード
CfnDBCluster の取り出し
最初に、RDS WriterインスタンスとしてClusterInstanceを作り、DatabaseClusterオブジェクトを生成します。
// RDS instance
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.ClusterInstance.html
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.ProvisionedClusterInstanceProps.html
const writer = ClusterInstance.provisioned('Dev1LoremRdsWriter1', {
instanceIdentifier: 'dev1-lorem-rds-writer-1',
});
// RDS Aurora PostgreSQL cluster
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.DatabaseCluster.html
const databaseCluster = new DatabaseCluster(this, 'Dev1LoremRdsCluster'), {
clusterIdentifier: 'dev1-lorem-rds-cluster',
engine: DatabaseClusterEngine.auroraPostgres({
version: AuroraPostgresEngineVersion.VER_15_2,
}),
writer: writer,
vpc: vpc,
subnetGroup: subnetGroup,
securityGroups: [sgForRds],
});
下記のように、 DatabaseCluster
型のオブジェクトから CfnDBCluster
型のオブジェクトを取り出すことが出来ます。
なお、 defaultChild
プロパティは常に IConstruct
型となるので、必要な型(今回は CfnDBCluster
)にキャストします。
L1コンストラクトオブジェクトは addPropertyOverride
メソッドを持っているので、これを用いて必要な設定を上書きします。
const dbClusterL1 = databaseCluster.node.defaultChild as CfnDBCluster;
dbClusterL1.addPropertyOverride('AutoMinorVersionUpgrade', false);
CfnDBInstance の取り出し
次に、DBクラスタ内のDBインスタンスのオブジェクトを、 CfnDBInstance
型オブジェクトとして取り出します。
まず、先ほどと同様に、ClusterInstanceを作り、DatabaseClusterオブジェクトを生成します。
// RDS instance
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.ClusterInstance.html
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.ProvisionedClusterInstanceProps.html
const writer = ClusterInstance.provisioned('Dev1LoremRdsWriter1', {
instanceIdentifier: 'dev1-lorem-rds-writer-1',
});
// RDS Aurora PostgreSQL cluster
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.DatabaseCluster.html
const databaseCluster = new DatabaseCluster(this, 'Dev1LoremRdsCluster'), {
clusterIdentifier: 'dev1-lorem-rds-cluster',
engine: DatabaseClusterEngine.auroraPostgres({
version: AuroraPostgresEngineVersion.VER_15_2,
}),
writer: writer,
vpc: vpc,
subnetGroup: subnetGroup,
securityGroups: [sgForRds],
});
DatabaseCluster
型オブジェクトから、 node
プロパティをたどって、配下にいるDBインスタンスのオブジェクトも取得することが出来ます。
指定が少し複雑になりますが、まず DatabaseCluster.node.findChild('ClusterInstance名')
で、DBインスタンスのオブジェクトを取得することが出来ます。
このDBインスタンスのオブジェクトから、 node.defaultChild
をたどることで、L1オブジェクトであるCfnDBInstance
型オブジェクトを取り出すことが出来ます。
下記がサンプルコードとなります。
// Make the RDS writer instance on a specific AZ.
// https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html#cfn_layer_raw
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.CfnDBInstance.html
const writerL1 = databaseCluster.node.findChild('Dev1LoremRdsWriter1')?.node.defaultChild as CfnDBInstance;
writerL1.addPropertyOverride("AvailabilityZone", "us-west-1a");
おわりに
上記、抽象化の概念や考え方、escape hatchesの考え方はAWS CDKのドキュメントに記載されています。
実装する上で参考になるので、一通り目を通しておくと良いでしょう。