【问题标题】:Ansible Automate configuration by iterating over files and assigning variables for each hostAnsible 通过迭代文件并为每个主机分配变量来自动化配置
【发布时间】:2021-04-26 19:01:48
【问题描述】:

我需要一些帮助来确定执行此操作的最佳方法以及如何设置我的剧本以适当地为每个节点提取变量。

假设我有 3 个主机

/etc/ansible/hosts:

host1
host2
host3

我有一个变量文件,里面有多个条目

vars/IPs.yaml:

---
IP: ['192.168.77.35', '192.167.77.36', '192.168.77.37']

我正在运行这个剧本:

network_change.yaml:

---
- hosts: all
  vars_files:
    - vars/IPs.yaml
  tasks:
    - name: Check 10G Interface
      stat:
        path: /etc/sysconfig/network-scripts/ifcfg-card-10Gb-1
      register: teng

    - name: Change 10G Interface Settings
      lineinfile:
        path: /etc/sysconfig/network-scripts/ifcfg-card-10Gb-1
        regexp: '{{item.From}}'
        line: '{{item.To}}'
      when: teng.stat.exists
      with_items:
       - { From: 'IPADDR=', To: 'IPADDR={{IP}}'}

我可以在单个主机上正常工作...但是当我有多个主机时,我不确定如何循环访问 IPs.yaml 变量并在下次循环运行时提取下一个值。还有没有办法让我不使用字典 .yaml 变量,我可以只使用在换行符上有 IP 的原始文本文件吗?

基本上我想循环并让主机在每个相应的主机 /etc/sysconfig/network-scripts/ifcfg-card-10Gb-1 中显示此内容。

host1 = 'IPADDR=192.168.77.35'

host2 = 'IPADDR=192.168.77.36'

host3 = 'IPADDR=192.168.77.37'

最终的目标是能够使用简单的文本文件而不是字典 yaml 文件来处理超过 100 台主机,并且将包括多个变量等。系统都可以通过 dhcp/hostnames/ 访问知识产权。

【问题讨论】:

    标签: ansible yaml jinja2


    【解决方案1】:

    用数据创建字典,例如

        - set_fact:
            _dict: '{{ dict(ansible_play_hosts|zip(IP)) }}'
          run_once: true
    

    应该给

      _dict:
        host1: 192.168.77.35
        host2: 192.167.77.36
        host3: 192.168.77.37
    

    然后使用这个字典并选择IP,例如

        - name: Change 10G Interface Settings
          lineinfile:
            path: /etc/sysconfig/network-scripts/ifcfg-card-10Gb-1
            regexp: 'IPADDR='
            line: 'IPADDR={{ _dict[inventory_hostname] }}'
          when: teng.stat.exists
    

    您可能想先对其进行测试,例如

        - name: Change 10G Interface Settings
          debug:
            msg: 'IPADDR={{ _dict[inventory_hostname] }}'
    

    应该给

    ok: [host2] => 
      msg: IPADDR=192.167.77.36
    ok: [host1] => 
      msg: IPADDR=192.168.77.35
    ok: [host3] => 
      msg: IPADDR=192.168.77.37
    

    下一个选项,而不是创建字典,是计算列表中的索引,例如应该给出相同的结果

        - name: Change 10G Interface Settings
          debug:
            msg: 'IPADDR={{ IP[_index|int] }}'
          vars:
            _index: '{{ ansible_play_hosts.index(inventory_hostname) }}'
    

    问:使用在换行符上有 IP 的原始文本文件

    A:创建文件,例如

    shell> cat IP.txt 
    192.168.77.35
    192.167.77.36
    192.168.77.37
    

    即时创建列表,例如

        - set_fact:
            IP: "{{ lookup('file', 'IP.txt').split('\n') }}"
          run_once: true
    

    应该给

      IP:
      - 192.168.77.35
      - 192.167.77.36
      - 192.168.77.37
    

    更强大的解决方案是将哈希放入文件中,例如

    shell> cat IP.txt
    host1: 192.168.77.35
    host2: 192.167.77.36
    host3: 192.168.77.37
    

    然后是任务

        - include_vars:
            file: IP.txt
            name: _dict
    

    应该创建字典

      _dict:
        host1: 192.168.77.35
        host2: 192.167.77.36
        host3: 192.168.77.37
    

    但是,最简单的解决方案是将这个字典存储在 IP.yml 中,并将其放入目录 group_vars/all

    【讨论】:

    • 哇,非常详细,解释了很多!非常感谢弗拉德米尔。我唯一的问题是原始文本文件(IP.txt)示例如何在 lineinfile 循环中迭代文件?其他示例使用清单主机名...我只是找不到让每个主机拉下一个换行符而不是原始文本文件中的第一个条目的方法...
    • 不客气。 each host pulls the next newline 的结果是字典,不是吗?我不明白你所说的iterate the file in the lineinfile loop 是什么意思。预期的结果是什么?如果您有问题edit 问题(或打开一个新问题)并提出minimal reproducible example
    • 我想我在你提到的评论中找到了我需要的东西:The next option, instead of creating the dictionary, is to calculate the index in the list, e.g. should give the same result
    • 我明白了。如果您确定 ansible_play_hosts 的项目和顺序正确,请使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2019-12-13
    相关资源
    最近更新 更多