自动化运维工具Ansible实战(七)playbook循环

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

(一)简述

    在使用ansible做自动化运维的时候,免不了的要重复执行某些操作,如:添加几个用户,创建几个MySQL用户并为之赋予权限,操作某个目录下所有文件等等。好在playbook支持循环语句,可以使得某些需求很容易而且很规范的实现。


(二)常用的循环语句

1,with_items。with_items是playbooks中最基本也是最常用的循环语句:

语法:

1
2
3
4
5
6
7
8
9
tasks:
- name:Secure config files
     file : path= /etc/ {{ item }} mode=0600 owner=root group=root
     with_items:
         - my.cnf
         - shadow
         - fstab
     或with_items: "{{ somelist }}"
###上面的例子说明在/etc下创建权限级别为600,属主属组都是root三个文件
1
2
3
4
5
6
7
使用with_items迭代循环的变量可以是个单纯的列表,也可以是一个较为复杂 的数据结果,如字典类型:
tasks:
- name: add several  users
   user: name={{ item.name }} state=present  groups ={{ item. groups  }}
   with_items:
     - { name:  'testuser1' groups 'wheel'  }
     - { name:  'testuser2' groups 'root'  }


2、with_nested嵌套循环

示例:

1
2
3
4
5
6
tasks:
- name: give  users  access to multiple databases
   mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs= yes  password=foo
   with_nested:
     - [  'alice' 'bob'  ]
     - [  'clientdb' 'employeedb' 'providerdb'  ]

item[0]是循环的第一个列表的值['alice','bob']。item[1]是第二个列表的值。表示循环创建alice和bob两个用户,并且为其赋予在三个数据库上的所有权限。

也可以将用户列表事先赋值给一个变量:

1
2
3
4
5
6
tasks:
- name: here,  'users'  contains the above list of employees
   mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs= yes  password=foo
   with_nested:
     "`users`"
     - [  'clientdb' 'employeedb' 'providerdb'  ]


3、with_dict

with_dict可以遍历更复杂的数据结构。假如有如下变量内容:

1
2
3
4
5
6
7
users :
   alice:
     name: Alice Appleworth
     telephone: 123-456-7890
   bob:
     name: Bob Bananarama
     telephone: 987-654-3210
1
2
3
4
5
####现在需要输出每个用户的用户名和手机号:
tasks:
   - name: Print phone records
     debug: msg= "User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
     with_dict:  "{{ users }}"


4、with_fileglob文件匹配遍历

1
2
3
4
5
6
7
8
9
10
####可以指定一个目录,使用with_fileglob可以循环这个目录中的所有文件,示例如下:
tasks:
- name:Make key directory     
       file : path= /root/ .sshkeys ensure=directory mode=0700 owner=root group=root     
