通过用户数据脚本安装新的 aws 实例时解密的变量
Decrypted vars when install a new aws instance via user-data script
我已经准备好 Ansible 剧本,它们包括几个加密变量。在正常过程中,我可以提供一个保险库密码文件以使用 --vault-password-file ~/.vault_pass.txt
解密它们并将更改部署到远程 EC2 实例。所以我不需要公开密码文件。
但是我这里的要求不一样。创建新的 EC2 实例时,我需要在 user-data
脚本中包含 ansible-playbook 更改。理想情况下,我应该在实例 运行.
之后自动准备好所有设置
我通过以下简单的 user-data
脚本使用 Terraform 部署实例:
#!/usr/bin/bash
yum -y update
/usr/local/bin/aws s3 cp s3://<BUCKET>/ansible.tar.gz ansible.tar.gz
gtar zxvf ansible.tar.gz
cd ansible
ansible-playbook -i inventory/ec2.py -c local ROLE.yml
所以我也必须将我的密码文件上传到用户数据脚本中,如果在剧本中,有一些加密的变量。
我能做些什么来避免它? Ansible Tower 会帮助这个请求吗?
我确实用 CredStash 进行了测试,但仍然是先有鸡还是先有蛋的问题。
如果您希望您的实例自行配置,它们要么需要所有凭据,要么需要其他方式来获取凭据,最好使用某种形式的一次性传递。
我能想到的最好的方法是使用 Hashicorp's Vault to store the credentials (potentially all of our secrets or maybe just the Ansible Vault password that then can be used to un-vault your Ansible variables) and have your deploy process create a one time use token that is injected into the user-data script via Terraform's templating。
为此,您可能需要使用某种形式的辅助脚本来包装 Terraform apply 命令,该脚本可能如下所示(未经测试):
#!/bin/bash
vault_host="10.0.0.3"
vault_port="8200"
response=`curl \
-X POST \
-H "X-Vault-Token:$VAULT_TOKEN" \
-d '{"num_uses":"1"}' \
http://${vault_host}:${vault_port}/auth/token/create/ansible_vault_read`
vault_token=`echo ${response} | jq '.auth.client_token' --raw-output`
terraform apply \
-var 'vault_host=${vault_host}'
-var 'vault_port=${vault_port}'
-var 'vault_token=${vault_token}'
然后您的用户数据脚本将希望在 Terraform 中使用如下内容(也未经测试)进行模板化:
template.tf:
resource "template_file" "init" {
template = "${file("${path.module}/init.tpl")}"
vars {
vault_host = "${var.vault_host}"
vault_port = "${var.vault_port}"
vault_token = "${var.vault_token}"
}
}
init.tpl:
#!/usr/bin/bash
yum -y update
response=`curl \
-H "X-Vault-Token: ${vault_token}" \
-X GET \
http://${vault_host}:${vault_port}/v1/secret/ansible_vault_pass`
ansible_vault_password=`echo ${response} | jq '.data.ansible_vault_pass' --raw-output`
echo ${ansible_vault_password} > ~/.vault_pass.txt
/usr/local/bin/aws s3 cp s3://<BUCKET>/ansible.tar.gz ansible.tar.gz
gtar zxvf ansible.tar.gz
cd ansible
ansible-playbook -i inventory/ec2.py -c local ROLE.yml --vault-password-file ~/.vault_pass.txt
或者,您可以简单地让实例调用诸如 Ansible Tower 之类的东西来触发剧本 运行 反对它。这使您可以将秘密保存在执行配置的中央盒子上,而不必将它们分发到您正在部署的每个实例。
对于 Ansible Tower,这是使用 callbacks 完成的,您将需要设置作业模板,然后让您的用户数据脚本卷曲 Tower 以触发配置 运行。您可以将用户数据脚本更改为如下内容:
template.tf:
resource "template_file" "init" {
template = "${file("${path.module}/init.tpl")}"
vars {
ansible_tower_host = "${var.ansible_tower_host}"
ansible_host_config_key = "${var.ansible_host_config_key}"
}
}
init.tpl:
#!/usr/bin/bash
curl \
-X POST
--data "host_config_key=${ansible_host_config_key}" \
http://{${ansible_tower_host}/v1/job_templates/1/callback/
host_config_key 乍一看似乎是个秘密,但它是一个共享密钥,可用于多个主机访问作业模板,Ansible Tower 仍然只会 运行 如果主机要么在作业模板的静态清单中定义,要么如果您使用的是动态清单,那么如果在该查找中找到主机。
我已经准备好 Ansible 剧本,它们包括几个加密变量。在正常过程中,我可以提供一个保险库密码文件以使用 --vault-password-file ~/.vault_pass.txt
解密它们并将更改部署到远程 EC2 实例。所以我不需要公开密码文件。
但是我这里的要求不一样。创建新的 EC2 实例时,我需要在 user-data
脚本中包含 ansible-playbook 更改。理想情况下,我应该在实例 运行.
我通过以下简单的 user-data
脚本使用 Terraform 部署实例:
#!/usr/bin/bash
yum -y update
/usr/local/bin/aws s3 cp s3://<BUCKET>/ansible.tar.gz ansible.tar.gz
gtar zxvf ansible.tar.gz
cd ansible
ansible-playbook -i inventory/ec2.py -c local ROLE.yml
所以我也必须将我的密码文件上传到用户数据脚本中,如果在剧本中,有一些加密的变量。
我能做些什么来避免它? Ansible Tower 会帮助这个请求吗?
我确实用 CredStash 进行了测试,但仍然是先有鸡还是先有蛋的问题。
如果您希望您的实例自行配置,它们要么需要所有凭据,要么需要其他方式来获取凭据,最好使用某种形式的一次性传递。
我能想到的最好的方法是使用 Hashicorp's Vault to store the credentials (potentially all of our secrets or maybe just the Ansible Vault password that then can be used to un-vault your Ansible variables) and have your deploy process create a one time use token that is injected into the user-data script via Terraform's templating。
为此,您可能需要使用某种形式的辅助脚本来包装 Terraform apply 命令,该脚本可能如下所示(未经测试):
#!/bin/bash
vault_host="10.0.0.3"
vault_port="8200"
response=`curl \
-X POST \
-H "X-Vault-Token:$VAULT_TOKEN" \
-d '{"num_uses":"1"}' \
http://${vault_host}:${vault_port}/auth/token/create/ansible_vault_read`
vault_token=`echo ${response} | jq '.auth.client_token' --raw-output`
terraform apply \
-var 'vault_host=${vault_host}'
-var 'vault_port=${vault_port}'
-var 'vault_token=${vault_token}'
然后您的用户数据脚本将希望在 Terraform 中使用如下内容(也未经测试)进行模板化:
template.tf:
resource "template_file" "init" {
template = "${file("${path.module}/init.tpl")}"
vars {
vault_host = "${var.vault_host}"
vault_port = "${var.vault_port}"
vault_token = "${var.vault_token}"
}
}
init.tpl:
#!/usr/bin/bash
yum -y update
response=`curl \
-H "X-Vault-Token: ${vault_token}" \
-X GET \
http://${vault_host}:${vault_port}/v1/secret/ansible_vault_pass`
ansible_vault_password=`echo ${response} | jq '.data.ansible_vault_pass' --raw-output`
echo ${ansible_vault_password} > ~/.vault_pass.txt
/usr/local/bin/aws s3 cp s3://<BUCKET>/ansible.tar.gz ansible.tar.gz
gtar zxvf ansible.tar.gz
cd ansible
ansible-playbook -i inventory/ec2.py -c local ROLE.yml --vault-password-file ~/.vault_pass.txt
或者,您可以简单地让实例调用诸如 Ansible Tower 之类的东西来触发剧本 运行 反对它。这使您可以将秘密保存在执行配置的中央盒子上,而不必将它们分发到您正在部署的每个实例。
对于 Ansible Tower,这是使用 callbacks 完成的,您将需要设置作业模板,然后让您的用户数据脚本卷曲 Tower 以触发配置 运行。您可以将用户数据脚本更改为如下内容:
template.tf:
resource "template_file" "init" {
template = "${file("${path.module}/init.tpl")}"
vars {
ansible_tower_host = "${var.ansible_tower_host}"
ansible_host_config_key = "${var.ansible_host_config_key}"
}
}
init.tpl:
#!/usr/bin/bash
curl \
-X POST
--data "host_config_key=${ansible_host_config_key}" \
http://{${ansible_tower_host}/v1/job_templates/1/callback/
host_config_key 乍一看似乎是个秘密,但它是一个共享密钥,可用于多个主机访问作业模板,Ansible Tower 仍然只会 运行 如果主机要么在作业模板的静态清单中定义,要么如果您使用的是动态清单,那么如果在该查找中找到主机。