Using loop in ansible PlayBook


  • به طور کلی برای استفاده از حلقه در پرونده‌های PlayBook از loop و with_lookup استفاده می‌شود.
  • در حال حاضر loop و نحوه‌ی استفاده از آن در حال توسعه و رشد است لذا پیشنهاد می‌شود بیشتر از with_lookup استفاده شود.

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • با استفاده از ماژول file ، سه پرونده با نام‌های متفاوت ایجاد شود.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
---
- hosts: centos-server
  tasks:
  - name: create multi file
    file: state=touch path=/opt/{{item}}
    with_items:
     - file1
     - file2
     - file3
  • همان طور که در کد بالا مشاهده می‌کنید، با استفاده از متغیر item مشخص کردیم که سه پرونده‌ی file1 ، file2 و file3 ایجاد شوند.
  • به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • دو بسته‌ی httpd و elinks بر روی گروهی خاص از خادم‌های تحت مدیریت نصب و راه اندازی شوند.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
---
- hosts: centos-server
  tasks:
  - name: install httpd and elinks package
    yum: name={{item}} state=latest
    with_items:
     - httpd
     - elinks
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • ابتدا محتویات پرونده‌های 01 و 02 به ترتیب درون متغیر item ریخته و نمایش داده شود.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
---
- hosts: centos-server
  tasks:
  - debug: msg="{{item}}"
    with_file:
     - /opt/ansible/files/01.txt
     - /opt/ansible/files/02.txt
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml

  • به عنوان مثال کد زیر باعث می شود تا :
    • مقدار متغیر item زمانی چاپ شود که محتویات آن برابر با محتویات متغیر loop_1 باشد.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
- hosts: all
  vars:
    loop_1: "hello1"
  tasks:
  - name: Ansible loop with conditional example
    debug:
      msg: "{{ item }}"
    with_items:
      - "hello1"
      - "hello2"
      - "hello3"
    when: item == "{{ loop_1 }}"
  • با اجرای پرونده‌ی بالا، ابتدا مقدار hello1 درون item ریخته می‌شود و چون مقدار item در این زمان برابر با مقدار متغیر loop_1 است، لذا مقدار item نمایش داده می‌شود.
  • در مرحله‌ی بعد مقدار hello2 درون item ریخته می‌شود و چون مقدار item در این زمان برابر با مقدار متغیر loop_1 نیست، لذا مقدار item نمایش داده نمی‌شود.
  • در مرحله‌ی بعد مقدار hello3 درون item ریخته می‌شود و چون مقدار item در این زمان برابر با مقدار متغیر loop_1 نیست، لذا مقدار item نمایش داده نمی‌شود.
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml
  • در صورتی که کد بالا به صورت موفقیت آمیز اجرا شده باشد، خروجی‌ای مشابه زیر دریافت خواهید کرد :
PLAY [all] *******************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
ok: [172.16.0.245]

TASK [Ansible loop with conditional example] *********************************************************************************************************
 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: item == "{{ loop_1 }}"

ok: [172.16.0.245] => (item=None) => {
    "msg": "hello1"
}
skipping: [172.16.0.245] => (item=None)
skipping: [172.16.0.245] => (item=None)

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

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • سه مقدار hello1 ، hello2 و hello3 زمانی چاپ شوند که مقدار متغیر ansible_distribution برابر با MacOSX باشد.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
- hosts: all
  tasks:
  - name: Ansible loop with conditional example
    debug:
      msg: "{{ item }}"
    with_items:
      - "hello1"
      - "hello2"
      - "hello3"
    when: ansible_distribution == "MacOSX"
  • نکته: محتویات متغیر ansible_distribution از ansible_facts بدست آمده است.
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • ابتدا یک گروه یا اصطلاحا یک directory از متغیرها با نام Fruits ایجاد شود.
    • سپس متغیرها یا کلیدهایی با نام Apple ، Orange و Grapes به همراه مقدارهایی برای آن‌ها در نظر گرفته شود.
    • سپس نام متغیرها یا کلیدها همراه با مقدار آن‌ها نمایش داده شود.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
- hosts: all
  vars:
    Fruits:
      Apple: 'Red'
      Orange: 'Orange'
      Grapes: 'Greem'
  tasks:
  - name: Ansible dictionary loop Example
    debug:
      msg: "Key is {{ item.key }} and color is {{ item.value }}"
    with_dict: "{{ Fruits }}"
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml
  • در صورتی که کد بالا به صورت موفقیت آمیز اجرا شده باشد، خروجی‌ای مشابه زیر دریافت خواهید کرد :
