title: How to decode a Base64 var to a binary file with Ansible module
body: <p>I am reading a base64 file from HashiCorp’s vault with the help of the <a href="https://docs.ansible.com/ansible/latest/plugins/lookup/hashi_vault.html?highlight=hashi_vault" rel="noreferrer">hashi_vault</a> module. Sample of code:</p>
  
  <pre><code>- name: Vault get b64.pfx file
    set_fact:
        b64_pfx: "{{ lookup('hashi_vault',
                      'secret={{ path_pfx }} token={{ token }} url={{ url }} cacert={{ role_path}}/files/CA.pem')}}"
  </code></pre>
  
  <p>Then as a next step I need to decode this base64 var to a binary format and store it in in a file. I am currently using <a href="https://docs.ansible.com/ansible/latest/modules/shell_module.html" rel="noreferrer">shell</a> module to do the work. Sample of code:</p>
  
  <pre><code>- name: Decode Base64 file to binary
    shell: "echo {{ b64_pfx }} | base64 --decode &gt; {{ pfxFile }}"
    delegate_to: localhost
  </code></pre>
  
  <p>I was looking online for possible solutions e.g. (<a href="https://github.com/ansible/ansible/issues/20150" rel="noreferrer">
  Copy module with base64-encoded binary file adds extra character</a> and <a href="https://stackoverflow.com/questions/22773294/how-to-upload-encrypted-file-using-ansible-vault">How to upload encrypted file using ansible vault?</a>).</p>
  
  <p>But the only working solution that I can found is using the shell module. Since this is an old problem is there any workaround on this?</p>
  
  <p><strong>Update:</strong></p>
  
  <p>Do not use <strong>Python 2.7</strong> as there seems to be a bug on the <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#id8" rel="noreferrer"><strong>b64decode</strong></a> filter (sample below):</p>
  
  <pre><code>&lt;localhost&gt; ESTABLISH LOCAL CONNECTION FOR USER: root
  &lt;localhost&gt; EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" &amp;&amp; echo ansible-tmp-1573819503.84-50241917358990="` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" ) &amp;&amp; sleep 0'
  Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
  &lt;localhost&gt; PUT /tmp/ansible-local-18pweKi1/tmpjQGOz8 TO /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py
  &lt;localhost&gt; EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819503.84-50241917358990/ /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py &amp;&amp; sleep 0'
  &lt;localhost&gt; EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py &amp;&amp; sleep 0'
  &lt;localhost&gt; EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819503.84-50241917358990/ &gt; /dev/null 2&gt;&amp;1 &amp;&amp; sleep 0'
  changed: [hostname -&gt; localhost] =&gt; {
      "changed": true,
      "cmd": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
      "delta": "0:00:00.126279",
      "end": "2019-11-15 13:05:04.227933",
      "invocation": {
          "module_args": {
              "_raw_params": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
              "_uses_shell": true,
              "argv": null,
              "chdir": null,
              "creates": null,
              "executable": null,
              "removes": null,
              "stdin": null,
              "stdin_add_newline": true,
              "strip_empty_ends": true,
              "warn": true
          }
      },
      "rc": 0,
      "start": "2019-11-15 13:05:04.101654",
      "stderr": "",
      "stderr_lines": [],
      "stdout": "4a71465d449a0337329e76106569e39d6aaa5ef0  /tmp/binary_file\nead5cb632f3ee80ce129ef5fe02396686c2761e0  /tmp/binary_file.ansible",
      "stdout_lines": [
          "4a71465d449a0337329e76106569e39d6aaa5ef0  /tmp/binary_file",
          "ead5cb632f3ee80ce129ef5fe02396686c2761e0  /tmp/binary_file.ansible"
      ]
  }
  </code></pre>
  
  <p><strong>Solution:</strong> use <strong>Python 3</strong> with <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#id8" rel="noreferrer"><strong>b64decode</strong></a> filter (sample below):</p>
  
  <pre><code>&lt;localhost&gt; ESTABLISH LOCAL CONNECTION FOR USER: root
  &lt;localhost&gt; EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" &amp;&amp; echo ansible-tmp-1573819490.9511943-224511378311227="` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" ) &amp;&amp; sleep 0'
  Using module file /usr/local/lib/python3.6/site-packages/ansible/modules/commands/command.py
  &lt;localhost&gt; PUT /tmp/ansible-local-18epk_0jsv/tmp4t3gnm7u TO /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py
  &lt;localhost&gt; EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819490.9511943-224511378311227/ /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py &amp;&amp; sleep 0'
  &lt;localhost&gt; EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py &amp;&amp; sleep 0'
  &lt;localhost&gt; EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819490.9511943-224511378311227/ &gt; /dev/null 2&gt;&amp;1 &amp;&amp; sleep 0'
  changed: [hostname -&gt; localhost] =&gt; {
      "changed": true,
      "cmd": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
      "delta": "0:00:00.135427",
      "end": "2019-11-15 13:04:51.239969",
      "invocation": {
          "module_args": {
              "_raw_params": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
              "_uses_shell": true,
              "argv": null,
              "chdir": null,
              "creates": null,
              "executable": null,
              "removes": null,
              "stdin": null,
              "stdin_add_newline": true,
              "strip_empty_ends": true,
              "warn": true
          }
      },
      "rc": 0,
      "start": "2019-11-15 13:04:51.104542",
      "stderr": "",
      "stderr_lines": [],
      "stdout": "4a71465d449a0337329e76106569e39d6aaa5ef0  /tmp/binary_file\n4a71465d449a0337329e76106569e39d6aaa5ef0  /tmp/binary_file.ansible",
      "stdout_lines": [
          "4a71465d449a0337329e76106569e39d6aaa5ef0  /tmp/binary_file",
          "4a71465d449a0337329e76106569e39d6aaa5ef0  /tmp/binary_file.ansible"
      ]
  }
  </code></pre>
  
  <p>Since <strong><a href="https://www.python.org/doc/sunset-python-2/" rel="noreferrer">Python 2</a></strong> is reaching the end of life in (<strong>January 1, 2020</strong>) there is no point of raising the bug.</p>