Ansible循环语句

1 简介

我们在编写playbook的时候,不可避免的要执行一些重复性操作,比如指安装软件包,批量创建用户,操作某个目录下的所有文件等。正如我们所说,ansible一门简单的自动化语言,所以流程控制、循环语句这些编程语言的基本元素它同样都具备。

在Ansible 2.5以前,playbook通过不同的循环语句以实现不同的循环,这些语句使用with_作为前缀。这些语法目前仍然兼容,但在未来的某个时间点,会逐步废弃。

2 with_items

[root@node1 ansible]# vim with_items.yml

- hosts: demo2.example.com
gather_facts: no
tasks:
- debug:
msg: "{{ item }}"
with_items: "{{ groups.webserver }}"

相当于

- hosts: demo2.example.com
gather_facts: no
tasks:
- debug:
msg: "{{ item }}"
with_items:
- demo1.example.com
- demo2.example.com
- demo3.example.com

[root@node1 ansible]# ansible-playbook with_items.yml

ok: [demo2.example.com] => (item=demo1.example.com) => {
"msg": "demo1.example.com"
}
ok: [demo2.example.com] => (item=demo2.example.com) => {
"msg": "demo2.example.com"
}
ok: [demo2.example.com] => (item=demo3.example.com) => {
"msg": "demo3.example.com"
}

[root@node1 ansible]# vim with_items.yml

- hosts: demo2.example.com
gather_facts: no
tasks:
- name: "create directory"
file:
path: "/tmp/{{ item.path1 }}/{{ item.path2 }}"
state: directory
with_items:
- {path1: a, path2: b}
- {path1: c, path2: d}

执行

[root@node1 ansible]# ansible demo2.example.com  -m shell -a "ls -l /tmp/{a,c}"

/tmp/a:
total 0
drwxr-xr-x 2 root root 6 May 2 01:01 b /tmp/c:
total 0
drwxr-xr-x 2 root root 6 May 2 01:01 d

with_list与 with_items一样,也是用于循环列表。区别是,如果列表的值也是列表,with_iems会将第一层嵌套的列表拉平,而with_list会将值作为一个整体返回。with_flatten会将所有列表全部拉平

[[1,2,[3,4]],[5,6],7,8]

with_item------->[1,2,[3,4],5,6,7,8]    拉平第一层

with_list--------->[[1,2,[3,4]],[5,6],7,8]   整体返回

with_flatten----->[1,2,3,4,5,6,7,8]     全部拉平

3 with_togther

将两个列表对齐合并

[root@node1 ansible]# vim with_items.yml

- hosts: demo2.example.com
gather_facts: no
vars:
alpha: [ 'a','b','c','d']
numbers: [ 1,2,3,4 ]
tasks:
- debug: msg="{{ item.0 }} and {{ item.1 }}"
with_together:
- "{{ alpha }}"
- "{{ numbers }}"

[root@node1 ansible]# ansible-playbook with_items.yml

ok: [demo2.example.com] => (item=[u'a', 1]) => {
"msg": "a and 1"
}
ok: [demo2.example.com] => (item=[u'b', 2]) => {
"msg": "b and 2"
}
ok: [demo2.example.com] => (item=[u'c', 3]) => {
"msg": "c and 3"
}
ok: [demo2.example.com] => (item=[u'd', 4]) => {
"msg": "d and 4"
}

4 with_nested

嵌套循环,相当于像个for

[root@node1 ansible]# vim with_items.yml

- hosts: demo2.example.com
gather_facts: no
tasks:
- debug: msg="name is {{ item[0] }} vaule is {{ item[1] }} num is {{ item[2] }}"
with_nested:
- ['alice','bob']
- ['a','b','c']
- ['1','2','3']

item[0]是循环的第一个列表的值["alice","bob"] item[1]是第二个列表的值;以上的执行输出如下:

[root@node1 ansible]# ansible-playbook with_items.yml

