天天看点

ansible之playbook循环

当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句指明迭代的元素列表即可。with_items的值是python list数据结构,每个task会循环读取list的值,然后后key的名称是item,list里面也支持python字典。

例子一:安装多个软件。

tasks:

  - name: "Install Packages"

    yum: name={{ item }} state=latest

    with_items:

      - httpd

      - mysql-server

      - php
           

例子二:批量创建多个用户。(with_items)

- hosts: slave
  remote_user: suixiaofeng
  sudo: yes
  
  tasks:
    - name: "add user"
      user: name={{ item.name }} state=present groups={{ item.groups }}
      with_items:
        - {name: "test5", groups: "suixiaofeng"}
        - {name: "test6", groups: "suixiaofeng"}
           

其中引用变量时前缀item变量是固定的,而item后跟的键名就是在with_items中定义的字典键名。

嵌套loops循环(with_nested:)

嵌套循环主要实现一对多,多对多的合并。

loops.yaml
- hosts: slave
  gather_facts: False
  tasks: 
   - name: debug loops
     debug: msg="name is {{ item[0] }}  vaule is {{ item[1] }} num is {{ item[2] }}"
     with_nested:
        - ['suixiaofeng']
        - ['a','b','c']
        - ['1','2','3'] 
           

 散列loops(对哈希表进行循环):

with_dict

---
-
  hosts: all
  gather_facts: False
  vars:
   user:
    Bob_hou:
     name: Bob_Hou
     shell: bash
    Jmilk:
     name: Jmilk
     shell: zsh
  tasks:
  -
    name: debug loops
    debug: "msg=\"name -----> {{item.key }} value -----> {{item.value.name }} shell -----> {{ item.value.shell }}\""
    with_dict: "{{ user }}"
           

文件匹配loops:

