aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.72k stars 3.94k forks source link

aws-cdk-lib/aws-rds: The `rds.DatabaseCluster` L2 construct cannot be conifgured with a custom parameter group containing customized parameter values #26909

Open Liroyal opened 1 year ago

Liroyal commented 1 year ago

Describe the bug

Provisioning an Aurora cluster using L2 constructs doesn't allow creating a custom parameter group with the parameter rds.babelfish_status set to on.

The code used:

import * as rds from 'aws-cdk-lib/aws-rds';
...
var parameterGroup1 = new rds.ParameterGroup(this, `${resourcePrefix}-custom-parameter-group`, {
   engine: rds.DatabaseInstanceEngine.postgres ({
     version: rds.PostgresEngineVersion.VER_14_6,
   }),
   parameters: {
     "rds.babelfish_status": "on",
   },
});
...
const cluster = new rds.DatabaseCluster(this, `${resourcePrefix}-aurora-cluster`, {
  engine: rds.DatabaseClusterEngine.auroraPostgres({
    version: rds.AuroraPostgresEngineVersion.VER_14_6,
  }),
  instances: 1,
  instanceProps: {
    vpc: vpc,
    instanceType: new InstanceType("r5.large"),
    autoMinorVersionUpgrade: true,
    vpcSubnets: {
      subnetType: ec2.SubnetType.PUBLIC,
    },
    securityGroups: [
      securityGroup1
    ],
  },      
  storageEncrypted: true,
  parameterGroup: parameterGroup1,
});

Omitting the parameterGroup property from the cluster's CTOR allows deploying the stack successfully, using the default cluster's parameter group.

Expected Behavior

The Aurora cluster should be deployed, configured with the custom parameter group defined in code, containing the parameter rds.babelfish_status set to on.

Current Behavior

A deployment time error occurs, with the error message: Resource handler returned message: "Invalid / Unmodifiable / Unsupported DB Parameter: rds.babelfish_status" (RequestToken: 24e84d17-a330-a5ae-140f-c0e9e37b7fdf, HandlerErrorCode: InvalidRequest).

image

Reproduction Steps

Deploy the below stack code:

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

export class AuroraServerlessStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    const resourcePrefix = 'my-prefix';

    super(scope, id, props);

    const vpc = new ec2.Vpc(this, 'a-secure-vpc', {
      ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
      maxAzs: 2,
      subnetConfiguration: [
        {
          name: `${resourcePrefix}-public-subnet-1`,
          subnetType: ec2.SubnetType.PUBLIC,
          cidrMask: 24,
        },
      ],
      gatewayEndpoints: {
        S3: {
          service: ec2.GatewayVpcEndpointAwsService.S3
        }
      },
    });

    const vpcEndpointSecurityGroup = new ec2.SecurityGroup(this, `${resourcePrefix}-endpoint-security-group`, {
      allowAllOutbound: true,
      vpc
    }
    );
    vpcEndpointSecurityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(443),
      "allow HTTPS from private ec2 "
    )

    vpc.addInterfaceEndpoint('ssm', {
      service: ec2.InterfaceVpcEndpointAwsService.SSM,
      securityGroups: [vpcEndpointSecurityGroup]
    });

    vpc.addInterfaceEndpoint('ssm-messages', {
      service: ec2.InterfaceVpcEndpointAwsService.SSM_MESSAGES,
      securityGroups: [vpcEndpointSecurityGroup]
    });

    vpc.addInterfaceEndpoint('ec2-messages', {
      service: ec2.InterfaceVpcEndpointAwsService.EC2_MESSAGES,
      securityGroups: [vpcEndpointSecurityGroup]
    });

    var securityGroup1 = new ec2.SecurityGroup(this, `${resourcePrefix}-my-pc-sg`, {
      vpc,
      allowAllOutbound: true,
    });

    securityGroup1.addIngressRule(
      ec2.Peer.ipv4("1.2.3.4/32"),
      ec2.Port.tcp(5432),
      "Allow Postgres from my IP"
    )

    securityGroup1.addIngressRule(
      ec2.Peer.ipv4("1.2.3.4/32"),
      ec2.Port.tcp(1433),
      "Allow MSSQL/TDS from my IP"
    )

    var parameterGroup1 = new rds.ParameterGroup(this, `${resourcePrefix}-custom-parameter-group`, {
      engine: rds.DatabaseInstanceEngine.postgres ({
        version: rds.PostgresEngineVersion.VER_14_6,
      }),
      parameters: {
        "rds.babelfish_status": "on",
      },
    });

    const dbase = new rds.DatabaseCluster(this, `${resourcePrefix}-aurora-cluster`, {
      engine: rds.DatabaseClusterEngine.auroraPostgres({
        version: rds.AuroraPostgresEngineVersion.VER_14_6,
      }),
      instances: 1,
      instanceProps: {
        vpc: vpc,
        instanceType: new InstanceType("r5.large"),
        autoMinorVersionUpgrade: true,
        vpcSubnets: {
          subnetType: ec2.SubnetType.PUBLIC,
        },
        securityGroups: [
          securityGroup1
        ],
      },      
      storageEncrypted: true,
      parameterGroup: parameterGroup1,
    });

    const bastion = new ec2.BastionHostLinux(this, `${resourcePrefix}-privateBastion`, {
      instanceName: "bastion1",
      instanceType: new ec2.InstanceType("t4g.nano"),
      vpc,
    });

    bastion.connections.allowToDefaultPort(dbase);

    new CfnOutput(this, 'Bastion ID', {
      exportName: bastion.stack.stackName + ':BastionID',
      value: bastion.instanceId,
    });

    new CfnOutput(this, 'OutputClusterIdentifier', {
      exportName: dbase.stack.stackName+'ClusterIdentifier',
      value: dbase.clusterIdentifier.toString(),
    });
  }
}

Possible Solution

Make the rds.DatabaseCluster support accepting custom parameter groups with customized parameter values.

Additional Information/Context

No response

CDK CLI Version

2.93.0 (build 724bd01)

Framework Version

No response

Node.js Version

18.17.1

OS

Windows 11

Language

Typescript

Language Version

5.1.6

Other information

No response

pahud commented 1 year ago

This seems to be a blocker from cloudformation instead of CDK as I can confirm the AWS::RDS::DBClusterParameterGroup is synthesized correctly according to the document sample. But for some reason cloudformation considers this an invalid parameter, which should be supported in Aurora Postgresql Version 14 according to this doc.

  "myprefixcustomparametergroupBB1CF4E4": {
   "Type": "AWS::RDS::DBClusterParameterGroup",
   "Properties": {
    "Description": "Cluster parameter group for postgres14",
    "Family": "postgres14",
    "Parameters": {
     "rds.babelfish_status": "on"
    }
   },
   "Metadata": {
    "aws:cdk:path": "xxx-stack/my-prefix-custom-parameter-group/Resource"
   }

I noticed the family of your parameter group is actually postgres14, maybe it should be aurora-postgresql14 instead? This parameter seems to be for Aurora PostgreSQL only?

Liroyal commented 1 year ago

Thanks, Pahud, for your answer.

Replacing the engine version rds.PostgresEngineVersion.VER_14_6 with rds.AuroraPostgresEngineVersion.VER_14_6 doesn't work because rds.AuroraPostgresEngineVersion.VER_14_6 type is AuroraPostgresEngineVersion which is a class that doesn't implement IEngine, as expected by the ParameterGroupProps interface.

image image image image image