Как мы можем вызвать переменную в ansible playbook при использовании циклов - PullRequest
2 голосов
/ 13 июля 2020

У меня есть два файла, в которых эти файлы содержат server names и server IP's, я хочу изменить / заменить некоторые спецификации c server names и IP addressees в обоих файлах в зависимости от требований.

Это связано с This Post <- </a>, поскольку было предложено открыть новое сообщение.

Мой сценарий:

В файлах примеров ниже (file & file2) мне нужно сделать следующее ..

1 - В file1 и fil2 мне нужно заменить fostrain01.example.com на dbfostrain01.example.com.

2 - Где в другой строке мне нужно заменить 171.20.20.18 с 172.20.20.18 в обоих файлах.

# cat /etc/file1
fostrain01.example.com
fostrain02.example.com
ServerIPS 171.20.20.16 171.20.20.17 171.20.20.18 171.20.20.19 171.20.20.20

# cat /etc/fil2
fostrain01.example.com
fostrain02.example.com  
ServerIPS 171.20.20.16 171.20.20.17 171.20.20.18 171.20.20.19 171.20.20.20

My Playbook:

---
- name: Replace file contents
  hosts: all
  gather_facts: false
  vars:
    files:
      - /etc/file1
      - /etc/file2
    from_str: "fostrain01.example.com"
    to_str: "dbfoxtrain01.example.com"
    from_ip: "^(.*)171\\.20\\.20\\.18(.*)$"
   to_ip: "\\g<1>172.20.20.18\\g<2>"
   
  tasks:
    - name: Replace elements in file
      replace:
        path: "{{ item.path }}"
        regexp: "{{ item.From }}"
        replace: "{{ item.To }}"
        backup: yes
      loop:
        # Replace the desired string
        - { path: "{{ item }}", From: "{{ from_str }}", To: "{{ to_str }}" }
        #  Replace the desired ip
        - { path: "{{ item }}", From: "{{ from_ip }}", To: "{{ to_ip }}" }

В приведенном выше сборнике воспроизведения я определил переменные для каждого раздела, как вы можете см.

Что мне не хватает и что я хотел бы знать:

Мне не хватает информации о How i can use or reference files variable в разделе path модуля замены в моем playbook выше, в то время как используя loop.

Чтобы прояснить, я говорю о нижнем ..

    files:
      - /etc/file1
      - /etc/file2

Я ищу, чтобы это соответствовало подходу, описанному выше laybook, я знаю другой способ сделать это.

Прошу прощения, если я не смог объяснить это более ясно.

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вы почти готовы к своему решению. Просто вам нужно использовать переменную files в качестве индексного ключа для выбора файла, как хорошо проиллюстрировано @ β.εηοιτ.βε в его разделе ответов.

Итак , чтобы завершить код, чтобы он заработал, он должен работать следующим образом:

---
- name: Replace file contents
  hosts: all
  gather_facts: false
  vars:
    files:
      - /etc/file1
      - /etc/file2
    from_str: "fostrain01.example.com"
    to_str: "dbfoxtrain01.example.com"
    from_ip: "^(.*)171\\.20\\.20\\.18(.*)$"
   to_ip: "\\g<1>172.20.20.18\\g<2>"
  
tasks:
    - name: Replace elements in file
      replace:
        path: "{{ item.path }}"
        regexp: "{{ item.From }}"
        replace: "{{ item.To }}"
        backup: yes
      loop:
        # Replace the desired string
        - { path: "{{ files[0] }}", From: "{{ from_str }}", To: "{{ to_str }}" }
        - { path: "{{ files[0] }}", From: "{{ from_ip }}", To: "{{ to_ip }}" } 
        #  Replace the desired ip
        - { path: "{{ files[1] }}", From: "{{ from_str }}", To: "{{ to_str }}" }
        - { path: "{{ files[1] }}", From: "{{ from_ip }}", To: "{{ to_ip }}" }
1 голос
/ 13 июля 2020

Итак, файл - это список переменных, как и любой список переменных, элементы доступны через ключ с индексом 0.

  • Итак, в вашем случае первый элемент Список files, содержащий /etc/file1, доступен через

    files.0
    

    или

    files[0]
    
  • Второй, содержащий /etc/file1, доступен либо через

    files.1
    

    Или

    files[1]
    
  • И так далее, и так далее.

Но есть много других способов сделать это:

  1. вы можете использовать product для объединения двух ваших списков
  2. вы можете использовать параметр loop_control index_var для создания собственного индекса
  3. вы можете использовать параметр extended из loop_control, который предоставляет расширенную переменную ansible_loop.index0

Все это сказано, чтобы сделать его немного более общим c, на вашем месте я бы использовал фильтр product и go с более простым:

- name: Replace elements in file
  replace:
    path: "{{ item.0 }}"
    regexp: "{{ item.1.from }}"
    replace: "{{ item.1.to }}"
    backup: yes
  vars:
    paths:
      - /etc/file1
      - /etc/file2
    replaces:
      - from: "fostrain01.example.com"
        to: "dbfoxtrain01.example.com"
      - from: "^(.*)171\\.20\\.20\\.18(.*)$"
        to: "\\g<1>172.20.20.18\\g<2>"
  loop: "{{ paths | product(replaces) | list }}"

Потому что тогда нет причин преобразовывать ваш список, он уже есть, он должен для вашей задачи replace. Имейте в виду, что переменные могут быть определены как на уровне игры, так и на уровне задачи. Если вам нужна переменная replaces в других задачах, просто верните ее на уровень игры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...