当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为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