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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

(一)简述

    在使用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
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
4月前
|
数据采集 机器学习/深度学习 人工智能
运维人的“福音”?AI 驱动的自动化网络监控到底香不香!
运维人的“福音”?AI 驱动的自动化网络监控到底香不香!
321 0
|
26天前
|
人工智能 运维 安全
运维老哥的救星?AI 驱动的自动化配置管理新趋势
运维老哥的救星?AI 驱动的自动化配置管理新趋势
80 11
|
3月前
|
机器学习/深度学习 人工智能 运维
运维不背锅,从“自动修锅”开始:AI自动化运维是怎么回事?
运维不背锅,从“自动修锅”开始:AI自动化运维是怎么回事?
295 49
|
2月前
|
运维 Prometheus 监控
系统崩了怪运维?别闹了,你该问问有没有自动化!
系统崩了怪运维?别闹了,你该问问有没有自动化!
100 9
|
2月前
|
运维 监控 应用服务中间件
运维打铁: Ruby 脚本在运维自动化中的应用探索
Ruby 是一种简洁、动态类型的编程语言,适合运维自动化任务。本文介绍了其在服务器配置管理、定时任务执行和日志分析处理中的应用,并提供了代码示例,展示了 Ruby 在运维自动化中的实际价值。
83 2
|
2月前
|
机器学习/深度学习 运维 监控
智能运维Agent:自动化运维的新范式
在数字化转型浪潮中,智能运维Agent正重塑运维模式。它融合人工智能与自动化技术,实现从被动响应到主动预防的转变。本文详解其四大核心功能:系统监控、故障诊断、容量规划与安全响应,探讨如何构建高效、可靠的自动化运维体系,助力企业实现7×24小时无人值守运维,推动运维效率与智能化水平全面提升。
434 0
|
2月前
|
运维 监控 安全
从实践到自动化:现代运维管理的转型与挑战
本文探讨了现代运维管理从传统人工模式向自动化转型的必要性与路径,分析了传统运维的痛点,如效率低、响应慢、依赖经验等问题,并介绍了自动化运维在提升效率、降低成本、增强系统稳定性与安全性方面的优势。结合技术工具与实践案例,文章展示了企业如何通过自动化实现运维升级,推动数字化转型,提升业务竞争力。
|
3月前
|
人工智能 缓存 运维
运维人不用秃头了?AI自动化配置管理了解一下!
运维人不用秃头了?AI自动化配置管理了解一下!
78 0
|
6月前
|
机器学习/深度学习 人工智能 运维
机器学习+自动化运维:让服务器自己修Bug,运维变轻松!
机器学习+自动化运维:让服务器自己修Bug,运维变轻松!
264 14
|
7月前
|
监控 jenkins 测试技术
Ansible与Jenkins:自动化工具的对比
Ansible和Jenkins是自动化领域的两大巨头。Ansible专注于配置管理和任务自动化,采用无代理架构,使用YAML定义配置,具有幂等性和可扩展性。Jenkins则擅长持续集成和持续交付(CI/CD),支持丰富的插件生态系统,适用于自动化构建、测试和部署。两者各有优势,Ansible适合配置管理与大规模部署,Jenkins则在CI/CD方面表现出色。结合使用可创建更强大的自动化工作流,提升团队生产力和软件质量。选择工具时应根据具体需求决定。