自动化运维工具Ansible实战(六)playbook常用的模块

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

(一)简述

    playbook的模块与在ansible命令行下使用的模块有一些不同。这主要是因为在playbook中会使用到一些facts变量和一些通过setup模块从远程主机上获取到的变量。有些模块没法在命令行下运行,就是因为它们需要这些变量。而且即使那些可以在命令行下工作的模块也可以通过playbook的模块获取一些更高级的功能。


(二)常用的模块

1,template模块

    在实际应用中,我们的配置文件有些地方可能会根据远程主机的配置的不同而有稍许的不同,template可以使用变量来接收远程主机上setup收集到的facts信息,针对不同配置的主机,定制配置文件。用法大致与copy模块相同。

常见的参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
backup:如果原目标文件存在,则先备份目标文件
dest:目标文件路径
force:是否强制覆盖,默认为 yes
group:目标文件属组
mode:目标文件的权限
owner:目标文件属主
src:源模板文件路径
validate:在复制之前通过命令验证目标文件,如果验证通过则复制
官方简单示例:
- template: src= /mytemplates/foo .j2 dest= /etc/file .conf owner=bin group=wheel mode=0644
- template: src= /mytemplates/foo .j2 dest= /etc/file .conf owner=bin group=wheel mode= "u=rw,g=r,o=r"
- template: src= /mine/sudoers  dest= /etc/sudoers  validate= 'visudo -cf %s'

通过以下的例子来讲解template模块与copy模块的区别。

有一个配置文件named.conf需要通过playbook的template模块来分发到主机组web1中,

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
下面是named.conf的简单配置:
[root@Server5 etc] # cat named.conf 
options {
listen-on port 53 {
127.0.0.1;
192.168.180.5;
};
listen-on-v6 port 53 { ::1; };
directory  "/var/named" ;
dump- file  "/var/named/data/cache_dump.db" ;
statistics- file  "/var/named/data/named_stats.txt" ;
memstatistics- file  "/var/named/data/named_mem_stats.txt" ;
};
zone  "."  IN {
type  hint;
file  "named.ca" ;
};
include  "/etc/named.rfc1912.zones" ;
include  "/etc/named.root.key" ;
zone  "internal.example.com"  IN {
type  slave;
file  "slaves/internal.example.com" ;
masters { 192.168.180.4; };
};
{ {group_names } }

下面开始编写templated.yml的配置

1
2
3
4
5
6
[root@Monitor ansible] # vim templated.yml              
- name: copy configure  file  to server web1 group
   hosts: web1
   tasks:          
       - template: src= /etc/ansible/named .conf dest= /etc/named .conf
       - copy: src= /etc/ansible/named .conf dest= /etc/named2 .conf

执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@Monitor ansible] # ansible-playbook templated.yml 
PLAY [copy configure  file  to server web1 group] ********************************
TASK [setup] *******************************************************************
ok: [Server6]
ok: [Server5]
TASK [template] ****************************************************************
ok: [Server6]
ok: [Server5]
TASK [copy] ********************************************************************
changed: [Server6]
changed: [Server5]
PLAY RECAP *********************************************************************
Server5                    : ok=3    changed=1    unreachable=0    failed=0   
Server6                    : ok=3    changed=1    unreachable=0    failed=0

去server5和server6上查看刚才拷贝的文件,发现name2.conf通过copy的没有任何改变,通过template模块拷贝的name.conf会有变量的更改。下面的是server5的name.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@Server5 etc] # cat /etc/named.conf 
options {
listen-on port 53 {
127.0.0.1;
192.168.180.5;
};
listen-on-v6 port 53 { ::1; };
directory  "/var/named" ;
dump- file  "/var/named/data/cache_dump.db" ;
statistics- file  "/var/named/data/named_stats.txt" ;
memstatistics- file  "/var/named/data/named_mem_stats.txt" ;
};
zone  "."  IN {
type  hint;
file  "named.ca" ;
};
include  "/etc/named.rfc1912.zones" ;
include  "/etc/named.root.key" ;
zone  "internal.example.com"  IN {
type  slave;
file  "slaves/internal.example.com" ;
masters { 192.168.180.4; };
};
{ {group_names }}


2,set_fact模块

    set_fact模块可以自定义facts,这些自定义的facts可以通过template或者变量的方式在playbook中使用。如果你想要获取一个进程使用的内存的百分比,则必须通过set_fact来进行计算之后得出其值,并将其值在playbook中引用。

#####下面是一个配置mysql innodb buffer size的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@Monitor ansible] # vim set_fact.yml 
 
- name: Configure MySQL
   hosts: web1
   tasks:
     - name:  install  MySql
       yum: name=mysql-server state=installed
 
     - name: Calculate InnoDB buffer pool size
       set_fact: innodb_buffer_pool_size_mb= "{{ ansible_memtotal_mb / 2 }}"
 
     - name: Configure MySQL 
       template: src= /etc/ansible/my .conf dest= /etc/my .cnf owner=root group=root mode=0644 
       notify: restart mysql 
 
     - name: Start MySQL 
       service: name=mysqld state=started enabled= yes 
   handlers: 
     - name: restart mysql 
       service: name=mysqld state=restarted

####配置mysql的配置文件my.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@Monitor ansible] # vim /etc/ansible/my.conf
# {{ ansible_managed }}
[mysqld]
datadir= /var/lib/mysql
socket= /var/lib/mysql/mysql .sock
# Disabling symbolic-links is recommended to prevent assorted
security risks
symbolic-links=0
# Configure the buffer pool
innodb_buffer_pool_size = {{ innodb_buffer_pool_size_mb|int }}M
[mysqld_safe]
log-error= /var/log/mysqld .log
pid- file = /var/run/mysqld/mysqld .pid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#######查看执行结果
[root@Monitor ansible] # ansible-playbook set_fact.yml 
PLAY [Configure MySQL] *********************************************************
TASK [setup] *******************************************************************
ok: [Server5]
ok: [Server6]
TASK [ install  MySql] ***********************************************************
ok: [Server5]
ok: [Server6]
TASK [Calculate InnoDB buffer pool size] ***************************************
ok: [Server6]
ok: [Server5]
TASK [Configure MySQL] *********************************************************
ok: [Server6]
ok: [Server5]
TASK [Start MySQL] *************************************************************
fatal: [Server5]: FAILED! => { "changed" false "failed" true "msg" "MySQL Daemon failed to start.\nStarting mysqld:  [FAILED]\r\n" }
fatal: [Server6]: FAILED! => { "changed" false "failed" true "msg" "MySQL Daemon failed to start.\nStarting mysqld:  [FAILED]\r\n" }
         to retry, use: --limit @ /etc/ansible/set_fact .retry
PLAY RECAP *********************************************************************
Server5                    : ok=4    changed=0    unreachable=0    failed=1   
Server6                    : ok=4    changed=0    unreachable=0    failed=1

在server5和server6服务器上查看该配置

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@Server5 etc] # vim my.cnf 
# Ansible managed
[mysqld]
datadir= /var/lib/mysql
socket= /var/lib/mysql/mysql .sock
# Disabling symbolic-links is recommended to prevent assorted
security risks
symbolic-links=0
# Configure the buffer pool
innodb_buffer_pool_size = 934M
[mysqld_safe]
log-error= /var/log/mysqld .log
pid- file = /var/run/mysqld/mysqld .pid


3,pause模块

    pause模块是在playbook执行的过程中暂停一定时间或者提示用户进行某些操作

1
2
3
4
常用参数:
minutes:暂停多少分钟
seconds:暂停多少秒
prompt:打印一串信息提示用户操作

简单的实例:

1
2
3
4
5
[root@Monitor ansible] # vim pause.yml
  - name: wait on user input
    pause: prompt= "Warning! Detected slight issue. ENTER to continue CTRL-C a to quit" 
  - name: timed wait
   pause: seconds=30

4,wait_for模块


在playbook的执行过程中,等待某些操作完成以后再进行后续操作

1
2
3
4
5
6
7
8
常用参数:
connect_timeout:在下一个任务执行之前等待连接的超时时间
delay:等待一个端口或者文件或者连接到指定的状态时,默认超时时间为300秒,在这等待的300s的时间里,wait_for模块会一直轮询指定的对象是否到达指定的状态,delay即为多长时间轮询一次状态。
host:wait_for模块等待的主机的地址,默认为127.0.0.1
port:wait_for模块待待的主机的端口
path:文件路径,只有当这个文件存在时,下一任务才开始执行,即等待该文件创建完成
state:等待的状态,即等待的文件或端口或者连接状态达到指定的状态时,下一个任务开始执行。当等的对象为端口时,状态有started,stoped,即端口已经监听或者端口已经关闭;当等待的对象为文件时,状态有present或者started,absent,即文件已创建或者删除;当等待的对象为一个连接时,状态有drained,即连接已建立。默认为started
timeout:wait_for的等待的超时时间,默认为300秒
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#####示例
[root@Monitor ansible] # cat /etc/ansible/wait_for.yml 
- name: create task
   hosts: 192.168.180.2
   tasks:
  
         - wait_for: port=8080 state=started      #等待8080端口已正常监听,才开始下一个任务,直到超时
         - wait_for: port=8081 delay=10     #等待8000端口正常监听,每隔10s检查一次,直至等待超时
         - wait_for: host=0.0.0.0 port=8000 delay=10 state=drained     #等待8000端口直至有连接建立
         - wait_for: host=0.0.0.0 port=8000 state=drained exclude_hosts=10.2.1.2,10.2.1.3     #等待8000端口有连接建立,如果连接来自10.2.1.2或者10.2.1.3,则忽略。
         - wait_for: path= /tmp/foo     #等待/tmp/foo文件已创建
         - wait_for: path= /tmp/foo  search_regex=completed     #等待/tmp/foo文件已创建,而且该文件中需要包含completed字符串
         - wait_for: path= /var/lock/file .lock state=absent     #等待/var/lock/file.lock被删除
         - wait_for: path= /proc/3466/status  state=absent         #等待指定的进程被销毁
         - local_action: wait_for port=22 host= "{{ ansible_ssh_host | default(inventory_hostname) }}"  search_regex=OpenSSH delay=10     #等待openssh启动,10s检查一次

执行过程为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@Monitor ansible] # ansible-playbook wait_for.yml
PLAY [create task] *************************************************************
TASK [setup] *******************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2]
TASK [wait_for] ****************************************************************
ok: [192.168.180.2 -> localhost]
PLAY RECAP *********************************************************************
192.168.180.2              : ok=10   changed=0    unreachable=0    failed=0


5,assemble模块

用于组装文件,即将多个零散的文件,合并一个大文件

1
2
3
4
5
6
7
8
常用参数:
src:原文件(即零散文件)的路径
dest:合并后的大文件路径
group:合并后的大文件的属组
owner:合并后的大文件的属主
mode:合并后的大文件的权限
validate:与template的validate相同,指定命令验证文件
ignore_hidden:组装时,是否忽略隐藏文件,默认为no,该参数在2.0版本中新增

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@Monitor ansible] # vim assemble.yml 
- hosts: web1
   tasks:
     - name: Make a Directory  in  /opt
       file : path= /opt/sshkeys  state=directory owner=root group=root mode=0700
     - name: Copy SSH keys over
       copy: src=playbook/{{ item }}.pub dest= /opt/sshkeys/ {{ item }}.pub owner=root group=root mode=0600
       with_items:
         - dan
         - kate
         - mal
     - name: Make the root  users  SSH config directory
       file : path= /root/ . ssh  state=directory owner=root group=root mode=0700
     - name: Build the authorized_keys  file
       assemble: src= /opt/static/  dest= /root/ . ssh /authorized_keys  owner=root group=root mode=0700    #将/opt/sshkeys目录里所
有的文件合并到 /root/ . ssh /authorized_keys 一个文件中

