Выполнить несколько Ansible задач с одним и тем же списком элементов

13

Я использую ANSIBLE PlayBook, чтобы настроить Apache для списка сайтов. Playbook должен скопировать шаблон конфигурации виртуального хоста для каждого сайта на место, а затем включить каждый сайт, используя a2ensite:

- name: Install apache site conf
  template: src=apache-sites-{{item}}-conf.j2 dest=/etc/apache2/sites-available/{{item}}.conf mode=0644
  with_items:
  - sitea
  - siteb
  - sitec
  - sited
- name: Enable site apache conf
  command: a2ensite {{item}}
  args:
    creates: /etc/apache2/sites-enabled/{{item}}.conf
  with_items:
  - sitea
  - siteb
  - sitec
  - sited

Мне не нравится повторять один и тот же список для каждой задачи. Как настроить playbook для выполнения обеих задач с одинаковым списком предметов?

Стивен Остермиллер
источник

Ответы:

15

Создайте отдельный файл задач make_site.yml:

---
- name: Install apache site conf
  template:
    src: apache-sites-{{ site }}-conf.j2
    dest: /etc/apache2/sites-available/{{ site }}.conf
    mode: 0644

- name: Enable site apache conf
  command: a2ensite {{ site }}
  args:
    creates: /etc/apache2/sites-enabled/{{ site }}.conf

И в вашей пьесе:

- include_tasks: make_site.yml
  with_items:
    - sitea
    - siteb
    - sitec
    - sited
  loop_control:
    loop_var: site
Константин Суворов
источник
Я надеялся найти решение, не создавая отдельный файл. Что - то вроде loopна blockблоке. Похоже, что это было запрошено, но отклонено в выпуске Ansible GH 13262 . :-(
gertvdijk
2

Я нашел решение с помощью файловых глобусов. Поскольку у меня есть файл конфигурации для каждого сайта, я могу просто использовать список этих файлов для перебора всех из них. Таким образом, у меня нет списка сайтов в файле задач ни разу, не говоря уже о двух. Все, что мне нужно сделать, чтобы добавить сайт, это добавить файл.

Чтобы было проще, я создал каталог для шаблонов:

  • roles/webserver/templates/apache-sites/sitea.conf.j2
  • roles/webserver/templates/apache-sites/siteb.conf.j2
  • roles/webserver/templates/apache-sites/sitec.conf.j2
  • roles/webserver/templates/apache-sites/sited.conf.j2

Затем roles/webserver/tasks/main.ymlя могу использовать этот список файлов и некоторые регулярные выражения:

---
- block:
  - name: Install apache site conf
    template: src={{item}} dest=/etc/apache2/sites-available/{{item|regex_replace(".*/","")|regex_replace("\.j2$","")}} mode=0644
    with_fileglob:
    - "roles/webserver/templates/apache-sites/*"
  - name: Enable site apache conf
    command: a2ensite {{item|regex_replace(".*/","")|regex_replace("\.conf\.j2$","")}}
    args:
      creates: /etc/apache2/sites-enabled/{{item|regex_replace(".*/","")|regex_replace("\.j2$","")}}
    with_fileglob:
    - "roles/webserver/templates/apache-sites/*"
  become: yes

Эту технику можно использовать даже с пустыми фиктивными файлами для создания списка для других приложений.

Стивен Остермиллер
источник
1

Константин дал хороший ответ; вот дополнительный аромат на этом.

Я обычно определяю списки как переменные и просто пишу два отдельных цикла над одной и той же переменной:

┌─[jamesph@geror] - [~/temp] - [Sat Jan 13, 10:06]
└─[$]> cat loops-1.yml
- hosts: localhost
  gather_facts: no
  vars:
    menu:
      - Egg and Spam
      - Spam, bacon, sausage and Spam
      - Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam
  tasks:
    - debug:
        msg: "We have {{ item }}"
      with_items: "{{ menu }}"
    - debug:
        msg: "I love {{ item }}!"
      with_items: "{{ menu }}"
┌─[jamesph@geror] - [~/temp] - [Sat Jan 13, 10:06]
└─[$]> ansible-playbook loops-1.yml
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] **********************************************************************************************************************

TASK [debug] **************************************************************************************************************************
ok: [localhost] => (item=Egg and Spam) => {
    "changed": false,
    "item": "Egg and Spam",
    "msg": "We have Egg and Spam"
}
ok: [localhost] => (item=Spam, bacon, sausage and Spam) => {
    "changed": false,
    "item": "Spam, bacon, sausage and Spam",
    "msg": "We have Spam, bacon, sausage and Spam"
}
ok: [localhost] => (item=Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam) => {
    "changed": false,
    "item": "Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam",
    "msg": "We have Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam"
}

TASK [debug] **************************************************************************************************************************
ok: [localhost] => (item=Egg and Spam) => {
    "changed": false,
    "item": "Egg and Spam",
    "msg": "I love Egg and Spam!"
}
ok: [localhost] => (item=Spam, bacon, sausage and Spam) => {
    "changed": false,
    "item": "Spam, bacon, sausage and Spam",
    "msg": "I love Spam, bacon, sausage and Spam!"
}
ok: [localhost] => (item=Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam) => {
    "changed": false,
    "item": "Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam",
    "msg": "I love Spam, Spam, Spam, Spam, Spam, Spam, baked beans, Spam, Spam, Spam and Spam!"
}

PLAY RECAP ****************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

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

Бойкот SE для Моники Челлио
источник