ok: [demo2.example.com] => (item=[u'alice', u'a', u'1']) => {
"msg": "name is alice vaule is a num is 1"
}
ok: [demo2.example.com] => (item=[u'alice', u'a', u'2']) => {
"msg": "name is alice vaule is a num is 2"
}
ok: [demo2.example.com] => (item=[u'alice', u'a', u'3']) => {
"msg": "name is alice vaule is a num is 3"
}
ok: [demo2.example.com] => (item=[u'alice', u'b', u'1']) => {
"msg": "name is alice vaule is b num is 1"
}
ok: [demo2.example.com] => (item=[u'alice', u'b', u'2']) => {
"msg": "name is alice vaule is b num is 2"
}
ok: [demo2.example.com] => (item=[u'alice', u'b', u'3']) => {
"msg": "name is alice vaule is b num is 3"
}
ok: [demo2.example.com] => (item=[u'alice', u'c', u'1']) => {
"msg": "name is alice vaule is c num is 1"
}
ok: [demo2.example.com] => (item=[u'alice', u'c', u'2']) => {
"msg": "name is alice vaule is c num is 2"
}
ok: [demo2.example.com] => (item=[u'alice', u'c', u'3']) => {
"msg": "name is alice vaule is c num is 3"
}
ok: [demo2.example.com] => (item=[u'bob', u'a', u'1']) => {
"msg": "name is bob vaule is a num is 1"
}
ok: [demo2.example.com] => (item=[u'bob', u'a', u'2']) => {
"msg": "name is bob vaule is a num is 2"
}
ok: [demo2.example.com] => (item=[u'bob', u'a', u'3']) => {
"msg": "name is bob vaule is a num is 3"
}
ok: [demo2.example.com] => (item=[u'bob', u'b', u'1']) => {
"msg": "name is bob vaule is b num is 1"
}
ok: [demo2.example.com] => (item=[u'bob', u'b', u'2']) => {
"msg": "name is bob vaule is b num is 2"
}
ok: [demo2.example.com] => (item=[u'bob', u'b', u'3']) => {
"msg": "name is bob vaule is b num is 3"
}
ok: [demo2.example.com] => (item=[u'bob', u'c', u'1']) => {
"msg": "name is bob vaule is c num is 1"
}
ok: [demo2.example.com] => (item=[u'bob', u'c', u'2']) => {
"msg": "name is bob vaule is c num is 2"
}
ok: [demo2.example.com] => (item=[u'bob', u'c', u'3']) => {
"msg": "name is bob vaule is c num is 3"
}

with_cartesian功能完全一样

5 with_index_items

在循环处理列表时,为列表的每一项添加索引

[root@node1 ansible]# vim with_items.yml

- hosts: demo2.example.com
gather_facts: no
tasks:
- debug:
msg: "{{ item }}"
with_indexed_items:
- test1
- test2
- test3

[root@node1 ansible]# ansible-playbook with_items.yml

ok: [demo2.example.com] => (item=[0, u'test1']) => {
"msg": [
0,
"test1"
]
}
ok: [demo2.example.com] => (item=[1, u'test2']) => {
"msg": [
1,
"test2"
]
}
ok: [demo2.example.com] => (item=[2, u'test3']) => {
"msg": [
2,
"test3"
]
}

6 with_sequence

用于返回一个数字序列

参数说明

start:指走起始值

end:指定结束值

stride:指定步长,即从 start至end,每次增加的值

count:生成连续的数字序列,从1开始,到 count的值结束

format:格式化输出类似于lnuX命令行中的 printi格式化输出

- hosts: all
tasks:
# create groups
- group: name=evens state=present
- group: name=odds state=present
# create some test users
- user: name={{ item }} state=present groups=evens
with_sequence: start=0 end=32 format=testuser%02d
# create a series of directories with even numbers for some reason
- file: dest=/var/stuff/{{ item }} state=directory
with_sequence: start=4 end=16 stride=2 # stride用于指定步长
# a simpler way to use the sequence plugin
# create 4 groups
- group: name=group{{ item }} state=present
with_sequence: count=4

7 with_random_choice

- debug: msg={{ item }}
with_random_choice:
- "go through the door"
- "drink from the goblet"
- "press the red button"
- "do nothing"

8 with_dict

[root@node1 ansible]# vi with_items.yml

