Ansible的lookup,query,with_xxx

环境

  • 管理节点:Ubuntu 22.04
  • 控制节点:CentOS 8
  • Ansible:2.15.6

file lookup插件

lookup插件从外部数据源(文件,数据库,API等)获取数据,它是在控制节点上运行的。

下面以 file 插件为例。

假设在控制节点上,有文件 /tmp/a.txt/tmp/b.txt

/tmp/a.txt 内容如下:

xxx
yyyyy
z

/tmp/b.txt 内容如下:

good
better
best

单个文件

lookup()

可以通过 file 插件来读取文件内容:

---
- hosts: all
  vars:
    var1: "{{ lookup('file', '/tmp/a.txt') }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ var1 }}"

运行结果如下:

......
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "xxx\nyyyyy\nz"
}
......

查看 var1 类型:

......
    - name: task2
      debug:
        msg: "{{ var1 | type_debug }}"
......

运行结果如下:

......
TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "AnsibleUnsafeText"
}
......

可见,其类型是字符串( AnsibleUnsafeText )。

with_file

我们常见的 with_ ,都是使用了 xxx lookup。因此,二者通常可以互换。

把上面的 lookup('file', '') 改为 with_file 的形式:

......
    - name: task1
      debug:
        msg: "{{ item }}"
      with_file: "/tmp/a.txt"
......

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=xxx
yyyyy
z) => {
    "msg": "xxx\nyyyyy\nz"
}

多个文件

lookup()

若想访问多个文件,只需对 lookup() 添加多个参数:

---
- hosts: all
  vars:
    var1: "{{ lookup('file', '/tmp/a.txt', '/tmp/b.txt', wantlist=True) }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      loop: "{{ var1 }}"

注意:一般情况下,对于多个文件,我们希望得到一个list,所以需要显式的指定 wantlist=True

......
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=xxx
yyyyy
z) => {
    "msg": "xxx\nyyyyy\nz"
}
ok: [192.168.1.55] => (item=good
better
best) => {
    "msg": "good\nbetter\nbest"
}
......

var1 的类型是list,可以遍历 var1 ,访问各个文件内容。

如果不指定 wantlist=True

---
- hosts: all
  vars:
    var1: "{{ lookup('file', '/tmp/a.txt', '/tmp/b.txt') }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ var1 }}"

运行结果如下:

......
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "xxx\nyyyyy\nz,good\nbetter\nbest"
}
......

可见, 若不指定 wantlist=True ,则 var1 类型为字符串,会通过逗号,把多个文件的内容拼接在一起。

当然,对于单个文件,也可以指定 wantlist=True ,只不过list里只有一个元素而已。

with_file

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      with_file:
        - "/tmp/a.txt"
        - "/tmp/b.txt"

运行结果如下:

......
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=xxx
yyyyy
z) => {
    "msg": "xxx\nyyyyy\nz"
}
ok: [192.168.1.55] => (item=good
better
best) => {
    "msg": "good\nbetter\nbest"
}
......

query

query 是一个Jinja2函数,会调用lookup插件。 query 会返回一个list,也就是相当于lookup指定了 wantlist=True

上面的例子,用query改写如下:

---
- hosts: all
  vars:
    #var1: "{{ lookup('file', '/tmp/a.txt', '/tmp/b.txt', wantlist=True) }}"
    var1: "{{ query('file', '/tmp/a.txt', '/tmp/b.txt') }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      loop: "{{ var1 }}"

注: query 可简写为 q

其它lookup插件

具体参见文末的lookup插件列表。

常见的比如 items lookup。

---
- hosts: all
  vars:
    var1: "{{ query('items', 'aaa', 'bbb', 'ccc') }}"
    # var1: "{{ lookup('items', 'aaa', 'bbb', 'ccc', wantlist=True) }}" # 两种写法都可以
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      loop: "{{ var1 }}"

也可以写成 with_items 的形式:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      with_items:
        - "aaa"
        - "bbb"
        - "ccc"

错误处理

比如,要访问的文件不存在,则会报错。

---
- hosts: all
  vars:
    var1: "{{ query('file','/tmp/a.txt', '/tmp/z.txt') }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      loop: "{{ var1 }}"

报错如下:

......
TASK [task1] ***************************************************************************************
fatal: [192.168.1.55]: FAILED! => {"msg": "An unhandled exception occurred while templating '{{ query('file','/tmp/a.txt', '/tmp/z.txt') }}'. Error was a , original message: The 'file' lookup had an issue accessing the file '/tmp/z.txt'. file not found, use -vvvvv to see paths searched"}

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

可以添加一个 errors 参数:

  • strict :默认值,即报错
  • ignore :忽略错误
  • warn :警告

指定 ignore

---
- hosts: all
  vars:
    var1: "{{ query('file', '/tmp/a.txt', '/tmp/z.txt', errors='ignore') }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      loop: "{{ var1 }}"

运行结果如下:

......
TASK [task1] ***************************************************************************************
skipping: [192.168.1.55]

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

指定 warn

---
- hosts: all
  vars:
    var1: "{{ query('file', '/tmp/a.txt', '/tmp/z.txt', errors='warn') }}"
  tasks:
    - name: task1
      debug:
        msg: "{{ item }}"
      loop: "{{ var1 }}"

运行结果如下:

TASK [task1] ***************************************************************************************
[WARNING]: Lookup failed but the error is being ignored: The 'file' lookup had an issue accessing
the file '/tmp/z.txt'. file not found, use -vvvvv to see paths searched
skipping: [192.168.1.55]

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

参考

  • https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_lookups.html
  • https://docs.ansible.com/ansible/latest/plugins/lookup.html
  • https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_lookup.html
  • https://docs.ansible.com/ansible/latest/collections/ansible/builtin/index.html#lookup-plugins

你可能感兴趣的:(Ansible,ansible)