【问题标题】:What's the best way to consume Parameter Store value in AWS CDK在 AWS CDK 中使用 Parameter Store 值的最佳方式是什么
【发布时间】:2024-08-15 15:25:02
【问题描述】:

我在 CDK 中使用 SSM valueForStringParameter 方法时遇到问题。它在我第一次部署堆栈时工作,但是当我重新部署堆栈时它没有更新参数值,因为 CloudFormation 模板没有更改,因此 CloudFormation 认为没有更新,即使 SSM 参数已更改。

对于上下文,我通过 CodePipeline 部署堆栈,我首先运行 cdk synth,然后使用 CloudFormationCreateUpdateStackAction 操作部署模板。

有人知道如何解决这个问题吗?我知道唯一可行的其他选项是切换到调用 SSM 并使用 aws-sdk 返回值的自定义资源 lambda,但这感觉像是一个过于复杂的选项。

更新 1 我不能使用 ValueFromLookup,因为值仅在运行时更新,作为另一个堆栈的 cloudformation 部署的一部分(我在 CodePipeline 中部署两个堆栈,在 2 个不同的区域),因此综合时间查找会导致值过时。

【问题讨论】:

  • 我面临同样的问题。我想将 synth 的结果用作与 env 无关的包,但是如果没有查找功能,某些 Constructs 基本上是不可能使用的。例如,任何需要 IVpc 的东西都需要新创建的 vpc 或 VPC.fromLookup 函数的结果。

标签: amazon-cloudformation aws-cdk ssm aws-parameter-store


【解决方案1】:

由于您不能使用查找功能,并且将配置传递给 cdk 的最常见方法是通过 context variables,因此我只能建议一些肮脏的解决方法。

例如,您可以在堆栈中创建一个虚拟参数,以便在每次部署时触发。

var deploymentId = new CfnParameter(this, "deploymentId", new CfnParameterProps() { Type = "String", Description = "Deployment Id" });
SetParameterValue(deploymentId, this.Node.GetContext("deploymentId").ToString());

当你合成 CF 时,你可以生成一个 ID:

cdk synth -c deploymentId=$(uuidgen)

如果您可以避免“与环境无关”syth 并且您确实需要一个不可变的工件来跨多个环境部署,您可以使用您的 cdk 中的构建包,例如,包含您的 cdk 的 npm 包。因此,您可以通过覆盖上下文参数而不是使用 ssm 参数存储在每个环境中部署它。

【讨论】:

    【解决方案2】:

    所有 valueOf*from* 方法都通过添加 CloudFormation 参数来工作。正如您已经知道的那样,更改参数值不会更改模板,也不会触发任何更改。

    您可能想改用valueFromLookup 方法。在合成期间执行查找,并将结果放入生成的 CFN 模板中。

    ssm.StringParameter.valueFromLookup(this, 'param-name');
    

    但请注意,查找存储在cdk.context.json 中。如果您已将该文件提交到您的 repo,您​​需要在 synth/diff/deploy 之前通过cdk context -e ... 擦除该密钥。

    【讨论】:

    • 这可行,除非在我的情况下,值仅在运行时设置,因此综合时间检查不会选择最新值。我已经更新了我的问题
    • 将参数值作为 CFN 输出/导出返回是否有意义?这可以被第二个堆栈消耗。
    • 我希望可以。不幸的是,第二个堆栈位于另一个区域(因为 lambda@edge 仅支持 us-east-1),而第一个堆栈位于欧洲。第二个堆栈使用自定义资源 lambda 在欧洲 SSM 中存储价值,这部分工作正常。我现在已经通过在第一个堆栈中使用自定义资源 lambda 而不是 valueFromStringParameter 解决了这个问题,并且它有效,但它看起来像过度工程
    【解决方案3】:

    参见https://docs.aws.amazon.com/cdk/latest/guide/get_ssm_value.html,您可以使用方法valueFromLookup在综合时获取参数存储value,当值与前一个不同时,这将触发CF堆栈更新。

    但是,我的印象是,valueForStringParameter 也应该适用于更新的 ssm 参数值,基于 https://aws.amazon.com/blogs/mt/integrating-aws-cloudformation-with-aws-systems-manager-parameter-store/ 示例 2:

    【讨论】:

    • 我更新了关于为什么我不能使用综合时间查找的问题。示例 2 确实表明它应该可以工作,所以我会尝试更深入地挖掘