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