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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 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
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
运维 应用服务中间件 网络安全
自动化运维的新篇章:使用Ansible进行服务器配置管理
【10月更文挑战第34天】在现代IT基础设施的快速迭代中,自动化运维成为提升效率、确保一致性的关键手段。本文将通过介绍Ansible工具的使用,展示如何实现高效的服务器配置管理。从基础安装到高级应用,我们将一步步揭开自动化运维的神秘面纱,让你轻松掌握这一技术,为你的运维工作带来革命性的变化。
|
6天前
|
机器学习/深度学习 数据采集 运维
智能化运维:机器学习在故障预测和自动化响应中的应用
智能化运维:机器学习在故障预测和自动化响应中的应用
25 4
|
4天前
|
运维 负载均衡 Ubuntu
自动化运维的利器:Ansible入门与实践
【10月更文挑战第31天】在当今快速发展的信息技术时代,高效的运维管理成为企业稳定运行的关键。本文将引导读者了解自动化运维工具Ansible的基础概念、安装步骤、基本使用,以及如何通过实际案例掌握其核心功能,从而提升工作效率和系统稳定性。
|
12天前
|
缓存 运维 应用服务中间件
自动化运维的新篇章:使用Ansible进行配置管理
【10月更文挑战第23天】随着云计算和微服务架构的兴起,传统的手动运维方式已经无法满足现代IT基础设施的需求。自动化运维成为提升效率、减少错误的关键。本文将介绍如何使用Ansible,一个流行的开源自动化工具,来简化配置管理和部署流程。我们将从基础概念出发,逐步深入到实战应用,展示如何通过编写Playbook来实现服务器的自动化配置和管理。
|
8天前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
21 2
|
9天前
|
运维 应用服务中间件 调度
自动化运维:使用Ansible实现服务器批量管理
【10月更文挑战第26天】在当今快速发展的IT领域,自动化运维已成为提升效率、降低人为错误的关键技术手段。本文通过介绍如何使用Ansible这一强大的自动化工具,来简化和加速服务器的批量管理工作,旨在帮助读者理解自动化运维的核心概念和实践方法。文章将围绕Ansible的基础使用、配置管理、任务调度等方面展开,通过实际案例引导读者深入理解自动化运维的实现过程,最终达到提高运维效率和质量的目的。
|
9天前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
23 2
|
14天前
|
运维 应用服务中间件 持续交付
自动化运维的利器:Ansible入门与实践
【10月更文挑战第21天】在现代IT基础设施的管理中,自动化运维已成为提升效率、降低错误率的关键。Ansible,作为一种简单而强大的自动化工具,正被广泛应用于配置管理、应用部署和任务自动化等领域。本文将引导你了解Ansible的基本概念,通过实际案例展示如何利用Ansible简化日常运维工作,并探讨其在现代IT运维中的应用价值。无论你是新手还是有经验的系统管理员,这篇文章都将为你开启Ansible的高效之旅提供指导。
|
17天前
|
运维 监控 jenkins
运维自动化实战:利用Jenkins构建高效CI/CD流程
【10月更文挑战第18天】运维自动化实战:利用Jenkins构建高效CI/CD流程
|
20天前
|
运维 负载均衡 安全
自动化运维:使用Ansible进行服务器配置管理
【10月更文挑战第15天】在本文中,我们将探讨如何利用Ansible这一强大的自动化工具来简化和加速服务器的配置管理工作。通过实际案例和代码示例,我们将展示Ansible如何帮助运维人员高效地进行软件部署、系统更新和日常维护任务,从而提升工作效率并减少人为错误。