PLAY [all] *******************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
ok: [172.16.0.245]

TASK [Ansible dictionary loop Example] ***************************************************************************************************************
ok: [172.16.0.245] => (item=None) => {
    "msg": "Key is Orange and color is Orange"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "Key is Apple and color is Red"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "Key is Grapes and color is Greem"
}

PLAY RECAP *******************************************************************************************************************************************
172.16.0.245               : ok=2    changed=0    unreachable=0    failed=0
  • به مواردی که به صورت رنگی مشخص شده است، دقت کنید.

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • مقادیر hello2 ، hello1 و hello3 به همراه شماره‌ی ترتیب آن‌ها نمایش داده شود.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
- hosts: all
  tasks:
  - name: Ansible loop with index example
    debug:
      msg: "echo loop index at {{ item.0 }} and value at {{item.1}}"
    with_indexed_items:
      - "hello1"
      - "hello2"
      - "hello3"
  • نکته: item.0 مولفه‌ی شماره‌ی ترتیب می‌باشد در صورتی که item.1 حاوی محتویاتی که مشخص شده است، می‌باشد.
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml
  • در صورتی که کد بالا به صورت موفقیت آمیز اجرا شده باشد، خروجی‌ای مشابه زیر دریافت خواهید کرد :
PLAY [all] *******************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
ok: [172.16.0.245]

TASK [Ansible loop with index example] ***************************************************************************************************************
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at 0 and value at hello1"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at 1 and value at hello2"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at 2 and value at hello3"
}

PLAY RECAP *******************************************************************************************************************************************
172.16.0.245               : ok=2    changed=0    unreachable=0    failed=0
  • به مواردی که به صورت رنگی مشخص شده است، دقت کنید.
  • نکته: همان طور که مشاهده می‌کنید، شروع ترتیب از عدد صفر می‌باشد. برای این که شروع از عدد یک باشد، کافیست یک واحد به آن اضافه کنیم :
{{ item.0 + 1 }}

  • به عنوان مثال کد زیر باعث می‌شود تا :
    • حلقه‌های تو در تو یا اصطلاحا nested با دو دسته از مقادیر شکل گیرد.
    • برای این منظور پرونده‌ی PlayBook زیر را در نظر بگیرید :
- hosts: all
  vars:
    keys:
    - key1
    - key2
    - key3
    - key4
  tasks:
  - name: Ansible loop with index example
    debug:
      msg: "echo loop index at {{ item[0] }} and value at {{ item[1] }}"
    with_nested:
    - [ 'calvin', 'josh', 'alice' ]
    - '{{ keys }}'
  •  به منظور اجرای پرونده‌ی PlayBook به شکل زیر عمل کنید :
# ansible-playbook playbook.yaml
  • در صورتی که کد بالا به صورت موفقیت آمیز اجرا شده باشد، خروجی‌ای مشابه زیر دریافت خواهید کرد :
PLAY [all] *******************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
ok: [172.16.0.245]

TASK [Ansible loop with index example] ***************************************************************************************************************
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at calvin and value at key1"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at calvin and value at key2"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at calvin and value at key3"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at calvin and value at key4"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at josh and value at key1"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at josh and value at key2"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at josh and value at key3"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at josh and value at key4"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at alice and value at key1"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at alice and value at key2"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at alice and value at key3"
}
ok: [172.16.0.245] => (item=None) => {
    "msg": "echo loop index at alice and value at key4"
}

PLAY RECAP *******************************************************************************************************************************************
172.16.0.245               : ok=2    changed=0    unreachable=0    failed=0
  • به مواردی که به صورت رنگی مشخص شده است، دقت کنید.
  • مشابه PlayBook بالا را می‌توان به صورت زیر در زبان Bash نظر گرفت :
#! /bin/bash
for i in $(echo calvin josh alice) ; do
        for j in $(echo key1 key2 key3 key4) ; do
                echo "$i - $j"
        done
done

  • به منظور مطالعه‌ی بیشتر لینک‌های زیر پیشنهاد می‌شود :
http://www.mydailytutorials.com/working-with-ansible-loop/
https://riptutorial.com/ansible/example/22081/nested-loops
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html

  • آزمایش شده بر روی Ansible نسخه‌ی 2.5.1
  • آزمایش شده بر روی سیستم عامل Ubuntu 18.04

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *