1. json 相关

1.1. ​from_json​ 过滤器

参考链接:ansible.builtin.from_json 过滤器 – 将 JSON 字符串转换为变量结构 — Ansible 社区文档

可以将 JSON 字符串解析为 Python 中的 字典或列表,以下是一个示例

- hosts: home
  become: yes
  become_method: sudo
  tasks:
    - name: Get docker config
      shell: "cat /etc/docker/daemon.json"
      register: docker_config_raw
      changed_when: false
      failed_when: false

    - name: Cat config content and type
      debug:
        msg:
          docker_config_raw.stdout 的值为: {{ docker_config_raw.stdout }}
          docker_config_raw.stdout 的类型为: {{ docker_config_raw.stdout | type_debug }}

    - name: Parse JSON config
      set_fact:
        docker_config: "{{ docker_config_raw.stdout | from_json | default({}) }}"
      when: docker_config_raw.stdout | length > 0

    - name: Cat config content and type
      debug:
        msg:
          docker_config 的值为: {{ docker_config }}
          docker_config 的类型为: {{ docker_config | type_debug }}

执行输出如下:

PLAY [home] ***********************************************************************************************************

TASK [get docker config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat config content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config_raw.stdout 的值为: {\n    \"data-root\": \"/data/dockerData\",\n    \"default-runtime\": \"runc\",\n    \"insecure-registries\": [\n        \"harbor.ctnrs.com\",\n        \"192.168.2.100:23456\"\n    ],\n    \"log-driver\": \"json-file\",\n    \"log-opts\": {\n        \"max-file\": \"1\",\n        \"max-size\": \"200m\"\n    }\n} docker_config_raw.stdout 的类型为: AnsibleUnsafeText"                                                                                                                                                                                                           
}
ok: [lenovo] => {
    "msg": "docker_config_raw.stdout 的值为: {\n    \"insecure-registries\": [\n        \"harbor.ctnrs.com\",\n        \"192.168.2.100:23456\"\n    ]\n} docker_config_raw.stdout 的类型为: AnsibleUnsafeText"
}

TASK [Parse JSON config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat config content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config 的值为: {'data-root': '/data/dockerData', 'default-runtime': 'runc', 'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456'], 'log-driver': 'json-file', 'log-opts': {'max-file': '1', 'max-size': '200m'}} docker_config 的类型为: dict"
}
ok: [lenovo] => {
    "msg": "docker_config 的值为: {'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456']} docker_config 的类型为: dict"
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

从上面输出可以看出,直接通过 shell 显示读出来的变量类型为 AnsibleUnsafeText​,经过 from_json​ 转换后的变量类型为:dict​,说明已经成功转换为字典类型

1.2. ​to_nice_json​ 过滤器

参考链接: 将变量转换为‘格式良好’的 JSON 字符串 — Ansible 社区文档

to_nice_json 过滤器可以将 Python 对象格式化为美观的 JSON 字符串,示例:

- hosts: home
  become: yes
  become_method: sudo
  tasks:
    - name: get docker config
      shell: "cat /etc/docker/daemon.json"
      register: docker_config_raw
      changed_when: false
      failed_when: false

    - name: Parse JSON config
      set_fact:
        docker_config: "{{ docker_config_raw.stdout | from_json | default({}) }}"
      when: docker_config_raw.stdout | length > 0

    - name: Cat config content and type
      debug:
        msg:
          docker_config 的值为: {{ docker_config }}
          docker_config 的类型为: {{ docker_config | type_debug }}

    - name: Decode JSON config
      set_fact:
        docker_config: "{{ docker_config | to_nice_json }}"
      when: docker_config | length > 0

    - name: Cat config content and type
      debug:
        msg:
          docker_config 的值为: {{ docker_config }}
          docker_config 的类型为: {{ docker_config | type_debug }}

执行输出为:

PLAY [home] ***********************************************************************************************************

TASK [get docker config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Parse JSON config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat config content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config 的值为: {'data-root': '/data/dockerData', 'default-runtime': 'runc', 'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456'], 'log-driver': 'json-file', 'log-opts': {'max-file': '1', 'max-size': '200m'}} docker_config 的类型为: dict"
}
ok: [lenovo] => {
    "msg": "docker_config 的值为: {'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456']} docker_config 的类型为: dict"
}