######执行过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@Monitor ansible] # ansible-playbook assemble.yml 
PLAY [web1] ********************************************************************
TASK [setup] *******************************************************************
ok: [Server5]
ok: [Server6]
TASK [Make a Directory  in  /opt ] ************************************************
ok: [Server6]
ok: [Server5]
TASK [Copy SSH keys over] ******************************************************
failed: [Server6] (item=mal) => { "failed" true "item" "mal" "msg" "Unable to find 'playbook/mal.pub' in expected paths." }
failed: [Server6] (item=kate) => { "failed" true "item" "kate" "msg" "Unable to find 'playbook/kate.pub' in expected paths." }
failed: [Server6] (item=dan) => { "failed" true "item" "dan" "msg" "Unable to find 'playbook/dan.pub' in expected paths." }
failed: [Server5] (item=kate) => { "failed" true "item" "kate" "msg" "Unable to find 'playbook/kate.pub' in expected paths." }
failed: [Server5] (item=dan) => { "failed" true "item" "dan" "msg" "Unable to find 'playbook/dan.pub' in expected paths." }
failed: [Server5] (item=mal) => { "failed" true "item" "mal" "msg" "Unable to find 'playbook/mal.pub' in expected paths." }
         to retry, use: --limit @ /etc/ansible/assemble .retry
PLAY RECAP *********************************************************************
Server5                    : ok=2    changed=0    unreachable=0    failed=1   
Server6                    : ok=2    changed=0    unreachable=0    failed=1


6,add_host模块

在playbook执行的过程中,动态的添加主机到指定的主机组中

1
2
3
常用参数:
groups :添加主机至指定的组
name:要添加的主机名或IP地址

示例

1
2
3
4
5
[root@Monitor ansible] # vim add_host.yml
- name: add a host to group webservers
   hosts: web1
   tasks:
     - add_host name={{ ip_from_ec2 }} group=web1 foo=23     #添加主机到webservers组中,主机的变量foo的值为42


7,group_by模块

playbook执行的过程中,动态的创建主机组

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- name: Create operating system group
   hosts: all
   tasks:
     - group_by: key=os_{{ ansible_distribution }}            #在playbook中设置一个新的主机组
- name: Run on CentOS hosts only
   hosts: os_CentOS
   tasks:
     - name: Install Apache
       yum: name=httpd state=latest
- name: Run on Ubuntu hosts only
   hosts: os_Ubuntu
   tasks:
     - name: Install Apache
       apt: pkg=apache2 state=latest

执行过程:

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
root@Monitor ansible] # ansible-playbook group_by.yml 
PLAY [Create operating system group] *******************************************
TASK [setup] *******************************************************************
ok: [Server6]
ok: [192.168.180.6]
ok: [192.168.180.5]
ok: [Server5]
ok: [192.168.180.4]
ok: [192.168.180.23]
ok: [192.168.180.2]
ok: [192.168.180.10]
TASK [group_by] ****************************************************************
ok: [Server6]
ok: [Server5]
ok: [192.168.180.4]
ok: [192.168.180.5]
ok: [192.168.180.6]
ok: [192.168.180.23]
ok: [192.168.180.2]
ok: [192.168.180.10]
PLAY [Run on CentOS hosts only] ************************************************
TASK [setup] *******************************************************************
ok: [Server6]
ok: [192.168.180.6]
ok: [Server5]
ok: [192.168.180.4]
ok: [192.168.180.5]
ok: [192.168.180.23]
ok: [192.168.180.2]
ok: [192.168.180.10]
TASK [Install Apache] **********************************************************
changed: [Server5]
changed: [Server6]
ok: [192.168.180.5]
ok: [192.168.180.6]
ok: [192.168.180.23]
ok: [192.168.180.4]
changed: [192.168.180.10]


8,debug模块

调试模块,用于在调试中输出信息

1
2
3
4
常用参数:
msg:调试输出的消息
var:将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出
verbosity:debug的级别

示例:

1
2
3
4
5
6
7
8
9
10
[root@Monitor ansible] # vim debug.yml              
# Example that prints the loopback address and gateway for each host- debug: msg="System {{ inventory_hostname }} has uuid
  {{ ansible_product_uuid }}"
- debug: msg= "System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
         when: ansible_default_ipv4.gateway is defined
- shell:  /usr/bin/uptime 
         register: result