cat fileloops.yaml 
---
   - hosts: slave
     gather_facts: False
     tasks:
     - name: debug loops
       debug: msg="this is ------> {{ item }}"
       with_fileglob:
       - /home/upsmart/yaml/*yaml 
           

随机选择loops:

with_random_choice
           
---
- hosts: slave
  gather_facts: False
  tasks:
     - name: debug loops
       debug: msg="name ------> {{ item }}"
       with_random_choice:
          - "ansible01"
          - "ansible02"
          - "ansible03"
           

效果:

PLAY [slave] **********************************************************************************************************************************************************************************

TASK [debug loops] ****************************************************************************************************************************************************************************

ok: [sp-116.130] => (item=None) => {

    "msg": "name ------> ansible03"

}

ok: [sp-116-128] => (item=None) => {

    "msg": "name ------> ansible01"

}

PLAY RECAP ************************************************************************************************************************************************************************************

sp-116-128                 : ok=1    changed=0    unreachable=0    failed=0   

sp-116.130                 : ok=1    changed=0    unreachable=0    failed=0   

[email protected]:~/yaml$ ansible-playbook suiji.yaml

PLAY [slave] **********************************************************************************************************************************************************************************

TASK [debug loops] ****************************************************************************************************************************************************************************

ok: [sp-116.130] => (item=None) => {

    "msg": "name ------> ansible01"

}

ok: [sp-116-128] => (item=None) => {

    "msg": "name ------> ansible02"

}

PLAY RECAP ************************************************************************************************************************************************************************************

sp-116-128                 : ok=1    changed=0    unreachable=0    failed=0   

sp-116.130                 : ok=1    changed=0    unreachable=0    failed=0

条件判断loops:

---
-
  hosts: slave
  gather_facts: False
  tasks:
  -
    name: debug loops
    shell: cat /root/Ansible
    register: host
    until: host.stdout.startswith("cat")
    retries: 5
    delay: 5
           

结果:

PLAY [slave] **********************************************************************************************************************************************************************************

TASK [debug loops] ****************************************************************************************************************************************************************************

FAILED - RETRYING: debug loops (5 retries left).

FAILED - RETRYING: debug loops (5 retries left).

FAILED - RETRYING: debug loops (4 retries left).

FAILED - RETRYING: debug loops (4 retries left).

FAILED - RETRYING: debug loops (3 retries left).

FAILED - RETRYING: debug loops (3 retries left).

FAILED - RETRYING: debug loops (2 retries left).

FAILED - RETRYING: debug loops (2 retries left).

FAILED - RETRYING: debug loops (1 retries left).

FAILED - RETRYING: debug loops (1 retries left).

fatal: [sp-116-128]: FAILED! => {"attempts": 5, "changed": true, "cmd": "cat /root/Ansible", "delta": "0:00:00.003312", "end": "2018-08-13 14:33:17.438968", "msg": "non-zero return code", "rc": 1, "start": "2018-08-13 14:33:17.435656", "stderr": "cat: /root/Ansible: Permission denied", "stderr_lines": ["cat: /root/Ansible: Permission denied"], "stdout": "", "stdout_lines": []}

fatal: [sp-116.130]: FAILED! => {"attempts": 5, "changed": true, "cmd": "cat /root/Ansible", "delta": "0:00:00.003301", "end": "2018-08-13 14:33:17.509310", "msg": "non-zero return code", "rc": 1, "start": "2018-08-13 14:33:17.506009", "stderr": "cat: /root/Ansible: Permission denied", "stderr_lines": ["cat: /root/Ansible: Permission denied"], "stdout": "", "stdout_lines": []}

    to retry, use: --limit @/home/upsmart/yaml/panduan1.retry

PLAY RECAP ************************************************************************************************************************************************************************************

sp-116-128                 : ok=0    changed=0    unreachable=0    failed=1   

sp-116.130                 : ok=0    changed=0    unreachable=0    failed=1  

echo "cat" > /home/upsmart/Ansible

再次执行:

PLAY [slave] **********************************************************************************************************************************************************************************

TASK [debug loops] ****************************************************************************************************************************************************************************

changed: [sp-116.130]

changed: [sp-116-129]

PLAY RECAP ************************************************************************************************************************************************************************************

sp-116-129                 : ok=1    changed=1    unreachable=0    failed=0   

sp-116.130                 : ok=1    changed=1    unreachable=0    failed=0  

文件优先匹配Loops:

 with_first_found

---
 - 
   hosts: slave
   gather_facts: True
   tasks: 
   - 
     name: debug loops
     debug: msg="files -----> {{ item }}"
     with_first_found:
     -
       "{{ ansible_distribution }}.yaml"
     - 
       "panduan1.yaml" 
           

register Loops:

register 是用于task直接互相传递数据的。register可以同时接受多个task结果当变量临时存储。

例子:

---
 -
   hosts: slave
   gather_facts: True
   tasks:
   - 
     name: debug loops
     shell: "{{ item }}"
     with_items:
       - hostname
       - uname
       - uname -a 
     register: ret
   - 
     name: display loops
     debug: msg="{% for i in ret.results %} {{ i.stdout }} {% endfor %}"
           

playbook lookups:

1.file,打开文件,然后把结果返回给变量。

---
  - hosts: slave
    gather_facts: False
    vars: 
       content: "{{ lookup('file','/etc/network/interfaces') }}"
    tasks:
    - 
      name: debug lookups
      debug: msg="the contents is {% for i in content.split("\n") %} {{ i }} {% endfor %}"
           

2.lookups password

对传入的内容进行加密;

--- 
  - hosts: slave
    gather_facts: False
    vars:
      contents: "{{ lookup('password','suixiaofeng') }}"
    tasks:
    -  
     name: debug lookups
     debug: msg="the contents is {{ contents }}"
           

3.lookups pipe

可以对系统执行命令,然后把命令传到变量使用。

---
   - hosts: slave
     gather_facts: False
     vars: 
        contents: "{{ lookup('pipe','hostname') }}"
     tasks:
         - 
          name: debug lookups
          debug: msg="the contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
           

4.lookups redis_kv

从redis数据库中get数据。

---
   - hosts: slave
     gather_facts: False
     vars:
       contents: "{{ lookup('redis_kv','redis://127.0.0.1:6379,ansible') }}"  
     tasks:
     - 
       name: debug lookups
       debug: msg="the contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}" 
           

5.lookups template

读取文件,类似于file,template读取文件之前需要把jiaja模板渲染后再读取。

---
   - 
    hosts: slave
    gather_facts: True
    vars: 
       contents: "{{ lookup('template','./lookups.j2') }}"
    tasks: 
    - 
     name: debug lookups
     debug: msg="the contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
           

执行结果:

ansible-playbook template.yaml 

PLAY [slave] **********************************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************
ok: [sp-116.130]
ok: [sp-116-129]

TASK [debug lookups] **************************************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the contents is  worker_processes 1;  IPaddress 192.168.116.130     "
}
ok: [sp-116-129] => {
    "msg": "the contents is  worker_processes 1;  IPaddress 192.168.116.129     "
}

PLAY RECAP ************************************************************************************************************************************************************************************
sp-116-129                 : ok=2    changed=0    unreachable=0    failed=0   
sp-116.130                 : ok=2    changed=0    unreachable=0    failed=0 
           

6.playbook conditionals

当不同的主机需要执行不同的任务时,可以用when进行判断。

--- 
   - 
    hosts: slave
    tasks:
    - 
     name: host 192.168.116.129 run this task
     debug: msg="{{ ansible_default_ipv4.address }}"
     when: ansible_default_ipv4.address == "192.168.116.129"
    -
     name: memtotal < 500M and processor_cores == 2 run this task
     debug: msg="{{ ansible_fqdn }}"
     when: ansible_memtotal_mb < 500 or ansible_processor_cores == 2
    -
     name: all host run this task
     shell: hostname
     register: info
    - 
     name: hostname is python Machie run this task
     debug: msg="{{ ansible_fqdn }}"
     when: info['stdout'] == "python"
    -
     name: hostname is startswith M run this task
     debug: msg="{{ ansible_fqdn }}"
     when: info['stdout'].startswith('M')
           

结果:

skipping: [sp-116.130]
ok: [sp-116-129] => {
    "msg": "192.168.116.129"
}

TASK [memtotal < 500M and processor_cores == 2 run this task] *********************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "mode02"
}
ok: [sp-116-129] => {
    "msg": "mode03"
}

TASK [all host run this task] *****************************************************************************************************************************************************************
changed: [sp-116.130]
changed: [sp-116-129]

TASK [hostname is python Machie run this task] ************************************************************************************************************************************************
skipping: [sp-116.130]
skipping: [sp-116-129]

TASK [hostname is startswith M run this task] *************************************************************************************************************************************************
skipping: [sp-116.130]
skipping: [sp-116-129]

PLAY RECAP ************************************************************************************************************************************************************************************
sp-116-129                 : ok=4    changed=1    unreachable=0    failed=0   
sp-116.130                 : ok=3    changed=1    unreachable=0    failed=0   
           

jinja2 filter

jiaja2.yaml 
---
   - 
    hosts: slave
    gather_facts: False
    vars: 
       list: [1,2,3,4,5]
       one: "1"
       str: "string"
    tasks:
    - 
     name: run commands
     shell: df -h
     register: info
    -
     name: debug pprint filter
     debug: msg="{{ info.stdout | pprint }}"
    -
     name: debug conditionals filter
     debug: msg="the run commands status is changed"
     when: info|changed
    - 
     name: debug int capitalize filter
     debug: msg="the int value {{ one | int }} the lower value is {{ str | capitalize }}"
    - 
     name: debug default filter
     debug: msg="the variable value is {{ ansible | default('ansible is not define') }}"
    -
     name: debug list max and min filter
     debug: msg="the list max value is {{ list | max }} the list min value is {{ list | min }}"
    -
     name: debug ramdom filter
     debug: msg="the list ramdom value is {{ list | random }} and generate a random value is {{ 1000 | random(1 ,10) }}"
    - 
     name: debug join filter
     debug: msg="the join filter value is {{ list | join("+") }}"
    -
     name: debug replace and regex_replace filter
     debug: msg="the replace value is {{ str | replace('t','T') }} the regex_replace value is {{ str | regex_replace('.*tr(.*)$','\\1') }}"
           

结果:

ansible-playbook  jiaja2.yaml 

PLAY [slave] **********************************************************************************************************************************************************************************

TASK [run commands] ***************************************************************************************************************************************************************************
changed: [sp-116.130]
changed: [sp-116-129]

TASK [debug pprint filter] ********************************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "u'Filesystem      Size  Used Avail Use% Mounted on\\nudev            225M  4.0K  225M   1% /dev\\ntmpfs            48M  948K   47M   2% /run\\n/dev/sda1        19G  5.2G   13G  30% /\\nnone            4.0K     0  4.0K   0% /sys/fs/cgroup\\nnone            5.0M     0  5.0M   0% /run/lock\\nnone            236M     0  236M   0% /run/shm\\nnone            100M     0  100M   0% /run/user'"
}
ok: [sp-116-129] => {
    "msg": "u'Filesystem      Size  Used Avail Use% Mounted on\\nudev            225M  4.0K  225M   1% /dev\\ntmpfs            48M  944K   47M   2% /run\\n/dev/sda1        19G  1.4G   17G   8% /\\nnone            4.0K     0  4.0K   0% /sys/fs/cgroup\\nnone            5.0M     0  5.0M   0% /run/lock\\nnone            236M     0  236M   0% /run/shm\\nnone            100M     0  100M   0% /run/user'"
}

TASK [debug conditionals filter] **************************************************************************************************************************************************************
[DEPRECATION WARNING]: Using tests as filters is deprecated. Instead of using `result|changed` instead use `result is changed`. This feature will be removed in version 2.9. Deprecation 
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Using tests as filters is deprecated. Instead of using `result|changed` instead use `result is changed`. This feature will be removed in version 2.9. Deprecation 
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [sp-116.130] => {
    "msg": "the run commands status is changed"
}
ok: [sp-116-129] => {
    "msg": "the run commands status is changed"
}

TASK [debug int capitalize filter] ************************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the int value 1 the lower value is String"
}
ok: [sp-116-129] => {
    "msg": "the int value 1 the lower value is String"
}

TASK [debug default filter] *******************************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the variable value is ansible is not define"
}
ok: [sp-116-129] => {
    "msg": "the variable value is ansible is not define"
}

TASK [debug list max and min filter] **********************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the list max value is 5 the list min value is 1"
}
ok: [sp-116-129] => {
    "msg": "the list max value is 5 the list min value is 1"
}

TASK [debug ramdom filter] ********************************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the list ramdom value is 1 and generate a random value is 651"
}
ok: [sp-116-129] => {
    "msg": "the list ramdom value is 2 and generate a random value is 11"
}

TASK [debug join filter] **********************************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the join filter value is 1+2+3+4+5"
}
ok: [sp-116-129] => {
    "msg": "the join filter value is 1+2+3+4+5"
}

TASK [debug replace and regex_replace filter] *************************************************************************************************************************************************
ok: [sp-116.130] => {
    "msg": "the replace value is sTring the regex_replace value is ing"
}
ok: [sp-116-129] => {
    "msg": "the replace value is sTring the regex_replace value is ing"
}

PLAY RECAP ************************************************************************************************************************************************************************************
sp-116-129                 : ok=9    changed=1    unreachable=0    failed=0   
sp-116.130                 : ok=9    changed=1    unreachable=0    failed=0