TASK [Decode JSON config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat config content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config 的值为: {\n    \"data-root\": \"/data/dockerData\",\n    \"default-runtime\": \"runc\",\n    \"insecure-registries\": [\n        \"harbor.ctnrs.com\",\n        \"192.168.2.100:23456\"\n    ],\n    \"log-driver\": \"json-file\",\n    \"log-opts\": {\n        \"max-file\": \"1\",\n        \"max-size\": \"200m\"\n    }\n} docker_config 的类型为: NativeJinjaUnsafeText"                                                                                                                                                                                                                             
}
ok: [lenovo] => {
    "msg": "docker_config 的值为: {\n    \"insecure-registries\": [\n        \"harbor.ctnrs.com\",\n        \"192.168.2.100:23456\"\n    ]\n} docker_config 的类型为: NativeJinjaUnsafeText"
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

也可以添加参数,如 {{ var | to_nice_json(indent=2) }}​,

  • ​indent​ 为缩进级别,默认为 4

1.3. ​default​ 过滤器

default 过滤器可以在 当变量为 undefined 或空时提供默认值,防止 Undefined variable​ 错误

示例:

- hosts: home
  become: yes
  become_method: sudo
  tasks:
    - name: Set default
      set_fact:
        docker_config: "{{ docker_config | default({'ip':'192.168.2.100'}) }}"

    - name: Cat config content and type
      debug:
        msg:
          docker_config 的值为: {{ docker_config }}
          docker_config 的类型为: {{ docker_config | type_debug }}

执行输出:

PLAY [home] ***********************************************************************************************************

TASK [Set default] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat config content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config 的值为: {'ip': '192.168.2.100'} docker_config 的类型为: dict"
}
ok: [lenovo] => {
    "msg": "docker_config 的值为: {'ip': '192.168.2.100'} docker_config 的类型为: dict"
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

1.4. slurp​ 模块

参考链接:ansible.builtin.slurp module – Slurps a file from remote nodes — Ansible Community Documentation

​ansible.builtin.slurp​ 模块用于从远程节点读取文件内容,并以 Base64 编码的形式返回到控制端内存中。它的行为类似 fetch​ 模块,但不会将文件保存到本地磁盘,而是直接在内存中处理,非常适合读取小型配置文件、状态文件等。

关键特性

  • 支持 POSIX 和 Windows 目标系统。

  • 仅支持读取​文件​,不能读取目录。

  • 返回值包含 ​content​(Base64 编码内容)、​encoding​(编码类型)、​source​(文件路径)。

  • 可在 check_mode 下运行,不会修改目标系统。

  • 注意:由于是内存中存储 Base64 数据,内存占用约为原文件的两倍。

示例:

- hosts: home
  become: yes
  become_method: sudo
  tasks:
    - name: get docker config
      slurp:
        src: "/etc/docker/daemon.json"
      register: docker_file
      ignore_errors: yes

    - name: Cat docker_file content and type
      debug:
        msg:
          docker_file 的值为: {{ docker_file }}
          docker_file 的类型为: {{ docker_file | type_debug }}

执行输出:

PLAY [home] ***********************************************************************************************************

TASK [get docker config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat docker_file content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_file 的值为: {'content': 'ewogICAgImRhdGEtcm9vdCI6ICIvZGF0YS9kb2NrZXJEYXRhIiwKICAgICJkZWZhdWx0LXJ1bnRpbWUiOiAicnVuYyIsCiAgICAiaW5zZWN1cmUtcmVnaXN0cmllcyI6IFsKICAgICAgICAiaGFyYm9yLmN0bnJzLmNvbSIsCiAgICAgICAgIjE5Mi4xNjguMi4xMDA6MjM0NTYiCiAgICBdLAogICAgImxvZy1kcml2ZXIiOiAianNvbi1maWxlIiwKICAgICJsb2ctb3B0cyI6IHsKICAgICAgICAibWF4LWZpbGUiOiAiMSIsCiAgICAgICAgIm1heC1zaXplIjogIjIwMG0iCiAgICB9Cn0=', 'source': '/etc/docker/daemon.json', 'encoding': 'base64', 'failed': False, 'changed': False} docker_file 的类型为: dict"                                                                                 
}
ok: [lenovo] => {
    "msg": "docker_file 的值为: {'content': 'ewogICAgImluc2VjdXJlLXJlZ2lzdHJpZXMiOiBbCiAgICAgICAgImhhcmJvci5jdG5ycy5jb20iLAogICAgICAgICIxOTIuMTY4LjIuMTAwOjIzNDU2IgogICAgXQp9', 'source': '/etc/docker/daemon.json', 'encoding': 'base64', 'failed': False, 'changed': False} docker_file 的类型为: dict"
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

命令行方式

ansible home -m slurp -a "src='/etc/docker/daemon.json'"

​​​输出示例:

think | SUCCESS => {
    "changed": false,
    "content": "ewogICAgImRhdGEtcm9vdCI6ICIvZGF0YS9kb2NrZXJEYXRhIiwKICAgICJkZWZhdWx0LXJ1bnRpbWUiOiAicnVuYyIsCiAgICAiaW5zZWN1cmUtcmVnaXN0cmllcyI6IFsKICAgICAgICAiaGFyYm9yLmN0bnJzLmNvbSIsCiAgICAgICAgIjE5Mi4xNjguMi4xMDA6MjM0NTYiCiAgICBdLAogICAgImxvZy1kcml2ZXIiOiAianNvbi1maWxlIiwKICAgICJsb2ctb3B0cyI6IHsKICAgICAgICAibWF4LWZpbGUiOiAiMSIsCiAgICAgICAgIm1heC1zaXplIjogIjIwMG0iCiAgICB9Cn0=",                                                                                                                                                                                                                                          
    "encoding": "base64",
    "source": "/etc/docker/daemon.json"
}
lenovo | SUCCESS => {
    "changed": false,
    "content": "ewogICAgImluc2VjdXJlLXJlZ2lzdHJpZXMiOiBbCiAgICAgICAgImhhcmJvci5jdG5ycy5jb20iLAogICAgICAgICIxOTIuMTY4LjIuMTAwOjIzNDU2IgogICAgXQp9",
    "encoding": "base64",
    "source": "/etc/docker/daemon.json"
}

使用建议

  • ​适用场景​:快速获取远程节点的小文件内容(如 PID 文件、配置文件片段)。

  • ​不适合​:大文件传输(会占用大量内存,建议改用 fetch 模块)。

  • ​安全性​:Base64 编码不等于加密,敏感信息需额外加密处理。

通过 slurp​,可以在不生成本地临时文件的情况下直接在 Playbook 中处理远程文件内容,尤其适合自动化检测和配置验证任务。

1.5. ​b64decode​ 过滤器

用于 解码 Base64 编码的字符串

示例:

- hosts: home
  become: yes
  become_method: sudo
  tasks:
    - name: get docker config
      slurp:
        src: "/etc/docker/daemon.json"
      register: docker_file
      ignore_errors: yes

    - name: Cat docker_file content and type
      debug:
        msg:
          docker_file 的值为: {{ docker_file }}
          docker_file 的类型为: {{ docker_file | type_debug }}

    - name: Decode
      set_fact:
        docker_config: "{{ docker_file.content | b64decode | from_json }}"
      when: docker_file | length > 0

    - name: Cat config content and type
      debug:
        msg:
          docker_config 的值为: {{ docker_config }}
          docker_config 的类型为: {{ docker_config | type_debug }}

执行输出:

PLAY [home] ***********************************************************************************************************

TASK [get docker config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat docker_file content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_file 的值为: {'content': 'ewogICAgImRhdGEtcm9vdCI6ICIvZGF0YS9kb2NrZXJEYXRhIiwKICAgICJkZWZhdWx0LXJ1bnRpbWUiOiAicnVuYyIsCiAgICAiaW5zZWN1cmUtcmVnaXN0cmllcyI6IFsKICAgICAgICAiaGFyYm9yLmN0bnJzLmNvbSIsCiAgICAgICAgIjE5Mi4xNjguMi4xMDA6MjM0NTYiCiAgICBdLAogICAgImxvZy1kcml2ZXIiOiAianNvbi1maWxlIiwKICAgICJsb2ctb3B0cyI6IHsKICAgICAgICAibWF4LWZpbGUiOiAiMSIsCiAgICAgICAgIm1heC1zaXplIjogIjIwMG0iCiAgICB9Cn0=', 'source': '/etc/docker/daemon.json', 'encoding': 'base64', 'failed': False, 'changed': False} docker_file 的类型为: dict"                                                                                 
}
ok: [lenovo] => {
    "msg": "docker_file 的值为: {'content': 'ewogICAgImluc2VjdXJlLXJlZ2lzdHJpZXMiOiBbCiAgICAgICAgImhhcmJvci5jdG5ycy5jb20iLAogICAgICAgICIxOTIuMTY4LjIuMTAwOjIzNDU2IgogICAgXQp9', 'source': '/etc/docker/daemon.json', 'encoding': 'base64', 'failed': False, 'changed': False} docker_file 的类型为: dict"
}

TASK [Decode] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Cat config content and type] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config 的值为: {'data-root': '/data/dockerData', 'default-runtime': 'runc', 'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456'], 'log-driver': 'json-file', 'log-opts': {'max-file': '1', 'max-size': '200m'}} docker_config 的类型为: dict"
}
ok: [lenovo] => {
    "msg": "docker_config 的值为: {'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456']} docker_config 的类型为: dict"
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

1.6. get方法(Python 字典方法)

可以获取 Python 字典的某个值,示例如下:

- hosts: home
  become: yes
  become_method: sudo
  tasks:
    - name: get docker config
      slurp:
        src: "/etc/docker/daemon.json"
      register: docker_file
      ignore_errors: yes

    - name: Decode docker config
      set_fact:
        docker_config: "{{ docker_file.content | b64decode }}"

    - name: Show docker_config
      debug:
        msg:
          docker_config 的值为: {{ docker_config }}
          docker_config 的类型为: {{ docker_config | type_debug }}
        
    - name: Get docker_config.insecure-registries
      debug:
        msg:
          docker_config.insecure-registries 为 {{ docker_config.get('insecure-registries') }}

执行结果:

PLAY [home] ***********************************************************************************************************

TASK [get docker config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Decode docker config] ***********************************************************************************************************
ok: [think]
ok: [lenovo]

TASK [Show docker_config] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config 的值为: {'data-root': '/data/dockerData', 'default-runtime': 'runc', 'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456'], 'log-driver': 'json-file', 'log-opts': {'max-file': '1', 'max-size': '200m'}} docker_config 的类型为: dict"
}
ok: [lenovo] => {
    "msg": "docker_config 的值为: {'insecure-registries': ['harbor.ctnrs.com', '192.168.2.100:23456']} docker_config 的类型为: dict"
}

