很好的问题。我同意 SSM Parameter Store 或 AWS Secrets Manager 是这项工作的推荐工具,但如果您遵循基础设施即代码原则,我认为它们并不那么有用。
因此,我将我的配置文件保存在同一个 Git 存储库中的 Terraform 脚本旁边,并在运行时将实际敏感数据(密码、密钥等)从 SSM 参数存储注入到特定的目标文件中。
与使用 AWS 提供的解决方案相比,这有几个优势:
- 没有大小限制(在免费版本中,SSM Parameter Store 将您限制为 4 KB)。
- 非敏感配置受版本控制,具有随之而来的所有优势。
- 我可以轻松查看当前使用的配置并更新它们,而无需登录 AWS 控制台等。
这是我使用 Terraform / AWS ECS 管理配置/机密的方法
基本思路如下:我们将没有敏感数据的配置文件存储在 Terraform 旁边的存储库中。秘密存储在 AWS 参数存储中。为了在运行时将数据放入我们的容器中,我们修改入口点。我们当然可以只创建修改后的图像,但在我看来这会产生很大的维护开销。使用入口点方法,我们可以继续使用原始图像。
缺点是我必须创建自定义入口点脚本。这意味着我必须找到我感兴趣的镜像的 Dockerfile 并提取用于启动镜像中运行的实际进程的命令。
我有一个这样的 git 存储库:
├── files
│ └── promstack
│ ├── grafana
│ │ ├── default-datasources.yml
│ │ ├── grafana.ini
│ │ └── run.sh
│ ├── loki
│ │ └── run.sh
│ ├── nginx
│ │ ├── nginx.conf
│ │ └── run.sh
│ └── prometheus
│ ├── prometheus.yml
│ ├── rules-alerting.yml
│ ├── rules-recording.yml
│ └── run.sh
├── myscript.tf
└── variables.tf
run.sh 脚本代表入口点。这是一个典型的run.sh:
#!/bin/sh
set -x
require () {
if [ ! "$1" ]; then
echo "ERROR: var not found"
exit 1
fi
}
expand () {
var_name="${1}"
file="${2}"
eval var="\$$var_name"
sed -i "s+\${${var_name}}+${var}+g" ${file}
sed -i "s+\$${var_name}+${var}+g" ${file}
}
require ${GRAFANA_INI}
require ${DEFAULT_DATASOURCES_YML}
require ${DOMAIN}
echo ${GRAFANA_INI} | base64 -d > /etc/grafana/grafana.ini
chmod 666 /etc/grafana/grafana.ini
expand DOMAIN /etc/grafana/grafana.ini
echo ${DEFAULT_DATASOURCES_YML} | base64 -d > /etc/grafana/provisioning/datasources/default.yml
chmod 666 /etc/grafana/provisioning/datasources/default.yml
su -s "/bin/sh" -c "/run.sh" grafana
这里是 Terraform 脚本的一部分(准确地说是 ECS 容器任务定义):
{
name: "grafana",
image: "grafana/grafana:7.0.5",
portMappings: [{
containerPort : 3000,
hostPort: 0,
protocol: "tcp"
}],
user: "0",
entryPoint: [ "/bin/sh", "-c", join(" ", [
"export DEFAULT_DATASOURCES_YML=${base64encode(file("${path.module}/files/promstack/grafana/default-datasources.yml"))};",
"export GRAFANA_INI=${base64encode(file("${path.module}/files/promstack/grafana/grafana.ini"))};",
"echo '${base64encode(file("${path.module}/files/promstack/grafana/run.sh"))}' | base64 -d | sh;"
])],
secrets: [
{
name: "DOMAIN",
valueFrom: "<my ssm parameter>"
}
]
},