- hosts: demo2.example.com
gather_facts: no
vars:
users:
alice:
name: Alice Appleworth
telephone: 123-456-7890
bob:
name: Bob Bananarama
telephone: 987-654-3210 # 现在需要输出每个用户的用户名和手机号:
tasks:
- name: Print phone records
debug:
msg: "User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
with_dict: "{{ users }}"

[root@node1 ansible]# ansible-playbook with_items.yml

ok: [demo2.example.com] => (item={'value': {u'name': u'Bob Bananarama', u'telephone': u'987-654-3210'}, 'key': u'bob'}) => {
"msg": "User bob is Bob Bananarama (987-654-3210)"
}
ok: [demo2.example.com] => (item={'value': {u'name': u'Alice Appleworth', u'telephone': u'123-456-7890'}, 'key': u'alice'}) => {
"msg": "User alice is Alice Appleworth (123-456-7890)"
}

9 with_subelement

假如现在需要遍历一个用户列表,并创建每个用户,而且还需要为每个用户配置以特定的SSH key登录。变量文件内容如下:

with_file,是在主控端完成

上面with_file用于获取文的内容,而 with_fileglob则用于匹配文件名称。可以通过该关键字,在指定的目录中匹配符合模式的文件名。与 with_file相同的是,with_ fileglob操作的文件也是主控端的文件而非被控端的文件

10 loop关键字说明

在playbook中使用循环,直接使用loop关键字即可。

with_list,with_item可以直接试用loop代替

with_flatten,loop:"{{  testlist| flatten}}"

启动httpd和postfilx服务:

tasks:
- name: postfix and httpd are running
service:
name: "{{ item }}"
state: started
loop:
- postfix
- httpd

也可以将loop循环的列表提前赋值给一个变量,然后在循环语句中调用:

#cat test_services.yml
test_services:
- postfix
- httpd # cat install_pkgs.yml
- name: start services
hosts: test
vars_files:
- test_services.yml
tasks:
- name: postfix and httpd are running
service:
name: "{{ item }}"
state: started
loop: "{{ test_services }}"

下面是一个循环更复杂类型数据的示例:

# cat test_loop.yml
- name: test loop
hosts: test
tasks:
- name: add www group
group:
name: www
- name: add several users
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
loop:
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'www' }

11 在循环语句中注册变量

下面是一个register的变量在循环中使用的例子:

# cat register_loop.yml
- name: registered variable usage as a loop list
hosts: test
tasks:
- name: ensure /mnt/bkspool exists
file:
path: /mnt/bkspool
state: directory
- name: retrieve the list of home directories
command: ls /home
register: home_dirs
- name: Show home_dirs results
debug:
var: home_dirs.stdout_lines
- name: add home dirs to the backup spooler
file:
path: /mnt/bkspool/{{ item }}
src: /home/{{ item }}
state: link
force: yes
loop: "{{ home_dirs.stdout_lines }}"

在循环语句中注册变量:

- name: Loop Register test
gather_facts: no
hosts: webserver
tasks:
- name: Looping Echo Task
shell: "echo this is my item: {{ item }}"
loop:
- one
- two
register: echo_results
- name: Show echo_results variable
debug:
var: echo_results

执行语句,可以看到变量的

 "echo_results": {
"changed": true,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": true,
"cmd": "echo this is my item: one",
"delta": "0:00:00.004610",
"end": "2020-05-02 02:16:40.824482",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "echo this is my item: one",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": "one",
"rc": 0,
"start": "2020-05-02 02:16:40.819872",
"stderr": "",
"stderr_lines": [],
"stdout": "this is my item: one",
"stdout_lines": [
"this is my item: one"
]
},
{
"ansible_loop_var": "item",
"changed": true,
"cmd": "echo this is my item: two",
"delta": "0:00:00.006417",
"end": "2020-05-02 02:16:41.372681",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "echo this is my item: two",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": "two",
"rc": 0,
"start": "2020-05-02 02:16:41.366264",
"stderr": "",
"stderr_lines": [],
"stdout": "this is my item: two",
"stdout_lines": [
"this is my item: two"
]
}
]
}
}

返回结果为一个字典列表


