如何使用 Ansible 模块将 Base64 var 解码为二进制文件

How to decode a Base64 var to a binary file with Ansible module

我正在 hashi_vault 模块的帮助下从 HashiCorp 的保险库中读取一个 base64 文件。代码示例:

- 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')}}"

下一步我需要将这个 base64 var 解码为二进制格式并将其存储在一个文件中。我目前正在使用 shell 模块来完成这项工作。代码示例:

- name: Decode Base64 file to binary
  shell: "echo {{ b64_pfx }} | base64 --decode > {{ pfxFile }}"
  delegate_to: localhost

我在网上寻找可能的解决方案,例如( 带有 base64 编码二进制文件的复制模块会添加额外的字符 How to upload encrypted file using ansible vault?).

但我能找到的唯一可行的解​​决方案是使用 shell 模块。由于这是一个老问题,是否有任何解决方法?

更新:

不要使用 Python 2.7 因为 b64decode 过滤器(下面的示例)似乎有一个错误:

<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" && echo ansible-tmp-1573819503.84-50241917358990="` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
<localhost> PUT /tmp/ansible-local-18pweKi1/tmpjQGOz8 TO /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py
<localhost> EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819503.84-50241917358990/ /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819503.84-50241917358990/ > /dev/null 2>&1 && sleep 0'
changed: [hostname -> localhost] => {
    "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"
    ]
}

解决方案: 使用 Python 3b64decode 过滤器(示例如下):

<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" && echo ansible-tmp-1573819490.9511943-224511378311227="` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" ) && sleep 0'
Using module file /usr/local/lib/python3.6/site-packages/ansible/modules/commands/command.py
<localhost> PUT /tmp/ansible-local-18epk_0jsv/tmp4t3gnm7u TO /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py
<localhost> EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819490.9511943-224511378311227/ /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819490.9511943-224511378311227/ > /dev/null 2>&1 && sleep 0'
changed: [hostname -> localhost] => {
    "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"
    ]
}

由于Python 2在(2020年1月1日)生命将尽,所以没有必要再养错误。

至少在 ansible 2.9 上使用 b64decode filter 做你想做的事:

- copy:
    dest: '{{ pfxFile }}'
    content: '{{ b64_pfx | b64decode }}'
  delegate_to: localhost

我确认它只写入指定的字节(没有尾随空格)并且是二进制安全的。

如果您尝试过该行为,但它对您不起作用,请更新您的问题以说明这一点并包括您正在使用的 ansible 版本。我还认为您链接到的错误已得到修复,因为我在 ansible 2.9 上尝试了他们的确切案例并且它做了正确的事情:

- hosts: localhost
  connection: local
  gather_facts: no
  tasks:
  - set_fact:
      string_in_base64: 'sxZARwIVokeqOMGPygc1S20CaGPiKDRGRzg0oSVGmCF2oXHua+9fVhriUQRd8vkmvpHoBmSsI6Y='
  - copy:
      dest: binary_file.ansible
      content: '{{ string_in_base64 | b64decode }}'
  - shell: |
      echo '{{ string_in_base64 }}' | base64 --decode > binary_file
      shasum -a 1 binary_file
      shasum -a 1 binary_file.ansible
{
  "changed": true,
  "cmd": "echo 'sxZARwIVokeqOMGPygc1S20CaGPiKDRGRzg0oSVGmCF2oXHua+9fVhriUQRd8vkmvpHoBmSsI6Y=' | base64 --decode > binary_file\nshasum -a 1 binary_file\nshasum -a 1 binary_file.ansible\n",
  "delta": "0:00:00.162251",
  "end": "2019-11-13 13:10:56.683186",
  "rc": 0,
  "start": "2019-11-13 13:10:56.520935",
  "stderr": "",
  "stderr_lines": [],
  "stdout": "7e88df04cf47019ae22e9c658b62c26b706c6ea5  binary_file\n7e88df04cf47019ae22e9c658b62c26b706c6ea5  binary_file.ansible",
  "stdout_lines": [
    "7e88df04cf47019ae22e9c658b62c26b706c6ea5  binary_file",
    "7e88df04cf47019ae22e9c658b62c26b706c6ea5  binary_file.ansible"
  ]
}