是否可以从剧本中的动态清单中解析加密的 Ansible 保险库值?
Is it possible to parse encrypted Ansible vault values from a dynamic inventory in a playbook?
我有一个动态清单设置,它从 MySQL 数据库中提取主机及其变量。动态库存本身运行良好。
库存中的一些变量是敏感的,所以我不想将它们存储为纯文本。
因此,作为测试,我使用以下方法加密了一个值:
ansible-vault encrypt_string 'foobar'
结果是:
!vault |
$ANSIBLE_VAULT;1.1;AES256
39653264643032353830336333356665663638353839356162386462303338363661333564633737
3737356131303563626564376634313865613433346438630a343534363066393431633366393863
30333636386536333166363533373239303864633830653566316663616432633336393936656233
6633666134306530380a356664333834353265663563656162396435353030663833623166363466
6436
Encryption successful
我决定将加密值存储为 MySQL 中的变量。为免疑义,经过一番测试,可以将加密后的字符串归一化为:
$ANSIBLE_VAULT;1.1;AES256
363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463
您可以使用简单的剧本测试此格式:
---
- hosts: all
gather_facts: no
vars:
final_var: !vault "$ANSIBLE_VAULT;1.1;AES256\n363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463"
tasks:
- name: Display variable
debug:
msg: "{{ final_var }}"
执行剧本时,观察到以下输出:
ok: [target] => {
"msg": "foobar"
}
尝试从清单中获取变量 (my_secret
) 而不是直接在文件中引用它时会出现困难。
---
- hosts: all
gather_facts: no
vars:
final_var: !vault "{{ my_secret }}"
tasks:
- name: Display variable
debug:
msg: "{{ final_var }}"
这导致:
fatal: [target]: FAILED! => {"msg": "input is not vault encrypted data"}
现在,虽然我已经在 MySQL 中多次谈到了存储在动态库存中的价值,但如果我们从等式中删除它,我们可以获得类似的行为。
---
- hosts: all
gather_facts: no
vars:
secret: "$ANSIBLE_VAULT;1.1;AES256\n363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463"
final_var: !vault "{{ secret }}"
tasks:
- name: Display variable
debug:
msg: "{{ final_var }}"
现在这与工作示例几乎相同,但加密的字符串不是内联写入的,而是来自另一个变量。
这会导致相同的错误:
fatal: [target]: FAILED! => {"msg": "input is not vault encrypted data"}
这可能表明更广泛的问题是 Ansible 出于某种原因无法解析存储为变量的加密数据。也许在解析 YAML 时,它实际上是在尝试解密 "{{ my_secret }}"
而不是 $ANSIBLE_VAULT;1.1;AES256 ...
.
哪一种说得通,但我想 运行 过去问问你们是否有办法解决这个问题,或者你们是否推荐完全不同的方法。谢谢。
您最好将变量放入加密文件中。将加密文件存储在 MySQL 而不是加密变量中。如果您已经 " 设置了动态清单,可以从 MySQL 数据库中提取主机及其变量",那么修改设置应该没有问题。从数据库中拉取加密文件并将它们存储在 host_vars (and/or group_vars, play vars, role vars ...) 而不是将加密变量存储在 inventory (and/or 在剧本,角色,......的代码中。这样,在代码中,你就不用关心变量是否加密了。
例如
shell> tree host_vars/
host_vars/
├── test_01
│ └── final_var.yml
├── test_02
│ └── final_var.yml
└── test_03
└── final_var.yml
shell> cat host_vars/test_01/final_var.yml
final_var: final_var for test_01
shell> cat host_vars/test_02/final_var.yml
final_var: final_var for test_02
shell> cat host_vars/test_03/final_var.yml
final_var: final_var for test_03
加密文件。例如
shell> ansible-vault encrypt host_vars/test_01/final_var.yml
Encryption successful
shell> cat host_vars/test_01/final_var.yml
$ANSIBLE_VAULT;1.1;AES256
37363965336263366466336236336466323033353763656262633836323062626135613834396435
3665356363396132356131663336396138663962646434330a346433353039383864333638633462
35623034363338356362346133303262393233346439363264353036386337356236336135626434
6533333864623132330a346566656630376439643533373263303338313063373239343463333431
62353230323336383263376335613635616339383934313164323938363066616136373036326461
3538613937663530326364376335343438366139366639303230
然后是下面的剧本
- hosts: test_01,test_02,test_03
tasks:
- debug:
msg: "{{ inventory_hostname }}: {{ final_var }}"
给出(删节)
"msg": "test_02: final_var for test_02"
"msg": "test_01: final_var for test_01"
"msg": "test_03: final_var for test_03"
我有一个动态清单设置,它从 MySQL 数据库中提取主机及其变量。动态库存本身运行良好。
库存中的一些变量是敏感的,所以我不想将它们存储为纯文本。
因此,作为测试,我使用以下方法加密了一个值:
ansible-vault encrypt_string 'foobar'
结果是:
!vault |
$ANSIBLE_VAULT;1.1;AES256
39653264643032353830336333356665663638353839356162386462303338363661333564633737
3737356131303563626564376634313865613433346438630a343534363066393431633366393863
30333636386536333166363533373239303864633830653566316663616432633336393936656233
6633666134306530380a356664333834353265663563656162396435353030663833623166363466
6436
Encryption successful
我决定将加密值存储为 MySQL 中的变量。为免疑义,经过一番测试,可以将加密后的字符串归一化为:
$ANSIBLE_VAULT;1.1;AES256
363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463
您可以使用简单的剧本测试此格式:
---
- hosts: all
gather_facts: no
vars:
final_var: !vault "$ANSIBLE_VAULT;1.1;AES256\n363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463"
tasks:
- name: Display variable
debug:
msg: "{{ final_var }}"
执行剧本时,观察到以下输出:
ok: [target] => {
"msg": "foobar"
}
尝试从清单中获取变量 (my_secret
) 而不是直接在文件中引用它时会出现困难。
---
- hosts: all
gather_facts: no
vars:
final_var: !vault "{{ my_secret }}"
tasks:
- name: Display variable
debug:
msg: "{{ final_var }}"
这导致:
fatal: [target]: FAILED! => {"msg": "input is not vault encrypted data"}
现在,虽然我已经在 MySQL 中多次谈到了存储在动态库存中的价值,但如果我们从等式中删除它,我们可以获得类似的行为。
---
- hosts: all
gather_facts: no
vars:
secret: "$ANSIBLE_VAULT;1.1;AES256\n363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463"
final_var: !vault "{{ secret }}"
tasks:
- name: Display variable
debug:
msg: "{{ final_var }}"
现在这与工作示例几乎相同,但加密的字符串不是内联写入的,而是来自另一个变量。
这会导致相同的错误:
fatal: [target]: FAILED! => {"msg": "input is not vault encrypted data"}
这可能表明更广泛的问题是 Ansible 出于某种原因无法解析存储为变量的加密数据。也许在解析 YAML 时,它实际上是在尝试解密 "{{ my_secret }}"
而不是 $ANSIBLE_VAULT;1.1;AES256 ...
.
哪一种说得通,但我想 运行 过去问问你们是否有办法解决这个问题,或者你们是否推荐完全不同的方法。谢谢。
您最好将变量放入加密文件中。将加密文件存储在 MySQL 而不是加密变量中。如果您已经 " 设置了动态清单,可以从 MySQL 数据库中提取主机及其变量",那么修改设置应该没有问题。从数据库中拉取加密文件并将它们存储在 host_vars (and/or group_vars, play vars, role vars ...) 而不是将加密变量存储在 inventory (and/or 在剧本,角色,......的代码中。这样,在代码中,你就不用关心变量是否加密了。
例如
shell> tree host_vars/
host_vars/
├── test_01
│ └── final_var.yml
├── test_02
│ └── final_var.yml
└── test_03
└── final_var.yml
shell> cat host_vars/test_01/final_var.yml
final_var: final_var for test_01
shell> cat host_vars/test_02/final_var.yml
final_var: final_var for test_02
shell> cat host_vars/test_03/final_var.yml
final_var: final_var for test_03
加密文件。例如
shell> ansible-vault encrypt host_vars/test_01/final_var.yml
Encryption successful
shell> cat host_vars/test_01/final_var.yml
$ANSIBLE_VAULT;1.1;AES256
37363965336263366466336236336466323033353763656262633836323062626135613834396435
3665356363396132356131663336396138663962646434330a346433353039383864333638633462
35623034363338356362346133303262393233346439363264353036386337356236336135626434
6533333864623132330a346566656630376439643533373263303338313063373239343463333431
62353230323336383263376335613635616339383934313164323938363066616136373036326461
3538613937663530326364376335343438366139366639303230
然后是下面的剧本
- hosts: test_01,test_02,test_03
tasks:
- debug:
msg: "{{ inventory_hostname }}: {{ final_var }}"
给出(删节)
"msg": "test_02: final_var for test_02"
"msg": "test_01: final_var for test_01"
"msg": "test_03: final_var for test_03"