How to upload encrypted file using ansible vault?

2019-02-03 00:41发布

Does anyone have an example of decrypting and uploading a file using ansible-vault.

I am thinking about keeping my ssl certificates encrypted in source control.

It seems something like the following should work.

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

10条回答
冷血范
2楼-- · 2019-02-03 01:12

Until the 'copy' module has been extended to automatically decrypt vault files, here's a simple workaround:

When stdout is not a tty, ansible-vault view <file> prints cleartext to stdout without invoking a pager.

In combination with a 'pipe' lookup, this behavior can be used with a vault password file to feed into the copy module's 'content' option:

- name: "install host key"
  copy: content="{{ lookup('pipe', 'ansible-vault view ' + src_key_file) }}"
        dest={{ dest_key_file }}
查看更多
太酷不给撩
3楼-- · 2019-02-03 01:15

There is a feature request to support this natively in the copy module. But until that is implemented, here is the workaround (similar to @dave1010's answer, but repeating common parts for completeness):

Create a secrets.yml file encrypted with ansible vault which contains your secrets, for example:

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

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

In your playbook, include it:

vars_files:
  - secrets.yml

Then you can use the variables in tasks:

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

However, this doesn't work if the file that you are trying to copy is a binary file. In that case, you need to first encode the content with base64:

cat your_secret_file | /usr/bin/base64

Then put the base64 encoded value in your secrets.yml file, e.g.:


crt_b64: |
  ndQbmFQSmxrK2IwOFZnZHNJa0sKICAxdDhFRUdmVzhMM...

Then you can create the remote file in two steps:

- 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

Note that you could delete the temporary cert.b64 file on the remote host. But then re-running the playbook will re-create it instead of skipping this task. So, I prefer to leave it there.

UPDATE: This feature has been implemented in Ansible 2.1.

copy module can now transparently use a vaulted file as source, if vault passwords were provided it will decrypt and copy on the fly.

查看更多
我想做一个坏孩纸
4楼-- · 2019-02-03 01:18

That's not going to work. What you will get is your encrypted.crt (with Ansible Vault) uploaded literally as domain.crt

What you need to do is make your playbook part of a "Vault" and add a variable that contains your certificate content. Something like this:

---
- 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

You can choose to put your mycert variable in a separate variable file using Ansible Vault too.

The copy module has been updated in Ansible 2.1. From the changelog: "copy module can now transparently use a vaulted file as source, if vault passwords were provided it will decrypt and copy on the fly." Noting it here, since some people will inevitably not look past the accepted answer. – JK Laiho

查看更多
虎瘦雄心在
5楼-- · 2019-02-03 01:19

I think, you have a simpler way to do this.

If you use certificate+key in one file in some format (like pkcs12 or just concatenated), you can use generic openssl (or gpg, or something else) encryption. It will look like this:

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

After that you can just copy encrypted.aes to remote host and decrypt it in-place:

- 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 }}

If you have separate key file in pem or der format, you can use

openssl rsa -in original.pem -out encrypted.pem -aes256 -passout pass:<pass-vault>
查看更多
Evening l夕情丶
6楼-- · 2019-02-03 01:22

You can also use local_action to temporairly decrypt your file as part of the playbook:

- 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
查看更多
小情绪 Triste *
7楼-- · 2019-02-03 01:24

Update: As of April 2016 my Github PR has been merged and is available in Ansible 2.1 and later. The below was an interim solution until the PR was merged.

Wanting to do the same thing I created an action plugin to implement the feature. This is available via github. The plugin is exactly the copy action plugin as shipped with ansible, but with support for vault decryption.

You can use it like this:

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

if secret.txt is encrypted (and the vault password is supplied) then it will be decrypted and copied.

查看更多
登录 后发表回答