博主声明:本文的内容来源主要来自誉天教育晏威老师,由本人实验完成操作验证,需要的博友请联系誉天教育(http://www.yutianedu.com/),获得官方同意或者晏老师(https://www.cnblogs.com/breezey/)本人同意即可转载,谢谢!

010.Ansible_palybook 循环语句的更多相关文章

  1. Python学习笔记(二):条件控制语句与循环语句及常用函数的用法

    总结的内容: 1.条件控制语句 2.while循环语句 3.for循环语句 4.函数的用法 一.条件控制语句 1.介绍 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决 ...

  2. 01.Python基础-2.判断语句和循环语句

    1判断语句 1.1判断语句介绍 满足条件才能做某件事 1.2 if语句 if 条件: 语句块 在if判断条件的时候 False:False, 0, '', None, [] True :基本除上面之外 ...

  3. 【python之路4】循环语句之while

    1.while 循环语句 #!/usr/bin/env python # -*- coding:utf-8 -*- import time bol = True while bol: print '1 ...

  4. python之最强王者(3)——变量,条件、循环语句

    1.Python 变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的 ...

  5. #9.5课堂JS总结#循环语句、函数

    一.循环语句 1.for循环 下面是 for 循环的语法: for (语句 1; 语句 2; 语句 3) { 被执行的代码块 } 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块) ...

  6. 详解Python中的循环语句的用法

    一.简介 Python的条件和循环语句,决定了程序的控制流程,体现结构的多样性.须重要理解,if.while.for以及与它们相搭配的 else. elif.break.continue和pass语句 ...

  7. 【java开发】分支语句、循环语句学习

    一.Java分支语句类型 if-else 语句 switch 关于if-esle语句可以拆分为三种 if语句 if(条件){语句块;} if-else语句if(条件语句){语句块;} if-else ...

  8. python3循环语句while

    Python的循环语句有for和while语句,这里讲while语句. Python中while语句的一般形式: while 条件判断 : 语句 需要注意冒号和缩进.另外,注意Python中没有do. ...

  9. 20.SqlServer中if跟循环语句

    --if语句declare @i int begin print @i end else --循环语句 declare @i int begin insert into grade(classname ...

随机推荐

  1. SwiftUI 简明教程之文本与图片

    本文为 Eul 样章,如果您喜欢,请移步 AppStore/Eul 查看更多内容. Eul 是一款 SwiftUI & Combine 教程类 App(iOS.macOS),以文章(文字.图片 ...

  2. 干掉 Feign,Spring Cloud Square 组件发布

    Spring Cloud Square 是什么 谈起 Spring Cloud 生态大家一定对 Feign 不陌生,如下图所示,Feign 可以把底层(okhttp.httpclient)Rest 的 ...

  3. 自动化kolla-ansible部署ubuntu20.04+openstack-victoria之系统安装-03

    自动化kolla-ansible部署ubuntu20.04+openstack-victoria之系统安装-03  欢迎加QQ群:1026880196  进行交流学习 一.镜像下载 网易源: http ...

  4. IDEA通过Maven打包JavaFX工程(OpenJFX11)

    1 概述 最近研究JFX,写出来了但是打包不了,这...尴尬... IDEA的文档说只支持Java8打成jar包: 尝试过直接使用Maven插件的package,不行,也尝试过Build Artifa ...

  5. mariadb_1 数据库介绍及基本操作

    数据库介绍 1.什么是数据库? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库提供的多种方法来管理 ...

  6. 4. selectKey语句属性配置细节

    selectKey语句属性配置细节:

  7. .Net Core 集成 Kafka

    最近维护的一个系统并发有点高,所以想引入一个消息队列来进行削峰.考察了一些产品,最终决定使用kafka来当做消息队列.以下是关于kafka的一些知识的整理笔记. kafka kafka 是分布式流式平 ...

  8. 473. Matchsticks to Square

    Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match ...

  9. 仅用一句SQL更新整张表的涨跌幅、涨跌率

    问题场景 各大平台店铺的三项评分(物流.服务.商品)变化情况: 商品每日价格的变化记录: 股票的实时涨跌浮: 复现场景 表:主键ID,商品编号,记录时的时间,记录时的价格,创建时间. 问题:获取每个商 ...

  10. php读取目录下的所有文件

    php读取目录下的所有文件 $path = './use'; $result = scanFile($path); function scanFile($path) { global $result; ...