如何在部署时使用 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 指定敏感环境变量的主要内容,如果未能解决你的问题,请参考以下文章