TASK [Get docker_config.insecure-registries] ***********************************************************************************************************
ok: [think] => {
    "msg": "docker_config.insecure-registries 为 ['harbor.ctnrs.com', '192.168.2.100:23456']"
}
ok: [lenovo] => {
    "msg": "docker_config.insecure-registries 为 ['harbor.ctnrs.com', '192.168.2.100:23456']"
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

1.7. unique 去重

可以从提供的输入列表中创建一个包含唯一元素的列表(集合),示例:

- hosts: home
  become: yes
  become_method: sudo
  vars:
    list1: [1, 2, 5, 1, 3, 4, 10]
  tasks:
    - name: 去重
      debug:
        msg: "{{ list1 | unique }}"

执行输出:

PLAY [home] ********************************************************************************************************************************************************************************************************************************************************************************************************

TASK [去重] ***********************************************************************************************************
ok: [think] => {
    "msg": [
        1,
        2,
        5,
        3,
        4,
        10
    ]
}
ok: [lenovo] => {
    "msg": [
        1,
        2,
        5,
        3,
        4,
        10
    ]
}

PLAY RECAP ***********************************************************************************************************
lenovo                     : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

有两个参数:

  • ​attribute​ 为这个属性筛选具有唯一值的对象(值为对象名称)

  • ​case_sensitive​ 指定是否区分大小写,默认为 false,不区分大小写,也是说 a 和 A 是一样的

示例:

- hosts: home
  become: yes
  become_method: sudo
  vars:
    list1: [1, 2, 5, 1, 3, 4, 10, 'a', 'A']
  tasks:
    - name: 去重
      debug:
        msg: "{{ list1 | unique(case_sensitive=true) }}"

输出:

PLAY [home] ********************************************************************************************************************************************************************************************************************************************************************************************************

TASK [去重] ********************************************************************************************************************************************************************************************************************************************************************************************************
ok: [think] => {
    "msg": [
        1,
        2,
        5,
        3,
        4,
        10,
        "a",
        "A"
    ]
}
ok: [lenovo] => {
    "msg": [
        1,
        2,
        5,
        3,
        4,
        10,
        "a",
        "A"
    ]
}

PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************************************************
lenovo                     : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
think                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0