aws-cdk: [DatabaseProxy] Model validation failed (#: required key [TargetGroupName] not found)

I tried DatabaseProxy with Database Cluster (Aurora, Postgres) but it’s failed as titled.

Reproduction Steps

    const databaseUser = 'test';
    const secret = new secretsmanager.Secret(this, 'secret', {
      generateSecretString: {
        generateStringKey: 'password',
        secretStringTemplate: `{"username": "${databaseUser}"}`,
        excludePunctuation: true
      }
    });

    const cluster = new rds.DatabaseCluster(this, 'Database', {
      engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,
      engineVersion: '11.7',
      defaultDatabaseName: 'mydatabase',
      masterUser: {
        username: databaseUser,
        password: secret.secretValueFromJson('password')
      },
      instanceProps: {
        instanceType: ec2.InstanceType.of(
          ec2.InstanceClass.R5,
          ec2.InstanceSize.LARGE
        ),
        vpcSubnets: {
          subnetType: ec2.SubnetType.PRIVATE
        },
        vpc
      },
      parameterGroup: new rds.ClusterParameterGroup(this, 'ParameterGroup', {
        family: 'aurora-postgresql11',
        parameters: {
          application_name: 'test',
        },
      }),
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    const proxy = new rds.DatabaseProxy(this, 'DatabaseProxy', {
      dbProxyName: 'test-proxy',
      debugLogging: true,
      iamAuth: false,
      requireTLS: true,
      secret,
      vpc,
      vpcSubnets: {
        subnetType: ec2.SubnetType.PRIVATE,
      },
      proxyTarget: rds.ProxyTarget.fromCluster(cluster),
    });

Error Log

Model validation failed (#: required key [TargetGroupName] not found)

Environment

  • CLI Version : 1.49.1
  • Framework Version: 1.49.1
  • Node.js Version: v13.7.0
  • OS : 10.14.6
  • Language (Version): TypeScript (3.7.5)

Other


This is 🐛 Bug Report

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 4
  • Comments: 20 (9 by maintainers)

Commits related to this issue

Most upvoted comments

This was my original workaround: Prior to rds.DatabaseProxy’s introduction in 1.49 I had to create the DB Proxy with CfnDBProxy. This route required me to set the proxy’s target group as follow:

const rdsProxy = new CfnDBProxy(this, id+'proxy',options);
const targetGroup = new CfnDBProxyTargetGroup(this, id + 'dbproxytarget', {
    dbProxyName: rdsProxy.ref,
    connectionPoolConfigurationInfo: {
        connectionBorrowTimeout: 120,
        maxConnectionsPercent: 99,
    },
    dbInstanceIdentifiers: [props.rds.instanceIdentifier]
});

This caused the same required key [TargetGroupName] error. After many hours of struggling and diving into the cdk source I realized there is no place where TargetGroupName* seems to be assigned to the target group, expept has has been pointed out, in cdk.Token.asString(this.getAtt('TargetGroupName')) which we can’t use, and no way to pass it into the constructor as a property. My workaround was to add the following line immediately after creating the target group:

targetGroup.addOverride('Properties.TargetGroupName', 'default');

TargetGroupName is not documented and assigning anything but default caused an enum error.

In cdk 1.49.0 the DatabaseProxy class was finally added, alongside the very helpful rdsInstance.addProxy(…) for which I am very thankful. However, I notice in the new proxy.ts file that was introduced calls the following

    new CfnDBProxyTargetGroup(this, 'ProxyTargetGroup', {
      dbProxyName: this.dbProxyName,
      dbInstanceIdentifiers,
      dbClusterIdentifiers: bindResult.dbClusters?.map((c) => c.clusterIdentifier),
      connectionPoolConfigurationInfo: toConnectionPoolConfigurationInfo(props),
    });

yet without again assigning the TargetGroupName. Hence the error still remaining.

You can thus solve the error by adding the following at the end of your code after const proxy

const proxy = ...

const targetGroup = proxy.node.findChild('ProxyTargetGroup') as CfnDBProxyTargetGroup;
targetGroup.addOverride('Properties.TargetGroupName', 'default');

I just tested these two lines on the new implementation of the cdk rds proxy class and it is working with my new db stack. I hope this helps.

Another problem has happened. After I applying this patch, the deployment was failed with the message “Timed out waiting for target group to become available.”. But I confirmed that the database proxy had been created successfully on the AWS Management Console.

Does anyone hit the same problem? Should I open another issue?

@tbrand thank you for your response! I found in the CloudWatch LogGroups that RDSProxy requires the RDS credentials to be formated {"username":"...","password":"..."}, however, my previous cdk stack only stores the password as secret.

Thanks guys. Finally I successfully created the proxy! 🎉 Here is the code.

     this.proxy = new rds.DatabaseProxy(this, 'DatabaseProxy', {
      dbProxyName: 'database-proxy',
      debugLogging: true,
      iamAuth: false,
      requireTLS: true,
      secret: this.secret,
      vpc: props.vpc,
      vpcSubnets: {
        subnetType: ec2.SubnetType.PRIVATE,
      },
      proxyTarget: rds.ProxyTarget.fromCluster(this.cluster),
    });

    const targetGroup = this.proxy.node.findChild('ProxyTargetGroup') as rds.CfnDBProxyTargetGroup;
    targetGroup.addOverride('Properties.TargetGroupName', 'default');
    targetGroup.addOverride('Properties.DBClusterIdentifiers', [this.cluster.clusterIdentifier]);
    targetGroup.addOverride('Properties.DBInstanceIdentifiers', []);

@d2kx Thank you for reporting.

fixed by 84d0a4a

I stumbled into this, and I also had to add another property override, because doing DBCluster#addProxy added both DBClusterIdentifiers and DBInstanceIdentifiers to the ProxyTargetGroup, which is not allowed. So my overrides look like this:

const dbProxyTargetGroup = dbProxy.node.findChild(
  'ProxyTargetGroup'
) as CfnDBProxyTargetGroup;
dbProxyTargetGroup.addPropertyDeletionOverride('DBInstanceIdentifiers');
dbProxyTargetGroup.addPropertyOverride('TargetGroupName', 'default');

which solves the problems.

Sorry for inconvenience caused.

It seems something has suddenly changed in CloudFormation. (They implicitly set TargetGroupName before)

Fortunately, I can find the point early with your help.

I hope this would work.