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