AWS CDK DocDB::DBCluster 失败 'not a valid password'

AWS CDK DocDB::DBCluster fails with 'not a valid password'

我正在尝试使用 AWS CKD (JAVA) 创建一个 DocumentDB 实例。 这适用于“简单”明文密码,但当我尝试使用 DatabaseSecret 和存储在 Secrets Manager.

中的密码时失败

我得到的错误是这样的:

1:44:42 PM | CREATE_FAILED        | AWS::DocDB::DBCluster                       | ApiDocDb15EB2C21
The parameter MasterUserPassword is not a valid password. Only printable ASCII characters besides '/', '@', '"', ' ' may
be used. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterValue; Request ID: c786d247-8ff2-4f30-9a8a-5
065fc89d3d1; Proxy: null)

这很清楚,但它继续发生,即使我将密码设置为 simplepassword 之类的东西 - 所以我现在有点困惑我现在应该修复什么。

这是代码,主要改编自 DocDB 文档:

    String id = String.format(DOCDB_PASSWORD_ID);

    return DatabaseSecret.Builder.create(scope, id)
        .secretName(store.getSsmSecretName())
        .encryptionKey(passwordKey)
        .username(store.getAdminUser())
        .build();

其中 ssmSecretName 是 SecretManager 中的秘密名称:

└─( aws secretsmanager get-secret-value --secret-id api-db-admin-pwd

ARN: arn:aws:secretsmanager:us-west-2:<ACCT>:secret:api-db-admin-pwd-HHxpFf

Name: api-db-admin-pwd
SecretString: '{"api-db-admin-pwd":"simplepassword"}'

这是用于构建 DbCluster 的代码:

    DatabaseCluster dbCluster = DatabaseCluster.Builder.create(scope, id)
        .dbClusterName(properties.getDbName())
        .masterUser(Login.builder()
            .username(properties.getAdminUser())
            .kmsKey(passwordKey)
            .password(masterPassword.getSecretValue())
            .build())
        .vpc(vpc)
        .vpcSubnets(ISOLATED_SUBNETS)
        .securityGroup(dbSecurityGroup)
        .instanceType(InstanceType.of(InstanceClass.MEMORY5, InstanceSize.LARGE))
        .instances(properties.getReplicas())
        .storageEncrypted(true)
        .build();

我的问题是:我应该使用 DatabaseSecret 吗?或者只是从 SM 中检索密码并完成它?

然后是一个子问题:那么应该使用 DatabaseSecret 做什么? (注意——这几乎与 rds 包中的 class 相同;但在这里我使用的是 docdb 包)

感谢任何建议!

原来 DatabaseSecret 创建了一个 key/value 对作为秘密:

{
  "username": <value of username()>,
  "password": <generated>
}

然而,对 Login.password() 的调用完全忽略了这一点,并将整个 JSON 正文视为密码(因此 " 双引号将其绊倒)。

诀窍是在对 Login.password() 的调用中使用 DatabaseSecret.secretValueFromJson("password"),它工作得很好。

这(顺便说一下)与 rds.DatabaseClusterrds.Credentials class 的行为不一致(他们采用 JSON SecretValue 并为 "password" 字段).

把它留在这里以防其他人无意中发现它,因为那里确实没有任何信息。