当前位置: 代码迷 >> 综合 >> ansible之playbook循环
  详细解决方案

ansible之playbook循环

热度:78   发布时间:2024-01-21 06:27:48.0

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

例子一:安装多个软件。
 

tasks:- name: "Install Packages"yum: name={
   { item }} state=latestwith_items:- httpd- mysql-server- php

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

- hosts: slaveremote_user: suixiaofengsudo: yestasks:- 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: slavegather_facts: Falsetasks: - name: debug loopsdebug: 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: allgather_facts: Falsevars:user:Bob_hou:name: Bob_Houshell: bashJmilk:name: Jmilkshell: zshtasks:-name: debug loopsdebug: "msg=\"name -----> {
   {item.key }} value -----> {
   {item.value.name }} shell -----> {
   { item.value.shell }}\""with_dict: "{
   { user }}"

文件匹配loops:

cat fileloops.yaml 
---- hosts: slavegather_facts: Falsetasks:- name: debug loopsdebug: msg="this is ------> {
   { item }}"with_fileglob:- /home/upsmart/yaml/*yaml 

随机选择loops:

with_random_choice
---
- hosts: slavegather_facts: Falsetasks:- name: debug loopsdebug: 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   

upsmart@mode01:~/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: slavegather_facts: Falsetasks:-name: debug loopsshell: cat /root/Ansibleregister: hostuntil: host.stdout.startswith("cat")retries: 5delay: 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: slavegather_facts: Truetasks: - name: debug loopsdebug: msg="files -----> {
   { item }}"with_first_found:-"{
   { ansible_distribution }}.yaml"- "panduan1.yaml" 

register Loops:

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

例子:

----hosts: slavegather_facts: Truetasks:- name: debug loopsshell: "{
   { item }}"with_items:- hostname- uname- uname -a register: ret- name: display loopsdebug: msg="{% for i in ret.results %} {
   { i.stdout }} {% endfor %}"

playbook lookups:

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

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

2.lookups password

对传入的内容进行加密;

--- - hosts: slavegather_facts: Falsevars:contents: "{
   { lookup('password','suixiaofeng') }}"tasks:-  name: debug lookupsdebug: msg="the contents is {
   { contents }}"

3.lookups pipe

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

---- hosts: slavegather_facts: Falsevars: contents: "{
   { lookup('pipe','hostname') }}"tasks:- name: debug lookupsdebug: msg="the contents is {% for i in contents.split("\n") %} {
   { i }} {% endfor %}"

4.lookups redis_kv

从redis数据库中get数据。

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

5.lookups template

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

---- hosts: slavegather_facts: Truevars: contents: "{
   { lookup('template','./lookups.j2') }}"tasks: - name: debug lookupsdebug: 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: slavetasks:- name: host 192.168.116.129 run this taskdebug: msg="{
   { ansible_default_ipv4.address }}"when: ansible_default_ipv4.address == "192.168.116.129"-name: memtotal < 500M and processor_cores == 2 run this taskdebug: msg="{
   { ansible_fqdn }}"when: ansible_memtotal_mb < 500 or ansible_processor_cores == 2-name: all host run this taskshell: hostnameregister: info- name: hostname is python Machie run this taskdebug: msg="{
   { ansible_fqdn }}"when: info['stdout'] == "python"-name: hostname is startswith M run this taskdebug: 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: slavegather_facts: Falsevars: list: [1,2,3,4,5]one: "1"str: "string"tasks:- name: run commandsshell: df -hregister: info-name: debug pprint filterdebug: msg="{
   { info.stdout | pprint }}"-name: debug conditionals filterdebug: msg="the run commands status is changed"when: info|changed- name: debug int capitalize filterdebug: msg="the int value {
   { one | int }} the lower value is {
   { str | capitalize }}"- name: debug default filterdebug: msg="the variable value is {
   { ansible | default('ansible is not define') }}"-name: debug list max and min filterdebug: msg="the list max value is {
   { list | max }} the list min value is {
   { list | min }}"-name: debug ramdom filterdebug: msg="the list ramdom value is {
   { list | random }} and generate a random value is {
   { 1000 | random(1 ,10) }}"- name: debug join filterdebug: msg="the join filter value is {
   { list | join("+") }}"-name: debug replace and regex_replace filterdebug: 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