一千萬個為什麽

搜索

使用相同的項目列表執行多個Ansible任務



我正在使用一個完善的手冊來配置Apache的網站列表。劇本必須將每個站點的虛擬主機配置模板復制到位,然後使用 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配置為使用相同的項目列表執行兩項任務?

轉載註明原文: 使用相同的項目列表執行多個Ansible任務

一共有 3 個回答:

創建單獨的任務文件 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

我找到了一個使用文件大小的解決方案。由於我有每個站點的配置文件,因此我可以簡單地使用這些文件的列表遍歷所有這些文件。這樣我就沒有我的任務文件中的網站列表甚至一次,更不用說兩次了。我只需要添加一個站點即可添加一個文件。

為了讓事情變得更容易,我為模板創建了一個目錄:

  • <�代碼>角色/網絡服務器/模板/阿帕奇站點/ sitea.conf.j2 </代碼>
  • <�代碼>角色/網絡服務器/模板/阿帕奇站點/ siteb.conf.j2 </代碼>
  • <�代碼>角色/網絡服務器/模板/阿帕奇站點/ sitec.conf.j2 </代碼>
  • <�代碼>角色/網絡服務器/模板/阿帕奇站點/ 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

這種技術甚至可以用於空虛擬文件來為其他應用程序創建一個列表。

康斯坦丁給出了一個很好的答案;這裏有一個額外的味道。

我將通常將列表定義為變量,並且只需在同一個變量上寫入兩個單獨的循環:

┌─[[email protected]] - [~/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 }}"
┌─[[email protected]] - [~/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

這適用於變量優先級,例如通過在每個環境中定義不同的服務器組。當您需要在兩個循環之間執行各種其他非循環任務時,它也可以工作。