在写 playbook 的时候发现了很多 task 都要重复引用某个相同的模块,如果按照传统的写法最少要写10次,这样会使得 playbook很臃肿。
Ansible提供了两个用于创建循环的关键字:loop和with_*,目前我们习惯于用loop替代with_*
1、---对迭代项的引用,固定变量名为"item";
2、---要在task中使用with_items或loop关键字给定要迭代的元素列表;
一、使用循环批量安装软件
方法一:这里把loop换成with_items效果一样
# vim /tmp/item.yaml
---
- hosts: web1
tasks:
- name: install some package
yum:
name: "{{ item }}"
state=present
loop:
- nginx
- htop
- keepalived
# ansible-playbook /tmp/item.yaml
方法二:采用变量的方式安装
# vim /tmp/item.yaml
---
- hosts: web1
tasks:
- name: install some package
yum:
name: "{{ item }}"
state: present
loop: "{{ package }}"
vars:
- package:
- nginx
- htop
- keepalived
# ansible-playbook /tmp/item.yaml
二、使用循环批量创建用户
方法一:使用loop循环
# vim /tmp/item.yaml
# vim /tmp/item.yaml
---
- hosts: web1
tasks:
- name: add some groups
group:
name: "{{ item }}"
state: present
loop: [ g1 , g2 , g3 ]
- name: add some users
user:
name: "{{ item.name }}"
groups: "{{ item.group }}"
uid: "{{ item.uid }}"
state: present
loop:
- { name: "user1" , groups: "g1" , uid: "2000" }
- { name: "user2" , groups: "g2" , uid: "2001" }
- { name: "user3" , groups: "g3" , uid: "2002" }
# ansible-playbook /tmp/item.yaml
方法二:引入外部yaml文件
# vim /tmp/item_var.yaml
---
- users:
- name: "user1"
group: "g1"
- name: "user2"
group: "g2"
- name: "user3"
group: "g3"
- group: [ g1 , g2 , g3 ]
# vim /tmp/item.yaml
---
- hosts: web1
vars_files:
- /root/users.yaml
tasks:
- name: add some groups
group:
name: "{{ item }}"
state: present
loop: "{{ groups }}"
- name: add some users
user:
name: "{{ item.name }}"
groups: "{{ item.group }}"
uid: "{{ item.uid }}"
state: present
loop: "{{ users }}"
# ansible-playbook /tmp/item.yaml
三、使用循环批量拷贝文件
# vim file_test.yaml
---
- file_test:
- src: /root/a.txt
dest: /tmp/
owner: root
group: root
mode: 0644
- src: /root/b.txt
dest: /tmp/
owner: root
group: root
mode: 0644
- src: /root/c.txt
dest: /tmp/
owner: root
group: root
mode: 0644
# vim /tmp/loopfile.yaml
---
- hosts: web1
vars_files:
- /root/file_test.yaml
tasks:
- name: copy file
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
loop: "{{ file_test }}"
# - { src: "/root/a.txt" , dest: "/tmp/", owner: "root", group: "root", mode: "0644" }
# - { src: "/root/b.txt" , dest: "/tmp/", owner: "root", group: "root", mode: "0644" }
# - { src: "/root/c.txt" , dest: "/tmp/", owner: "root", group: "root", mode: "0644" }
# ansible-playbook /tmp/loopfile.yaml
四、嵌套循环with_nested
# vim /tmp/with_nested.yaml
---
- hosts: web1
tasks:
- name: mkdir
file:
path: "/testdir/{{item.0}}/{{item.1}}/{{item.2}}"
state: directory
with_nested:
- [ a, b, c ]
- [ test1, test2 ]
- [ a1, a2 ]
# ansible-playbook /tmp/with_nested.yaml
执行后的结果
# tree /testdir/
/testdir/
├── a
│ ├── test1
│ │ ├── a1
│ │ └── a2
│ └── test2
│ ├── a1
│ └── a2
├── b
│ ├── test1
│ │ ├── a1
│ │ └── a2
│ └── test2
│ ├── a1
│ └── a2
└── c
├── test1
│ ├── a1
│ └── a2
└── test2
├── a1
└── a2
五、对哈希表循环(key:value)
# vim /tmp/key_value.yaml
---
- hosts: web1
vars:
- users:
- user1:
name: tom
age: 20
telephone: 123-456-7890
- user2:
name: jerry
age: 22
telephone: 987-654-3210
tasks:
- name: print phone
debug:
msg: "User {{ item.key }} is {{ item.value.name }} 年龄: {{ item.value.age }} 联系方式: {{ item.value.telephone }}"
with_dict: "{{ users }}"
# ansible-playbook /tmp/key_value.yaml
输出结果:
ok: [192.168.58.101] => (item={'key': 'user1', 'value': {'name': 'tom', 'telephone': '123-456-7890'}}) => {
"msg": "User user1 is tom 123-456-7890"
}
ok: [192.168.58.101] => (item={'key': 'user2', 'value': {'name': 'jerry', 'telephone': '987-654-3210'}}) => {
"msg": "User user2 is jerry 987-654-3210"
六、文件列表使用循环with_fileglob
# vim /tmp/with_fileglob.yaml
---
- hosts: web1
tasks:
- name: copy file *
copy:
src: "{{ item }}"
dest: /tmp
owner: root
mode: 0600
with_fileglob:
- /tmp/copy/*
- /root/index.html
# - /tmp/copy/a.txt
# - /tmp/copy/b.txt
相当于批量化拷贝文件到被控端,使用loop也可以循环,但是不能指定/tmp/copy/*,只能一个个列出需要循环拷贝的文件
# ansible-playbook /tmp/with_fileglob.yaml