How to pass AWS Secret to Elastic Document DB Cluster using CDK/ Terraform/ Cloudformation

127 views Asked by At

I am trying to create a Elastic Document DB cluster using AWS CDK. This is the L1 resource to achieve the same (sadly there is no L2 construct for Elastic doc db).

There is a property authType which accepts either PLAIN_TEXT or SECRET_ARN as values. The documentation doesn't clarify what it means. Neither is the Cloudformation documentation clear. I am assuming that when the value is set to PLAIN_TEXT, we have to hardcode our password in our CDK code under the adminUserPassword field (which is not secure). So how to use the SECRET_ARN value? Where do I create and pass my AWS Secret?

The CDK documentation states that adminUserPassword is an optional field while the Cloud formation documentation states that it is a conditional field. But when I omit this field (regardless of the value of authType), Cloudformation throws an error that this field is missing.

This is what I tried

const secret = new cdk.aws_secretsmanager.Secret(this, 'DocDbSecret', {
      description: "Secret for docDb cluster",
      secretName: "docDbSecret", 
    });


    const elasticCluster = new aws_docdbelastic.CfnCluster(this, 'elasticCluster', {
        adminUserName: 'myAdmin',
        adminUserPassword: secret.secretArn, // Should we pass secret here? if yes how?
        authType: 'SECRET_ARN',
        clusterName: 'myCluster',
        shardCapacity: 2,
        shardCount: 2,
    });

The terraform resource also has the same confusion...

3

There are 3 answers

0
Exter On BEST ANSWER

We have to pass the ARN of the secret in the adminUserPassword field.

Though, the password for doc db cluster has some conditions which should be specified when generating the secret.

  • Auth type will be SECRET_ARN.

  • adminUserPassword will be secret.secretArn

  • Secret

should not contain @"/

/**
 * Create a new secret
 * https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_secretsmanager.Secret.html
 */
const secret = new secretsmanager.Secret(this, 'docDbSecret', {
  description: "Description",
  secretName: "docDbSecret",
  generateSecretString: {
    // Don't include / @ "
    excludeCharacters: '/@"',
  }
});


const elasticCluster = new aws_docdbelastic.CfnCluster(this, 'elasticCluster', {
    adminUserName: 'myAdmin',
    adminUserPassword: secret.secretArn, 
    authType: 'SECRET_ARN',
    clusterName: 'myCluster',
    shardCapacity: 2,
    shardCount: 2,
});
1
Cloudlady On

You can create a username / password in AWS Secrets Manager, with the username being the name of your secret. You can then reference this ARN in the call. secret-ARN

0
André Sionek On

Why don't you use the L2 opensearch.Domain? Then you can specify the engine to be elastic: opensearch.EngineVersion.ELASTICSEARCH_7_10.

But to answer your question exactly, you need to tell CDK to parse the secret value as a string.

        
secret = secretmanager.Secret(
    scope=self,
    id="Secret",
    generate_secret_string=secretmanager.SecretStringGenerator(
        generate_string_key="password",
        password_length=30,
        secret_string_template="{\"username\":\"myAdmin\"}",
        exclude_characters="%+~`#$&*()|[]{}:;<>?!'/@\"",
    )
)

docdb.CfnCluster(
    scope=self,
    id="DocDB",
    admin_user_name=secret.secret_value_from_json("username").to_string(),
    admin_user_password=secret.secret_value_from_json("password").to_string(),
    auth_type="PLAINTEXT",
    cluster_name="docdb-cluster",
    shard_capacity=1,
    shard_count=1,
)

Will result in this:

"StorageDocDBD4AB00F5": {
   "Type": "AWS::DocDBElastic::Cluster",
   "Properties": {
    "AdminUserName": {
     "Fn::Join": [
      "",
      [
       "{{resolve:secretsmanager:",
       {
        "Ref": "StorageSecretAF41D9AB"
       },
       ":SecretString:username::}}"
      ]
     ]
    },
    "AdminUserPassword": {
     "Fn::Join": [
      "",
      [
       "{{resolve:secretsmanager:",
       {
        "Ref": "StorageSecretAF41D9AB"
       },
       ":SecretString:password::}}"
      ]
     ]
    },
    "AuthType": "PLAINTEXT",
    "ClusterName": "docdb-cluster",
}