AWS Elastic Beanstalk 和 Secret Manager

Dam*_*ien 8 amazon-web-services amazon-elastic-beanstalk aws-secrets-manager

有谁知道是否可以在弹性 beantalk 中将秘密值作为环境变量传递?显然,另一种方法是在我们的代码库中使用 sdk,但我想首先探索环境变量方法

干杯达米安

小智 14

正如上面的答案提到的,如果您想在 Elastic Beanstalk 中执行此操作,仍然没有内置解决方案。然而,解决方案是使用“平台挂钩”。不幸的是,目前记录很少。

要存储您的密钥,最佳解决方案是在AWS-Secret-Manager中创建自定义密钥。在秘密管理器中,您可以通过单击“存储新秘密”来创建新秘密,然后选择“其他类型的秘密”并输入您的秘密密钥/值(请参阅截屏)。在下一步中,您需要提供一个秘密名称(例如“your_secret_name”),并且您可以将其他所有内容保留为默认设置。

然后,您需要允许 Elastic Beanstalk 获取此秘密。您可以通过创建新的 IAM 策略来完成此操作,例如使用以下内容:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "Getsecretvalue",
        "Effect": "Allow",
        "Action": [
            "secretsmanager:GetResourcePolicy",
            "secretsmanager:GetSecretValue",
            "secretsmanager:DescribeSecret",
            "secretsmanager:ListSecretVersionIds"
        ],
        "Resource": "your-secret-arn"
    }
]}
Run Code Online (Sandbox Code Playgroud)

您需要将“your-secret-arn”替换为您可以在 AWS-secret-manager 界面上获取的秘密 ARN。然后,您需要将创建的策略添加到 EB 角色(它应该是“aws-elasticbeanstalk-ec2-role”或“aws-elasticbeanstalk-service-role”)。

最后,您需要在应用程序中添加一个挂钩文件。从应用程序的根目录添加文件“.platform/hooks/prebuild/your_hook.sh”。文件的内容可以是这样的:

#!/bin/sh
export your_secret_key=$(aws secretsmanager get-secret-value --secret-id your-secret-name --region us-east-1 | jq -r '.SecretString' | jq -r '.your_secret_key')

touch .env
{
  printf "SECRET_KEY=%s\n" "$your_secret_key"
  # printf whatever other variable you want to pass
} >> .env
Run Code Online (Sandbox Code Playgroud)

显然,您需要将“your_secret_name”和其他变量替换为您自己的值,并将区域设置为存储您的秘密的区域(如果不是 us-east-1)。并且不要忘记使其可执行(“chmod +x your_hook.sh”)。

这假设您的应用程序可以从 .env 文件加载其 env(例如,它可以与 docker / docker-compose 配合使用)。

另一种选择是将变量存储在“.ebextensions”配置文件中,但不幸的是它似乎不适用于新的 Amazon Linux 2 平台。此外,您不应将敏感信息(例如凭据)直接存储在应用程序构建中。具有 Elastic Beanstalk 读取访问权限的任何人都可以访问该应用程序的构建,并且它们也未加密地存储在 S3 上。

通过挂钩方法,密钥仅存储在本地 Elastic Beanstalk 底层 EC2 实例上,并且您可以(应该!)限制对它们的直接 SSH 访问。


Ali*_*Ali 7

不幸的是,EB 在这一点上不支持机密,这可能会在未来添加。您可以按照文档的建议在环境变量中使用它们,但它们将以纯文本形式出现在控制台中。另一种和 IMO 更好的方法是使用 ebextensions,并使用AWS CLI 命令从 secrets manager 获取秘密,这需要一些设置(例如安装 AWS CLI 并将您的秘密存储在 SM 中)。您可以在同一 eb 配置中将这些设置为环境变量。希望这可以帮助!


kal*_*ech 6

根据@Ali 的回答,此时它不是内置的。但是,使用.ebextensions和 AWS cli相对容易。这是一个根据 MY_ENV 环境变量将机密提取到文件的示例。然后可以将此值设置为环境变量,但请记住,环境变量特定于 shell。您需要将它们传递给您正在启动的任何内容。

  10-extract-htpasswd:
    env:
      MY_ENV: 
        "Fn::GetOptionSetting":
          Namespace: "aws:elasticbeanstalk:application:environment"
          OptionName: MY_ENV
    command: |
      aws secretsmanager get-secret-value --secret-id myproj/$MY_ENV/htpasswd --region=us-east-1 --query=SecretString --output text > /etc/nginx/.htpasswd
      chmod o-rwx /etc/nginx/.htpasswd
      chgrp nginx /etc/nginx/.htpasswd
Run Code Online (Sandbox Code Playgroud)

这还需要向 EB 服务角色授予对机密的 IAM 权限。即一个政策,如:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "xxxxxxxxxx",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:us-east-1:xxxxxxxxxxxx:secret:myproj*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)


Kri*_*ver 5

我只是添加@kaliatech 的答案,因为虽然非常有帮助,但它有一些空白,让我几天无法正常工作。基本上,您需要将配置文件添加到EB 应用程序的.ebextensions目录,该文件使用container_commands部分检索您的密钥(以 JSON 格式)并将其作为.env.文件输出到/var/app/current应用程序代码所在的 EC2 实例的目录中:

# .ebextensions/setup-env.config
container_commands:
  01-extract-env:
    env:
      AWS_SECRET_ID:
        "Fn::GetOptionSetting":
          Namespace: "aws:elasticbeanstalk:application:environment"
          OptionName: AWS_SECRET_ID
      AWS_REGION: {"Ref" : "AWS::Region"}
      ENVFILE: .env

    command: >
        aws secretsmanager get-secret-value --secret-id $AWS_SECRET_ID --region $AWS_REGION |
        jq -r '.SecretString' |
        jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' > $ENVFILE
Run Code Online (Sandbox Code Playgroud)

注意:这假设是AWS_SECRET_ID在应用程序环境中配置的,但也可以在此处轻松进行硬编码。

此脚本工作所需的所有实用程序均已烘焙到 EC2 Linux 映像中,但您需要向 EC2 假定的IamInstanceProfile角色(通​​常名为)授予权限,以允许其访问 SecretManager:aws-elasticbeanstalk-ec2-role

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SecretManagerAccess",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:ap-southeast-2:xxxxxxxxxxxx:secret:my-secret-name*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

最后,要调试 EC2 实例引导期间遇到的任何问题,请下载 EB 日志并检查位于和 的EC2 日志文件/var/log/cfn-init.log/var/log/cfn-init-cmd.log