- debug: var=result verbosity=2     #直接将上一条指令的结果作为变量传递给var,由debug打印出result的值
- name: Display all variables /facts  known  for  a host
         debug: var=hostvars[inventory_hostname] verbosity=4


9,fail模块

用于终止当前playbook的执行,通常与条件语句组合使用,当满足条件时,终止当前play的运行。可以直接由failed_when取代。

1
2
选项只有一个:
msg:终止前打印出信息

示例:

1
2
3
[root@Monitor ansible] # vim fail.yml 
- fail: msg= "The system may not be provisioned according to the CMDB status."
   when: cmdb_status !=  "to-be-staged"


备注:以后会继续修改有不妥之处

本文转自 lqbyz 51CTO博客,原文链接:http://blog.51cto.com/liqingbiao/1968916


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
消息中间件 运维 Kubernetes
构建高效自动化运维体系:Ansible与Kubernetes的融合实践
【5月更文挑战第9天】随着云计算和微服务架构的普及,自动化运维成为确保系统可靠性和效率的关键。本文将深入探讨如何通过Ansible和Kubernetes的集成,构建一个强大的自动化运维体系。我们将分析Ansible的配置管理功能以及Kubernetes容器编排的优势,并展示如何将二者结合,以实现持续部署、快速扩展和高效管理现代云原生应用。文章还将涵盖实际案例,帮助读者理解在真实环境下如何利用这些工具优化运维流程。
|
1天前
|
存储 人工智能 测试技术
python自动化测试实战 —— CSDN的Web页面自动化测试
python自动化测试实战 —— CSDN的Web页面自动化测试
8 0
|
1天前
|
Web App开发 设计模式 测试技术
python自动化测试实战 —— 自动化测试框架的实例
python自动化测试实战 —— 自动化测试框架的实例
4 0
|
1天前
|
监控 数据可视化 IDE
python自动化测试实战 —— 单元测试框架
python自动化测试实战 —— 单元测试框架
8 2
|
1天前
|
Web App开发 JavaScript 测试技术
python自动化测试实战 —— WebDriver API的使用
python自动化测试实战 —— WebDriver API的使用
6 1
|
1天前
|
运维 安全 API
构建高效自动化运维体系:Ansible与Docker的协同实践
【5月更文挑战第13天】在现代IT基础设施管理中,自动化运维已成为提升效率、确保一致性和降低人为错误的关键。本文通过深入探讨Ansible和Docker的集成实践,揭示了如何构建一个灵活、可扩展且高效的自动化运维体系。我们将从理论到实践,展示如何利用这两种技术实现自动化部署、管理和扩展应用服务,以及它们如何帮助运维团队应对快速变化的业务需求和复杂的IT环境。
12 1
|
6天前
|
Java 测试技术 持续交付
自动化测试框架选型与实战:深入探索与应用
【5月更文挑战第8天】本文探讨了自动化测试框架的选型与实战应用,强调了其在软件质量保障中的重要性。选型原则包括考虑项目需求、技术栈、可扩展性和可维护性,以及社区支持和文档。介绍了Selenium、Appium、JUnit和Pytest等常用框架,并概述了实战应用的步骤,包括明确需求、搭建环境、编写测试用例、执行测试、分析结果、维护代码和持续集成。合理选型与实践能提升测试效率,保障项目成功。
|
6天前
|
运维 Kubernetes 监控
构建高效自动化运维体系:基于Ansible的策略与实践
【5月更文挑战第8天】 在当今IT基础设施管理领域,自动化不再是一个选择,而是必要的步骤。随着复杂性的增加和变更的频繁性,自动化工具如Ansible提供了一种高效、可靠的解决方案来简化配置管理和多节点部署。本文将探讨如何利用Ansible构建一个高效的自动化运维体系,涵盖其核心原理、策略设计以及在实际环境中的应用。我们将分析Ansible与其他自动化工具的不同之处,并提供一些最佳实践,以帮助运维专家提升他们的工作效率和系统稳定性。
|
8月前
|
缓存 运维 Linux
Linux(CentOS)运维脚本工具集合
Linux(CentOS)运维脚本工具集合
158 2
|
1月前
|
运维 Linux Shell
linux运维常用命令
linux运维常用命令