如何在部署时使用 Elastic Beanstalk 指定敏感环境变量

Posted

技术标签:

【中文标题】如何在部署时使用 Elastic Beanstalk 指定敏感环境变量【英文标题】:How to specify sensitive environment variables at deploy time with Elastic Beanstalk 【发布时间】:2015-08-10 00:40:07 【问题描述】:

我正在使用 Elastic Beanstalk 部署 Python Flask 应用程序。我有一个配置文件/.ebextensions/01.config,其中我设置了一些环境变量——其中一些应该是秘密的。

文件看起来像这样:

packages:
  yum:
    gcc: []
    git: []
    postgresql93-devel: []

option_settings:
  "aws:elasticbeanstalk:application:environment":
    SECRET_KEY: "sensitive"
    MAIL_USERNAME: "sensitive"
    MAIL_PASSWORD: "sensitive"
    SQLALCHEMY_DATABASE_URI: "sensitive"
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "app/static/"

对某些价值观保密的最佳做法是什么?目前.ebextensions 文件夹处于源代码控制之下,我喜欢这个,因为它与所有人共享,但同时我不想将敏感值保留在源代码控制之下。

部署时有没有办法通过 EB CLI 工具指定一些环境变量(例如eb deploy -config ...)?或者 AWS 部署工具如何涵盖此用例?

【问题讨论】:

【参考方案1】:

AWS documentation recommends storing sensitive information in S3 因为环境变量可能以各种方式暴露:

通过环境向您的应用程序提供连接信息 properties 是让密码远离代码的好方法,但它是 不是一个完美的解决方案。环境属性可在 环境管理控制台,任何拥有 在您的环境中描述配置设置的权限。 根据平台的不同,环境属性也可能出现在 实例日志。

下面的示例来自文档,您应该参考该文档以获取完整的详细信息。简而言之,您需要:

    以最小权限将文件上传到 S3,possibly encrypted。

    授予对您的 Elastic Beanstalk 自动扩展组的实例配置文件角色的读取权限。政策如下:

    
        "Version": "2012-10-17",
        "Statement": [
            
                "Sid": "database",
                "Action": [
                    "s3:GetObject"
                ],
                "Effect": "Allow",
                "Resource": [
                    "arn:aws:s3:::my-secret-bucket-123456789012/beanstalk-database.json"
                ]
            
        ]
    
    

    在您的应用程序包根目录中添加一个名称类似于 s3-connection-info-file.config/.ebextensions 的文件,其中包含以下内容:

    Resources:
      AWSEBAutoScalingGroup:
        Metadata:
          AWS::CloudFormation::Authentication:
            S3Auth:
              type: "s3"
              buckets: ["my-secret-bucket-123456789012"]
              roleName: "aws-elasticbeanstalk-ec2-role"
    
    files:
      "/tmp/beanstalk-database.json" :
        mode: "000644"
        owner: root
        group: root
        authentication: "S3Auth"
        source: https://s3-us-west-2.amazonaws.com/my-secret-bucket-123456789012/beanstalk-database.json
    

然后更新您的应用程序代码以从文件 /tmp/beanstalk-database.json(或您决定将其放入实际配置的任何位置)中提取值。

【讨论】:

我偶然发现了AWS Systems Manager Parameter Store,它也可能是存储敏感信息(但不是专门用于环境变量)的解决方案。它“为配置数据管理和机密管理提供安全的分层存储”。看起来很像 HashiCorp 的领事。【参考方案2】:

这个问题已经有了答案,但我想为这个问题提供一个替代解决方案。我不必将秘密保存在环境变量中(然后必须在不受版本控制的地方进行管理和存储,而且您需要记住在部署时设置它们),而是将我所有的秘密放在一个加密的 S3 存储桶中,只能从EB 运行的角色。然后我在启动时获取秘密。这具有将部署与配置完全解耦的好处,您再也不必在命令行中摆弄秘密。

如果需要(例如,如果在应用设置期间需要机密信息,例如获取代码的存储库的密钥),您还可以使用带有 S3Auth 指令的 .ebextensions 配置文件轻松复制所述 S3 的内容存储到您的本地实例;否则,只需在启动时使用 AWS 开发工具包从应用程序中获取所有机密。

编辑:截至 2018 年 4 月,AWS 为机密管理提供了专门的托管服务; AWS Secrets Manager。它以字符串或 json 格式、版本控制、阶段、轮换等提供方便的安全存储秘密。当涉及到 KMS、IAM 等时,它还消除了一些配置,以实现更快的设置。我认为没有真正的理由使用任何其他 AWS 服务来存储私钥、密码等静态敏感数据。

【讨论】:

【参考方案3】:

您应该能够从 eb Web 控制台将敏感值指定为环境变量:您的 EB 应用程序 -> 您的 EB 环境 -> 配置 -> 软件配置 -> 环境属性

或者,你可以使用这个:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb3-setenv.html

编辑:虽然这是 2015 年接受的答案,但这不应该是您处理它的方式。现在您可以为此目的使用 AWS Secrets Manager。

【讨论】:

我们如何修改环境属性,环境属性列表是不可见的。我想更新我已经设置的环境属性并且应用程序也在运行。我已经按照你的回答做了。我是新手。 PS。 不好的做法。为此使用 AWS Secrets Manager。 @Manuel 是的。自从这篇文章是在 2015 年发表后,我继续使用参数存储并最终使用秘密管理器.. 太棒了!只是想提一下未来的读者。最近的 Codecov 安全不雅事件实际上表明 env var 很容易被暴露。【参考方案4】:

我一直在使用另一个 shell 脚本,即 ./deploy_production.sh 来设置环境特定的变量。在shell脚本中,可以使用“eb setenv NAME1=VAR1 NAME2=VAR2 ...”来设置环境变量。

而且这个文件不需要进入 git repo。

【讨论】:

有没有办法从 aws cli 做到这一点? 如果它不在 git repo 中,你如何在你的实例上运行它?【参考方案5】:

其他一些答案提到使用 Parameter Store / Secrets Manager 可能有更好的方法。

我在这个答案中描述了我是如何使用 AWS Systems Manager Parameter Store(它还为您提供 Secrets Manager 的接口)做到这一点的:https://***.com/a/59910941/159178。基本上,您让您的 Beanstalk ECS IAM 角色访问相关参数,然后在启动时从您的应用程序代码中加载它。

【讨论】:

以上是关于如何在部署时使用 Elastic Beanstalk 指定敏感环境变量的主要内容,如果未能解决你的问题,请参考以下文章