- name:Upload public keys     
       copy: src={{ item }} dest= /root/ .sshkeys mode=0600 owner=root group=root     
       with_fileglob:
         - keys/*.pub     
- name:Assemble keys into authorized_keys  file     
       assemble: src= /root/ .sshkeys dest= /root/ . ssh /authorized_keysmode =0600 owner=root group=root

5、with_subelement遍历子元素

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
users :
   - name: alice
     authorized:
       /tmp/alice/onekey .pub
       /tmp/alice/twokey .pub
     mysql:
         password: mysql-password
         hosts:
           "%"
           "127.0.0.1"
           "::1"
           "localhost"
         privs:
           "*.*:SELECT"
           "DB1.*:ALL"
   - name: bob
     authorized:
       /tmp/bob/id_rsa .pub
     mysql:
         password: other-mysql-password
         hosts:
           "db1"
         privs:
           "*.*:SELECT"
           "DB2.*:ALL"
1
2
3
4
5
6
7
###playbook中定义如下:
- user: name={{ item.name }} state=present generate_ssh_key= yes
   with_items:  "`users`"
- authorized_key:  "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"
   with_subelements:
      users
      - authorized
1
2
3
4
5
6
###也可以遍历嵌套的子列表:
- name: Setup MySQL  users
   mysql_user: name={{ item.0.name }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs |  join ( '/' ) }}
   with_subelements:
     users
     - mysql.hosts

6、with_sequence循环整数序列

with_sequence可以生成一个自增的整数序列,可以指定起始值和结束值,也可以指定增长步长。 参数以key=value的形式指定,format指定输出的格式。数字可以是十进制、十六进制、八进制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 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随机选择

从列表中随机取一个值:

1
2
3
4
5
6
- debug: msg={{ item }}
   with_random_choice:
      "go through the door"
      "drink from the goblet"
      "press the red button"
      "do nothing"

8、do-Util循环

示例:

1
2
3
4
5
- action: shell  /usr/bin/foo
   register: result
   until : result.stdout. find ( "all systems go" ) != -1
   retries: 5
   delay: 10

重复执行shell模块,当shell模块执行的命令输出内容包含"all systems go"的时候停止。重试5次,延迟时间10秒。retries默认值为3,delay默认值为5。任务的返回值为最后一次循环的返回结果。


9、循环注册变量

在循环中使用register时,保存的结果中包含results关键字,该关键字保存模块执行结果的列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
- shell:  echo  "{{ item }}"
   with_items:
     - one
     - two
   register:  echo
变量 echo 内容如下:
{
     "changed" true ,
     "msg" "All items completed" ,
     "results" : [
         {
             "changed" true ,
             "cmd" "echo \"one\" " ,
             "delta" "0:00:00.003110" ,
             "end" "2013-12-19 12:00:05.187153" ,
             "invocation" : {
                 "module_args" "echo \"one\"" ,
                 "module_name" "shell"
             },
             "item" "one" ,
             "rc" : 0,
             "start" "2013-12-19 12:00:05.184043" ,
             "stderr" "" ,
             "stdout" "one"
         },
         {
             "changed" true ,
             "cmd" "echo \"two\" " ,
             "delta" "0:00:00.002920" ,
             "end" "2013-12-19 12:00:05.245502" ,
             "invocation" : {
                 "module_args" "echo \"two\"" ,
                 "module_name" "shell"
             },
             "item" "two" ,
             "rc" : 0,
             "start" "2013-12-19 12:00:05.242582" ,
             "stderr" "" ,
             "stdout" "two"
         }
     ]
}
1
2
3
4
5
6
##遍历注册变量的结果:
- name: Fail  if  return  code is not 0
   fail:
     msg:  "The command ({{ item.cmd }}) did not have a 0 return code"
   when: item.rc != 0
   with_items:  "`echo`.`results`"

10、with_together遍历数据并行集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
示例:
- hosts: webservers
   remote_user: root
   vars:
     alpha: [  'a' , 'b' , 'c' , 'd' ]
     numbers: [ 1,2,3,4 ]
   tasks:
     - debug: msg= "{{ item.0 }} and {{ item.1 }}"
       with_together:
          "{{ alpha }}"
          "{{ numbers }}"
输出的结果为:
ok: [192.168.1.65] => (item=[ 'a' , 1]) => {
     "item" : [
         "a" ,
         1
     ],
     "msg" "a and 1"
}
ok: [192.168.1.65] => (item=[ 'b' , 2]) => {
     "item" : [
         "b" ,
         2
     ],
     "msg" "b and 2"
}
ok: [192.168.1.65] => (item=[ 'c' , 3]) => {
     "item" : [
         "c" ,
         3
     ],
     "msg" "c and 3"
}
ok: [192.168.1.65] => (item=[ 'd' , 4]) => {
     "item" : [
         "d" ,
         4
     ],
     "msg" "d and 4"
}

 

loop模块一般在下面的场景中使用

  1. 类似的配置模块重复了多遍

  2. fact是一个列表

  3. 创建多个文件,然后使用assemble聚合成一个大文件

  4. 使用with_fileglob匹配特定的文件管理


本文转自 lqbyz 51CTO博客,原文链接:http://blog.51cto.com/liqingbiao/1969595
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7天前
|
敏捷开发
【sgCreatePinyin】自定义小工具:敏捷开发→自动化生成拼音字段名称(字段名生成工具)
【sgCreatePinyin】自定义小工具:敏捷开发→自动化生成拼音字段名称(字段名生成工具)
|
22天前
|
jenkins 测试技术 持续交付
现代软件测试中的自动化工具与挑战
随着软件开发领域的不断发展,自动化测试工具在测试过程中扮演着越来越重要的角色。本文将探讨现代软件测试中自动化工具的应用及面临的挑战,旨在帮助开发人员和测试人员更好地理解和应对自动化测试中的问题。
|
7天前
|
敏捷开发
【sgCreateTableData】自定义小工具:敏捷开发→自动化生成表格数据数组[基于el-table]
【sgCreateTableData】自定义小工具:敏捷开发→自动化生成表格数据数组[基于el-table]
|
15天前
|
Java 测试技术 API
软件测试中的自动化工具与策略
软件测试是确保软件质量的重要环节,而自动化测试工具和策略的应用在提高测试效率和准确性方面发挥着重要作用。本文将介绍几种常见的自动化测试工具,并探讨在软件测试中应用自动化测试的最佳实践和策略。
|
17天前
|
Web App开发 Java 测试技术
深入理解与应用软件自动化测试工具Selenium
随着软件开发的快速发展,软件测试在保证产品质量方面发挥着越来越重要的作用。其中,自动化测试以其效率高、成本低的特点受到了广大开发者的欢迎。本文主要介绍了自动化测试工具Selenium的基本概念、原理以及在实际开发中的应用,旨在帮助读者更好地理解和使用Selenium进行高效的自动化测试。
22 4
|
24天前
|
人工智能 运维 Prometheus
现代运维中的自动化工具与挑战
随着信息技术的不断发展,现代运维工作日益复杂且关键。本文将探讨现代运维中自动化工具的应用与挑战,介绍各类自动化工具在提高效率、降低风险方面的作用,并讨论在实际应用中可能面临的问题与解决方法。
20 4
|
25天前
|
人工智能 测试技术 虚拟化
现代软件测试中的自动化工具与技术
随着信息技术的迅猛发展,现代软件开发和测试领域也在不断创新。本文将探讨现代软件测试中自动化工具与技术的应用。通过分析自动化测试的优势、挑战以及最佳实践,帮助读者更好地理解当前软件测试领域的发展趋势,并为实际工作提供参考。
16 1
|
6月前
|
运维 Shell Linux
Ansible自动化运维工具之常用模块使用实战(5)
Ansible自动化运维工具之常用模块使用实战(5)
|
8月前
|
网络协议 网络安全
Ansible模块介绍——防火墙模块
Ansible模块介绍——防火墙模块
136 0
|
6月前
|
运维 Linux
Ansible自动化运维工具之常用模块使用实战(6)
Ansible自动化运维工具之常用模块使用实战(6)