如何使用ansible vault上传加密文件?

时间:2014-03-31 22:17:29

标签: ansible ansible-playbook

是否有人使用ansible-vault解密和上传文件。

我正在考虑在源代码管理中加密我的ssl证书。

以下似乎应该有效。

---
  - name: upload ssl crt
    copy: src=../../vault/encrypted.crt dest=/usr/local/etc/ssl/domain.crt

10 个答案:

答案 0 :(得分:39)

复制模块现在可以从Ansible 2.1.x开始无缝地执行此操作。只需使用Ansible Vault加密文件,然后在文件上发出复制任务。

(供参考,以下是添加此内容的功能:https://github.com/ansible/ansible/pull/15417

答案 1 :(得分:33)

那不行。您将获得的encrypted.crt(使用Ansible Vault)按字面意思上传为domain.crt

你需要做的是让你的剧本成为" Vault"并添加包含证书内容的变量。像这样:

---
- name: My cool playbook
  hosts: all

  vars:
    mycert: |
       aasfasdfasfas
       sdafasdfasdfasdfsa
       asfasfasfddasfasdfa


  tasks:
    # Apparently this causes new lines on newer ansible versions
    # - name: Put uncrypted cert in a file
    #   shell: echo '{{ mycert }}' > mydecrypted.pem

    # You can try this as per
    # https://github.com/ansible/ansible/issues/9172
    - copy:
      content: "{{ mycert }}"
      dest: /mydecrypted.pem

    - name: Upload Cert
      copy: src=/home/ubuntu/mydecrypted.pem dest=/home/ubuntu/mydecrypteddest.pem

    - name: Delete decrypted cert
      file: path=/home/ubuntu/mydecrypted.pem state=absent

您也可以选择使用Ansible Vault将mycert变量放在单独的变量文件中。

  

副本模块已在Ansible 2.1中更新。来自更改日志:   "复制模块现在可以透明地使用存储文件作为源,如果   提供了保险箱密码,它将动态解密和复制。"   在这里注意到,因为有些人不可避免地会过去   接受了答案。 - JK Laiho

答案 2 :(得分:21)

在复制模块中有a feature request本地支持此功能。但在实施之前,这里是解决方法(类似于@ dave1010'答案,但为了完整性重复公共部分):

创建一个用ansible vault加密的secrets.yml文件,其中包含您的秘密,例如:

---
private_ssl_key: |
  -----BEGIN PRIVATE KEY-----
  abcabcabcabcabcabcabcabcabc
  -----END PRIVATE KEY-----

private_crt: |
  -----BEGIN CERTIFICATE-----
  abcabcabcabcabcabcabcabcabc
  -----END CERTIFICATE-----

在你的剧本中,加上:

vars_files:
  - secrets.yml

然后你可以在任务中使用变量:

- name: Copy private kay
  copy: content="{{ private_ssl_key }}" dest=/some/path/ssl.key

但是,如果您尝试复制的文件是二进制文件,则不起作用。在这种情况下,您需要首先使用base64编码内容:

cat your_secret_file | /usr/bin/base64

然后将base64编码的值放在secrets.yml文件中,例如:

crt_b64: |
  ndQbmFQSmxrK2IwOFZnZHNJa0sKICAxdDhFRUdmVzhMM...

然后您可以分两步创建远程文件:

- name: Copy certificate (base64 encoded)
  copy: content="{{ crt_b64 }}" dest=/some/path/cert.b64

- name: Decode certificate
  shell: "base64 -d /some/path/cert.b64 > /some/path/cert.txt"
  args:
    creates: /some/path/cert.txt

请注意,您可以删除远程主机上的临时cert.b64文件。但是重新运行该剧本将重新创建它,而不是跳过这个任务。所以,我宁愿把它留在那里。

<强>更新: 此功能已在Ansible 2.1中实施。

  

复制模块现在可以透明地使用存储文件作为源,如果   提供了保险箱密码,它将动态解密和复制。

答案 3 :(得分:15)

我使用了模板和vars_file来执行此操作:

在您的顶级剧本中:

vars_files:
  - secretvars.yml

在任务中:

- name: Private ssl key
  template: src=etc-ssl-private-site.key dest=/etc/ssl/private/site.key

在模板(etc-ssl-private-site.key)中,您只需要变量:

{{ private_ssl_key }}

在加密的secretvars.yml中(使用ansible-vault加密):

---

private_ssl_key: |
  -----BEGIN PRIVATE KEY-----
  abcabcabcabcabcabcabcabcabc
  -----END PRIVATE KEY-----

答案 4 :(得分:13)

更新:自 2016年4月以来,我的Github PR已合并,可在Ansible 2.1及更高版本中使用。在公关合并之前,以下是临时解决方案。

我想做同样的事情,我创建了一个动作插件来实现这个功能。这可以通过github获得。该插件正是ansible随附的复制动作插件,但支持Vault解密。

你可以像这样使用它:

- name: Copy Some Secret File
  copyv: src="secret.txt" dest="/tmp/"

如果secret.txt已加密(并提供了保管库密码),则会对其进行解密和复制。

答案 5 :(得分:11)

我认为,你有一个更简单的方法。

如果您以某种格式在某个文件中使用证书+密钥(例如pkcs12或只是连接),则可以使用通用openssl(或gpg或其他)加密。它看起来像这样:

openssl enc -e -aes-256-ctr -in original.pem -out encrypted.aes -k <pass-vault>

之后,您只需将encrypted.aes复制到远程主机并就地解密:

- name: copy encrypted cert and key
  copy: src=encrypted.aes dest=/root/ansible-files/ mode=0600

- name: decrypt cert and key
  command: openssl enc -aes-256-ctr -d -in /root/ansible-files/encrypted.aes -out <dest> -k {{ pass-vault }}

如果您有pem或der格式的单独密钥文件,则可以使用

openssl rsa -in original.pem -out encrypted.pem -aes256 -passout pass:<pass-vault>

答案 6 :(得分:3)

直到&#39;复制&#39;模块已扩展为自动解密文件库文件,这是一个简单的解决方法:

当stdout不是tty时,ansible-vault view <file>会在不调用寻呼机的情况下将明文打印到stdout。

与管道相结合&#39;查找,此行为可与保险库密码文件一起使用,以提供给复制模块的内容&#39;选项:

- name: "install host key"
  copy: content="{{ lookup('pipe', 'ansible-vault view ' + src_key_file) }}"
        dest={{ dest_key_file }}

答案 7 :(得分:2)

Ansible 2.5将参数decrypt添加到了copy模块中。

例如,如果您使用以下方式加密文件:

$ ansible-vault encrypt vault/encrypted.crt

现在您可以使用复制+ 解密

---
  - name: upload ssl crt
    copy:
      src: path/to/encrypted-with-vault.crt
      dest: /usr/local/etc/ssl/domain.crt
      decrypt: yes
      mode: 0600

答案 8 :(得分:1)

您还可以使用local_action临时解密您的文件作为剧本的一部分:

- name: "temporairly decrypt the twpol.enc"
  sudo: False
  local_action: shell ansible-vault view --vault-password-file {{ lookup('env', 'ANSIBLE_VAULT_PASS_FILE') }} ./roles/copykey/files/key.enc > ./roles/copykey/files/key.txt 

- name: "copy the key to the target machine."
  copy: src=key.txt dest=/tmp

- name: "remove decrypted key.txt file"
  sudo: False
  local_action: rm ./roles/copykey/files/key.txt

答案 9 :(得分:-1)

上面@utapyngo建议的copy: content= {{ private_ssl_key }}"方法的

+1。

如果您将密钥分发作为一个角色,而不仅仅是在一个剧本中(为什么不是,因为密钥分发是您稍后可能需要的),请记住以下内容:

  • 您只为您的vars获取一个文件,因此所有密钥(假设您有基于主机或其他的不同捆绑包)必须在<role>/vars/main.yml
  • 中一起使用
  • <role>/vars/main.yml中的变量是可引用的,没有任何路径(非常好!)
  • 请记住,只要您想要变量的内容,就需要引用AND curlies,即"{{ your_variable_name }}"
  • 如果要为每个任务复制多个文件,则需要with_items:循环
  • 如果你想让你的敏感数据在屏幕上的第一个位置加密,你会遇到很多麻烦,一个巧妙的诀窍就是在字典里找到你的关键变量;这样,在你的with_items循环中,你正在向它提供字典键而不是变量本身的内容。