在 CDK 2.0.0 中访问 AWS SecretsManager:software.amazon.awscdk.services.secretsmanager.Secret 的错误在未命名的模块中

Posted

技术标签:

【中文标题】在 CDK 2.0.0 中访问 AWS SecretsManager:software.amazon.awscdk.services.secretsmanager.Secret 的错误在未命名的模块中【英文标题】:Accessing AWS SecretsManager in CDK 2.0.0: Errors with software.amazon.awscdk.services.secretsmanager.Secret are in unnamed module 【发布时间】:2022-01-11 11:46:36 【问题描述】:

我最近从 AWS CDK v1.x 升级到 v2.0.0。我的堆栈使用 SecretsManager 访问包含许多秘密的 json 上的字符串有效负载。

在 CDK 1.x 中,我使用 SecretsManager 控制台中的示例代码来访问密钥字符串,它运行良好。但是在 CDK v2.0.0 中这些类不再可用,所以我需要将代码移植到 CDK v2.0.0 类中。

按照 CDK 指南 (https://docs.aws.amazon.com/cdk/v2/guide/get_secrets_manager_value.html) 中的示例,我在我的应用程序中创建了一个 SecretsManagerStack,如下所示:

public class SecretsManagerStack extends Stack 

    private String secretValue;

    public String getSecretValue()  
        return this.secretValue; 
    

    public SecretsManagerStack(final Construct scope, final String id) 
        this(scope, id, null);
    

    public SecretsManagerStack(final Construct scope, final String id, final SecretsManagerStackProps props) 
        super(scope, id, props.getStackProps());

        String secretName = ConfigManager.getInstance().get("$.aws.secrets.secretName");

        //Note this throws throws errors like:
        // java.lang.ClassCastException: class software.amazon.awscdk.services.secretsmanager.ISecret$Jsii$Proxy cannot be cast to class software.amazon.awscdk.services.secretsmanager.Secret
        // (software.amazon.awscdk.services.secretsmanager.ISecret$Jsii$Proxy and software.amazon.awscdk.services.secretsmanager.Secret are in unnamed module of loader 'app')

        Secret secret = (Secret)Secret.fromSecretAttributes(this, "sm-stack", 
             SecretAttributes.builder()
                .secretCompleteArn(secretName)
                .build());

        // Attempt to set a role on the secret - but this 'should' not be necessary?
        String accountId = ConfigManager.getInstance().get("$.aws.account");
        AccountPrincipal accountPrincipal = new AccountPrincipal(accountId);
        RoleProps roleProps = RoleProps.builder()
                .assumedBy(accountPrincipal)
                .build();
        Role secretAccessRole = new Role(this, "SecretsAccessRole", roleProps);
        secret.grantRead(secretAccessRole);

        this.secretValue = secret.getSecretValue().toString();

        //Ideally if this worked we would pass the stack as properties into other stacks so they
        // could access this secretValue and parse the json into what it needs to do. But alas no.

    


根据指南,这似乎是相当标准的库存,但没有运气。在运行时它返回:

java.lang.ClassCastException: class software.amazon.awscdk.services.secretsmanager.ISecret$Jsii$Proxy cannot be cast to class software.amazon.awscdk.services.secretsmanager.Secret 
(software.amazon.awscdk.services.secretsmanager.ISecret$Jsii$Proxy and software.amazon.awscdk.services.secretsmanager.Secret are in unnamed module of loader 'app')

尝试将角色添加到密钥以读取角色也没有影响(根据代码)。我的假设是,由于我是帐户所有者,因此没有必要这样做。

尝试使用 Secret.fromSecretCompleteArn 样式:

secret = (Secret) Secret.fromSecretCompleteArn(this, "SecretsManagerStack", secretName);

也产生相同的结果。

由于 CDK v2.0.0 看起来很新,我在搜索中没有找到任何类似的结果,所以有时间联系我们。有什么线索吗?有人在 AWS CDK v2.0.0 中见过这个吗?

【问题讨论】:

In CDK 1.x I used the sample code in the SecretsManager console to access the secret string and it worked fine. - 你是什么意思?该代码是 SDK,而不是 CDK。 当您滚动到密钥底部时,我指的是 AWS Secrets Manager Web 控制台中的示例代码 sn-p。好的,我知道这是使用不是 CDK 的 Java SDK。感谢您的澄清 - 这是我需要的精神推动。 【参考方案1】:

这是不可能的,而且从来没有。

无法在 CDK 中将 Secrets Manager 机密读取为纯文本。 CDK 只能传递对秘密的引用,这将在部署期间由 CloudFormation 解决。

您可以通过使用 SDK 来解决这个问题(看起来这就是您之前所做的),但这不是一个好的做法。您不应该在 CDK 代码中处理明文机密。

需要明确的是,CDK v1 和 v2 在这方面没有区别。

【讨论】:

谢谢 - 这很好地解释了它。在我的 CDK 堆栈中,我还引入了 SDK maven 依赖项,但没有意识到区别并正在使用它们。升级到 CDK v2.0.0 时,我清除了 SDK 依赖项,并试图在 CDK v2.0.0 中找到它们。我现在很欣赏两者之间的区别。它还很好地解释了为什么我在测试它们而不是实际秘密时从 CDK api 获取令牌 - 因为正如您所指出的,这些应该只在 cloudformation 部署时可用。感谢您朝正确的方向轻推!

以上是关于在 CDK 2.0.0 中访问 AWS SecretsManager:software.amazon.awscdk.services.secretsmanager.Secret 的错误在未命名的模块中的主要内容,如果未能解决你的问题,请参考以下文章

AWS 跨账户 - 对 AWS CDK 中的参数的参数存储/Secrets Manager 访问

Cloudfront 提供通过 AWS CDK Python 为 S3 存储桶来源创建的访问被拒绝响应,无需公共访问

AWS - 如何使用 CDK/CloudFormation 将服务链接角色传递给自动缩放组?

如何将 VPC 和安全组分配给 AWS CDK 中的 Lambda?

在 aws cdk 中安装软件包时面临的问题

如何在 Cloudformation 模板/CDK 中添加 AWS IoT 配置模板