AWS DocumentDB CloudFormation部署遇密码/用户名长度超限异常
使用CloudFormation搭建AWS DocumentDB集群时,通过Secrets Manager生成凭据:
DbClusterCredentials: Type: AWS::SecretsManager::Secret Properties: Name: … Description: … GenerateSecretString: SecretStringTemplate: '{"username": "admin"}' GenerateStringKey: "password" PasswordLength: 100 ExcludeCharacters: '/"@'
在DocumentDB集群配置中引用该凭据:
DbCluster: Type: AWS::DocDB::DBCluster Properties: DBClusterIdentifier: … DBSubnetGroupName: … … MasterUsername: !Sub "{{resolve:${DbClusterCredentials}:SecretString:username}}" MasterUserPassword: !Sub "{{resolve:${DbClusterCredentials}:SecretString:password}}" …
部署时CloudFormation回滚,DbCluster创建失败,错误信息:
Property validation failure: [Length of value for property {/MasterUserPassword} is greater than maximum allowed length {100}, Length of value for property {/MasterUsername} is greater than maximum allowed length {63}]
明明密码长度设置为100(未超最大值),用户名为admin(未超63字符限制),却触发长度超限错误。
问题出在**!Sub和Secrets Manager的resolve表达式结合使用的方式错误**。当用!Sub包裹{{resolve:...}}时,CloudFormation不会直接解析resolve表达式获取实际的用户名/密码,而是会把整个经过Sub替换后的字符串(比如{{resolve:arn:aws:secretsmanager:...:SecretString:username}})作为值传递给MasterUsername和MasterUserPassword字段。这个字符串的长度远超过了DocumentDB对用户名(63字符)和密码(100字符)的限制,因此触发了验证失败。
解决方法很简单:直接使用resolve表达式,不要用!Sub包裹。修改后的集群配置如下:
DbCluster: Type: AWS::DocDB::DBCluster Properties: DBClusterIdentifier: … DBSubnetGroupName: … … MasterUsername: "{{resolve:secretsmanager:${DbClusterCredentials}:SecretString:username}}" MasterUserPassword: "{{resolve:secretsmanager:${DbClusterCredentials}:SecretString:password}}" …
或者使用CloudFormation的动态引用格式(推荐):
DbCluster: Type: AWS::DocDB::DBCluster Properties: DBClusterIdentifier: … DBSubnetGroupName: … … MasterUsername: !GetAtt DbClusterCredentials.SecretString.username MasterUserPassword: !GetAtt DbClusterCredentials.SecretString.password …
这两种方式都能让CloudFormation正确解析Secrets Manager中的实际凭据值,而不是传递resolve模板字符串,从而符合DocumentDB的字段长度限制。
内容的提问来源于stack exchange,提问作者Garret Wilson

