Ansible:字典中的任何文件

Ansible: any file from dictionary

今天我完全被它弄坏了。我有一些字典文件的结构,我需要用字典中使用的变量制作一些文本或json:

> hosts_vars
    varfile.yaml
> inventory
    hosts.yml
tasks.yml

varfile.yaml


host_vars:
 host1: { ip: 192.168.1.1 }
 host2: { ip: 192.168.1.2 }

hosts.yml

all:
  hosts:
    host1:
      ansible_host: 192.168.1.1
    host2:
      ansible_host: 192.168.1.2

tasks.yml

- hosts: all
  become: no
  gather_facts: false
  vars_files:
    - hosts_vars/varfile.yaml
  vars:
   temp_file: /tmp/out_file.txt
  tasks:
   - local_action:
      module: ansible.builtin.lineinfile
      path: '{{ temp_file }}'
      line: |
         - targets: ['{{ host_vars[inventory_hostname].ip }}']
      state: present

当我运行它:ansible-playbook tasks.yml -l all 我得到了:

~> cat /tmp/out_file.txt

- targets: ['192.168.1.1']

我不明白为什么会这样。如果我有 60 台主机,我将在文件中得到 ~54 行。它是如何工作的?

带有 ansible [core 2.11.2] 的 macOS 在 /tmp 中写入文件有问题如果你想使用它,你需要设置主文件夹或任何其他具有根权限的文件夹。

您需要在 localhost 中创建文件并将任务委托给 localhost 循环主机。

  tasks:
   -  name: update host
      lineinfile:
        path: '{{ temp_file }}'
        create: yes
        line: |
         - targets: ['{{ host_vars[item].ip }}'] # or ['{{ host_vars[item]['ip'] }}']
        insertafter: EOF
      delegate_to: localhost
      run_once: true
      with_inventory_hostnames:
        - all

例如

  tasks:
    - ansible.builtin.lineinfile:
        create: yes
        path: "{{ temp_file }}"
        line: "- targets: ['{{ host_vars[inventory_hostname].ip }}']"
      delegate_to: localhost

给予

shell> cat /tmp/out_file.txt
- targets: ['192.168.1.2']
- targets: ['192.168.1.1']

备注:

  • 不要使用 Yaml Literal Style block with line。它说它是什么。您不希望行中有任何换行符 \n。如果您出于某种原因必须使用方块,请将破折号 - 放在管道 | 后面。这将删除尾随的换行符 \n
    - ansible.builtin.lineinfile:
        create: true
        path: "{{ temp_file }}"
        line: |-
          - targets: ['{{ host_vars[inventory_hostname].ip }}']
      delegate_to: localhost
  • 你可以用delegate_to: localhost代替local_action

  • 使用create: yes。默认为 no,如果文件不存在,任务将失败 Destination /tmp/out_file.txt does not exist !

  • state: present 默认为

  • insertafter: EOF 默认为

  • varfile.yaml 放入目录 host_vars 缺少重点 host_vars工作。没有名称为 varfile 的主机。你应该把文件,例如改成 vars/varfile.yaml

  • 变量host_vars是多余的。主机的 IP 存储在变量 ansible_host 中。下面的任务给出了相同的结果

    - ansible.builtin.lineinfile:
        create: true
        path: "{{ temp_file }}"
        line: "- targets: ['{{ ansible_host }}']"
      delegate_to: localhost
  • 如果您想创建所有 IP 地址的列表,请执行以下任务
    - ansible.builtin.lineinfile:
        create: true
        path: "{{ temp_file }}"
        line: "- targets: {{ ansible_play_hosts_all|
                             map('extract', hostvars, 'ansible_host') }}"
      run_once: true
      delegate_to: localhost

给予

shell> cat /tmp/out_file.txt
- targets: ['192.168.1.1', '192.168.1.2']