Ansible un-vault 和模板文件

Ansible un-vault and template a file

我的本地计算机上有一个文件,我想上传到远程服务器,它包含我不想在我的 VCS 中公开的机密信息。它还有一些我需要在其中动态替换的文本(目前作为 Jinja2 占位符“{{}}”)。

如果我使用复制模块,那么当我上传文件时文件是未入库的,但显然占位符被替换了。

如果我使用模板模块,那么它不会取消保存文件,因此它以加密格式上传(并且不会替换占位符,因为它们被加密混淆了)。

如何将文件(使用 ansible)模板化和取消存储到远程服务器?

正如评论中已经提到的,您可以在变量中设置秘密并在提供期间将它们呈现到模板中,但是如果出于某种原因您想对整个模板保密,也可以采取一些变通方法那。

处理加密模板

作为解决方法,您可以在本地临时解密模板,并在推出后使用 local_action 模块删除解密的文件。 让我们假设您的加密模板在您的角色 templates 目录中作为 template.enc 驻留。

---

- name: Decrypt template
  local_action: "shell {{ view_encrypted_file_cmd }} {{ role_path }}/templates/template.enc > {{ role_path }}/templates/template"
  changed_when: False

- name: Deploy template
  template:
    src=templates/template
    dest=/home/user/file

- name: Remove decrypted template
  local_action: "file path={{ role_path }}/templates/template state=absent"
  changed_when: False

请注意changed_when: False。这对于 运行 对你的 ansible 角色进行幂等性测试很重要 - 否则每次你 运行 剧本都会发出更改信号。 在 group_vars/all.yml 中,您可以设置全局解密命令以供重用,例如 view_encrypted_file_cmd

group_vars/all.yml

---

view_encrypted_file_cmd: "ansible-vault --vault-password-file {{ lookup('env', 'ANSIBLE_VAULT_PASSWORD_FILE') }} view"

处理加密的静态文件

一种方式:作为模板

您可以将秘密静态文件的内容(例如私钥)设置为 ansible 中的变量,并将其提供为模板。

var.yml

---

my_private_key: |
  YOUR KEY
  asfdlsafkj
  asdlkfjasf

templates/private_key.j2

{{ private_key }}

tasks/main.yml

---

template: 
  src=templates/private_key.j2
  dest=/home/user/.ssh/id_rsa
  vars:
    private_key: "{{ my_private_key }}"

另一种方式:通过查找管道

另一种方法是使用 lookup 模块和 pipecopy 模块中设置 content 属性 - 你就是这样做的不需要额外的变量。

---

- copy:
    dest=/your/dest
    content=lookup('pipe', 'VAULT_PASSWORD_FILE=path/to/pass_file ansible-vault view path/to/file.enc')

不应再使用此内容,请参阅下面的 ...


在静态文件的情况下,还有另一种类似于的可能性。使用 copy 而不是 template 就不需要额外的文件了。

使用vars.yml:

存储在加密的保管库中vars.yml:

encrypted_content: |
  foo = {{ bar }}
  password = abcabc
  ...

任务代码:

- name: Save encrypted template
  copy: 
    content: "{{ encrypted_content }}"
    dest: /path/to/destination

使用单独的 YAML 文件

您也可以将加密的模板代码存储在另一个 YAML 文件中。这个有用,wenn vars.yml 不得加密。例如 vars/encrypted.yml 可能是:

encrypted_content: |
  foo = {{ bar }}
  password = abcabc
  ...

任务代码:

- name: Read encrypted variable file
  include_vars: encrypted.yml
  no_log: true

- name: Save encrypted template
  copy: 
    content: "{{ encrypted_content }}"
    dest: /path/to/destination

现在 Ansible 2.4 支持复制模块上的解密选项:http://docs.ansible.com/ansible/latest/copy_module.html#options

简而言之,使用copy模块和ansible-vault

这里是将名为 hello.vault 的本地加密文件复制到远程服务器上的 hello.txt 的完整示例。其明文内容为WORLD,加密密钥为1234.

  1. 创建您的库文件 hello.vault:
$ ansible-vault create hello.vault
New Vault password: 1234
Confirm New Vault password: 1234
## Then input your secret and exit the editor ##
WORLD

$ cat hello.vault
$ANSIBLE_VAULT;1.1;AES256
39653932393834613339393036613931393636663638636331323034653036326237373061666139
6434373635373065613135633866333733356532616635640a663739306639326535336637616138
39666462343737653030346463326464333937333161306561333062663164313162376564663262
3533393839633466300a666661303363383265613736376564623465613165656531366331366664
6436
  1. 创建您的密码文件,例如vault.key如下
1234
  1. 使用 copy 模块将保险库文件传输到 webserver 上的明文(在清单中定义)。
ansible webserver -i inventory --vault-password-file=vault.key \
        -m copy -a "src=hello.vault dest=hello.txt"

ansible webserver -i inventory -m command -a "cat hello.txt"
WORLD