首页 > 解决方案 > 我可以强制 CloudFormation 解析来自 Secrets Manager 的值吗?

问题描述

在以下(缩写 CloudFormation 模板)中,我尝试配置 AWS Lambda 函数以从注入其环境的 AWS Secrets Manager 获取值:

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      Environment:
        Variables:
          SECRET_KEY: !Sub '{{resolve:secretsmanager:${Secret}:SecretString:KEY}}'

  Secret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: 'very-secret-thing'
      SecretString: '{"KEY":"dummy"}'

使用此模板创建堆栈时,一切都按预期出现。然后我去更改 CloudFormation 之外的机密值,因为我真的不希望将机密检查到源代码控制中。这是完全可能的,并且文档暗示,只要我避免更改SecretString模板中的虚拟值,后续 CloudFormation 堆栈更新就不会触及密钥的值。

因此,在 AWS 控制台中设置实际密钥后,我需要触发 Lambda 函数的重新部署,以便 CloudFormation 解析新的密钥值并在函数的环境中设置。我怎么做?

执行aws cloudformation deploy失败并显示消息:没有要部署的更改。

我怀疑 CloudFormation 将模板的“原始”版本与上次部署的版本进行比较,而没有首先解析对 Secrets Manager 的引用。是这样吗?是否有一些技巧可以强制提前取消引用?

脚注:我很清楚,以这种方式使用 Secrets Manager 会导致密钥值在 AWS Lambda 控制台中可见,并且在运行时从 Secrets Manager 获取值将是更安全的方法。这恰好超出了我希望做的事情的范围。

标签: amazon-web-servicesamazon-cloudformationaws-secrets-manager

解决方案


您可以人为地更改资源上的其他内容AWS::Serverless::Function,以在您进行部署时强制其更新。

比如说,一个时间戳:

Parameters:
  DeployTimestamp: { Type: String }

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      Environment:
        Variables:
          SECRET_KEY: !Sub '{{resolve:secretsmanager:${Secret}:SecretString:KEY}}'
          SECRET_KEY_UPDATED: !Ref DeployTimestamp

假设您从脚本进行部署,那么您aws cloudformation deploy --parameter-overrides "DeployTimestamp=$(date)"每次都会执行类似更改值的操作。

当然,这样做的缺点是该函数将更新每个部署,即使密钥尚未更新。如果这让您感到困扰,您可以变得更花哨并aws secretsmanager describe-secret --query LastChangedDate作为参数而不是当前时间注入。


推荐阅读