devops工具-Ansible进阶playbook&roles
一、playbook介绍
二、核心元素
- Hosts和User:主机列表和用户,定义一个playbook操作的远程主机以及登录的用户
- Tasks:tasks代表任务集,定义远程主机运行的任务列表,
- Variables:变量,可以在playbook中传递变量
- Templates:模版,复用配置文件,jinja2模版引擎
- Handlers和Notify:触发器,用于在task任务结束后,可以触发其他操作
hosts和users
---
- hosts: test #指定主机组
remote_user: root #指定ssh登录的用户
tasks:
- name: test server
ping:
使用sudo切换
---
- hosts: test
remote_user: root
become: yes #become参数在2.6版本用于指定sudo
become_user: admin #sudo的用户
tasks:
- name: test server
ping:
tasks
tasks:
- name: task_name #任务名称
module: module_args #使用的模块,以及模块参数,列如yum: name=nginx state=present
---
- hosts: 10.1.210.51
remote_user: root
tasks:
- name: install package #使用yum安装包
yum: name=httpd state=present
- name: start httpd #启动该服务
service: name=httpd state=started
执行:
variables
---
- hosts: 10.1.210.53
remote_user: root
tasks:
- name: test facts var
shell: echo "{{ ansible_all_ipv4_addresses }}" > host_ip.txt
#单独主机变量,优先级高于公共变量
host varname=value
#主机组变量
[groupname:vars] #为指定主机组自定义变量,vars为关键字
varname=value
列如:
vi /etc/ansible/hosts
10.1.210.51 business=card #变量名为business值为card
10.1.210.53 [dev]
10.1.210.33
10.1.210.32 [dev:vars] #组变量定义
myname=wd
示例:
[root@app52 ~]# cat test.yaml
---
- hosts: 10.1.210.51
remote_user: root
tasks:
- name: test facts from hosts
debug: var=business #使用debug打印变量的值,var参数测试变量不需要用{{ }}
运行playbook:
3.playbook中定义变量
格式:
vars:
- varname1: value1
- varname2: value2
示例:
---
- hosts: 10.1.210.51
remote_user: root
vars:
- pkg_name: httpd
- pkg_cmd: /usr/sbin/httpd
tasks:
- name: restart httpd
service: name={{ pkg_name }} state=restarted
- name: copy cmd
copy: src={{ pkg_cmd }} dest=/tmp/
运行playbook:
4.命令行中定义变量
ansible-playbook -e 'varname=value’ #该方式定义的变量优先级最高
5.通过文件引用变量。
[root@app52 ~]# cat /tmp/myvars.yml
var1: value1
var2: value2
playbook中使用
---
- hosts: 10.1.210.51
remote_user: root
vars_files:
- /tmp/myvars.yml #变量文件
tasks:
- name: test myvar
debug: msg="{{ var1 }}/{{ var2 }}" #这里的var1变量和var2变量来自于文件/tmp/myvars.yml
运行结果:
6.在roles中定义变量,后续在介绍roles在讲解。
Templates
vim /tmp/nginx.conf.j2 user nginx;
worker_processes {{ ansible_processor_vcpus }}; #使用cpu个数作为woeker数量
error_log /var/log/nginx_error.log crit;
pid /var/run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
worker_rlimit_nofile 65535;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server
{
listen 80;
server_name {{ ansible_fqdn }} #使用主机名作为hostname
access_log /var/log/access.log;
error_log /var/log/error.log;
}
}
2.playbook中使用
---
- hosts: 10.1.210.53
remote_user: root
vars:
- package_name: nginx
- config_path: /etc/nginx/nginx.conf
tasks:
- name: install epel
yum: name=epel-release
- name: install package
yum: name={{ package_name }}
- name: copy config file
template: src=/tmp/nginx.conf.j2 dest={{ config_path }} backup=yes #backup用于备份
- name: start service
service: name={{ package_name }} state=started
运行playbook
Handlers和notify
- hosts: 10.1.210.53
remote_user: root
vars:
- package_name: nginx
- config_path: /etc/nginx/nginx.conf
tasks:
- name: install epel
yum: name=epel-release
- name: install package
yum: name={{ package_name }}
- name: copy config file
template: src=/tmp/nginx.conf.j2 dest={{ config_path }} backup=yes
notify: #当配置文件发生变化时候,通知hanler触发task
- stop service
- start service
handlers:
- name: stop service
service: name={{ package_name }} state=stopped
- name: start service
service: name={{ package_name }} state=started
运行playbook
三、playbook进阶技巧
使用tag标记任务
- --list-tags :列出playbook中所有的tag
- --skip-tags:跳过playbook中被标记的tag任务
- -t 或 --tags:指定运行playbook中被标记的tag任务
---
- hosts: 10.1.210.51
remote_user: root
tasks:
- name: exec tag1
shell: cat /etc/passwd
tags: tag1
- name: exec tag2
file: path=/tmp/b.txt state=touch
tags: tag2
- name: view password
shell: cat /etc/passwd
列出tag
指定运行某个tag任务
跳过tag任务运行
从以上结果可看出,跳过了tag1和tag2任务,只运行了view password任务。
条件测试when
- when判断的对象是task,所以和tas k在同一列表层次。它的判断结果决定它所在task是否执行,而不是它下面 的task是否执行。
- when中引用变量的时候不需要加{{ }}符号。
示例一:使用facts变量测试
tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "Debian" #当操作系统是Debian才执行该任务
示例二:使用逻辑运算进行多条件判断
tasks:
- name: "shut down CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "") or
(ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "")
两个条件使用and还可以如下表示
tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "" #同时满足系统是CentOS且版本是6
示例三:根据任务的执行结果状态来判断任务是否执行,这里使用register来保存了任务执行结果,后续会介绍。
---
- hosts: 10.1.210.51
name: test when
remote_user: root
tasks:
- name: task1
command: /bin/false
register: result #将本次任务结果保存在变量中
ignore_errors: True #忽略错误执行,可确保任务错误也能执行下一个任务 - name: pre task failed
file: path=/tmp/failed.txt state=touch
when: result is failed #判断result结果是否是failed - name: pre task successed state=touch
file: path=/tmp/success.txt
when: result is succeeded #判断result结果是否是succeeded - name: pre task skipped state=touch
file: path=/tmp/skip.txt
when: result is skipped #判断结果是否是skipped
运行一下:
如上图,红色的部分任务都跳过了未执行,这是因为result结果是failded,所以只执行了“pre task failed”这个任务。
示例4:使用变量进行测试
---
- hosts: 10.1.210.51
name: test var when
remote_user: root
vars:
- flag: true #变量定义
tasks:
- name: test server
ping:
when: flag #判断变量flag为true执行 - name: create file
file: path=/tmp/myfile.txt state=touch
when: not flag #变量flag不为true执行
执行结果:
同样可以看到create file 任务被跳过了。
使用register保存任务结果
register注册变量,用于保存任务结果,可用于保存配置或when关键字判断,这是非常有用了,在上个示例中使用了任务结果作为判断条件。例如,你可以将文件中的配置或者json内容保存在变量中,可以供后续使用:
---
- hosts: 10.1.210.51
name: test register
remote_user: root
tasks:
- name: read conf
shell: cat /tmp/nginx.conf
register: nginx_conf #注册变量 - name: copy conf
copy: content={{ nginx_conf }} dest=/etc/nginx/nginx.conf #使用变量
还可以配合循环使用,以下示例展示了批量创建软链接:
- name: registered variable usage as a loop list
hosts: all
tasks: - name: retrieve the list of home directories
command: ls /home
register: home_dirs - name: add home dirs to the backup spooler
file:
path: /mnt/bkspool/{{ item }}
src: /home/{{ item }}
state: link
loop: "{{ home_dirs.stdout_lines }}"
使用迭代进行重复性操作或任务
---
- hosts: localhost
remote_user: root
tasks:
- name: create user
user: name={{ item }} state=present
with_items:
- zabbix
- admin
执行结果:
示例二:循环中使用register注册变量
- hosts: localhost
remote_user: root
tasks:
- command: echo {{ item }}
with_items: [ 0, 2, 4, 6, 8, 10 ]
register: num
- debug: msg="{% for i in num.results %} {{i.stdout}} {% endfor %}"
注意,将with_items迭代后的结果注册为变量时,其注册结果也是列表式的,且其key为"results"。具体的结果比较长,可以使用debug模块的var或msg参数观察变量的结果。以上示例运行结果如下:
2.with_dict迭代字典
---
- hosts: localhost
remote_user: root
tasks:
- debug: msg="{{ item.key }} / {{ item.value }}"
with_dict: { ip: 10.1.210.51, hostname: app52, gateway: 10.1.210.1}
以上示例中字典是已经存在了,除此之外字典可以来源于变量、facts等。例如使用facts进行迭代
---
- hosts: localhost
remote_user: root
tasks:
- debug: msg="{{item.key}} / {{item.value}}"
with_dict: "{{ ansible_cmdline }}"
使用include简化playbook
如果将所有的play都写在一个playbook中,很容易导致这个playbook文件变得臃肿庞大,且不易读。因此,可以将多个不同任务分别写在不同的playbook中,然后使用include将其包含进去即可。include可以导入两种文件:导入task文件、导入playbook。
示例:创建task.yml任务列表
vim task.yml
- name: task1
debug: msg="exec task1"
- name: task2
debug: msg="exec task2"
在目标playbook中倒入任务
---
- hosts: 10.1.210.51
remote_user: root
tasks:
- include: task.yml
执行playbook:
示例2:直接导入其他playbook,不过在ansible2.8将移除,2.8中将使用import_playbook
---
- hosts: 10.1.210.51
remote_user: root
tasks:
- include: task.yml - include: test_when.yml
- include: test_with.yml
四、roles(角色)介绍
简介
使用场景
- 同时安装多个不同的软件如:LNMP环境
- 不同服务器组需要安装不同服务
- 复杂的playbook,使用role可以具有阅读性
目录结构
- files:用来存放由copy模块或script模块调用的文件。
- templates:用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。
- tasks:此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。
- handlers:此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。
- vars:此目录应当包含一个main.yml文件,用于定义此角色用到的变量。
- defaults:此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。
- meta:此目录应当包含一个main.yml文件,用于定义此角色的元数据信息。
例如:一个nginx角色的目录结构可以是:
.
└── nginx
├── default
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
多个role目录:
├── httpd #http role
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── nginx #nginx role
├── default
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
演示:使用role安装nginx
一、创建对应的目录结构:
[root@app52 ~]# mkdir -pv roles/nginx/{files,templates,vars,tasks,handlers,meta,default}
mkdir: 已创建目录 "roles"
mkdir: 已创建目录 "roles/nginx"
mkdir: 已创建目录 "roles/nginx/files"
mkdir: 已创建目录 "roles/nginx/templates"
mkdir: 已创建目录 "roles/nginx/vars"
mkdir: 已创建目录 "roles/nginx/tasks"
mkdir: 已创建目录 "roles/nginx/handlers"
mkdir: 已创建目录 "roles/nginx/meta"
mkdir: 已创建目录 "roles/nginx/default”
二、定义变量
[root@app52 ~]# vi roles/nginx/vars/main.yml
pkg_name: nginx #安装包名称
listen_port: 80 #监听端口
三、编写任务
这里可以把任务模块化,最后在main.yml包含它们
[root@app52 ~]# vi roles/nginx/tasks/yum.yml
- name: install epel
yum: name=epel-release state=present - name: install nginx pkg
yum: name={{ pkg_name }} state=present [root@app52 ~]# vi roles/nginx/tasks/copy.yml
- name: copy nginx.conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf - name: copy index.html
copy: src=index.html dest=/var/www/html/
notify: reload [root@app52 ~]# vi roles/nginx/tasks/start_service.yml
- name: start nginx
service: name=nginx state=restarted [root@app52 ~]# vi roles/nginx/tasks/main.yml
- include: yum.yml
- include: copy.yml
- include: start_service.yml
四、准备配置文件以及index.html
#index.html
[root@app52 ~]# vi roles/nginx/files/index.html
<h1>Hello wd</h1> #配置文件模版
[root@app52 ~]# vi roles/nginx/templates/nginx.conf.j2
user nginx;
worker_processes {{ ansible_processor_vcpus }}; #使用cpu个数作为woeker数量
error_log /var/log/nginx_error.log crit;
pid /var/run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
worker_rlimit_nofile 65535;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server
{
listen {{ listen_port }};
server_name {{ ansible_all_ipv4_addresses[0] }} ; #使用IP地址作为server name
root /var/www/html ;
access_log /var/log/access.log;
error_log /var/log/error.log;
}
}
五、编写handlers
如果在task中使用了notify,则就需要写对应的handlers,上述我使用了reload这个handler,所以这里需要定义:
[root@app52 ~]# vi roles/nginx/handlers/main.yml
- name: reload
service: name=nginx state=reloaded
六、在角色同级目录编写playbook引入角色
[root@app52 ~]# vi roles/install_nginx.yml
- hosts: web #指定使用role的主机或主机组
remote_user: root #指定用户
roles: #使用的role,可以有多个
- nginx
最后的目录结构为:
[root@app52 ~]# tree roles/
roles/
├── install_nginx.yml
└── nginx
├── default
├── files
│ └── index.html
├── handlers
│ └── main.yml
├── meta
├── tasks
│ ├── copy.yml
│ ├── main.yml
│ ├── start_service.yml
│ └── yum.yml
├── templates
│ └── nginx.conf.j2
└── vars
└── main.yml 8 directories, 9 files
七、运行playbook并测试
如红色部分,curl测试nginx 安装成功。
devops工具-Ansible进阶playbook&roles的更多相关文章
- devops工具-Ansible基础
一.Ansible介绍 简介 Ansible使用Python语言开发,是一个配置管理型工具,与之类似的工具还有Puppet.SaltStack.chef等,默认通过SSH协议进行远程命令执行或 ...
- 在CentOS7.6上安装自动化运维工具Ansible以及playbook案例实操
前言 Ansible是一款优秀的自动化IT运维工具,具有远程安装.远程部署应用.远程管理能力,支持Windows.Linux.Unix.macOS和大型机等多种操作系统. 下面就以CentOS 7.6 ...
- Ansible进阶--playbook的使用
一.什么是playbooksplaybooks是ansible的脚本.如同shell脚本一样,它是控制远程主机的一系列命令的集合,通过YAML语言编写.执行一些简单的任务,我们可以使用ad-hoc命令 ...
- 自动化运维工具——ansible剧本playbook(三)
一.Playbook--Ansible剧本 playbook是由一个或多个 "play"组成的列表 play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的ta ...
- 自动化运维工具——ansible模板与roles(四)
一. 模板Templates 文本文件,嵌套有脚本(使用模板编程语言编写) Jinja2语言,使用字面量,有下面形式 字符串:使用单引号或双引号 数字:整数,浮点数 列表:[item1, item2, ...
- DevOps - 配置管理工具Ansible
1 - 配置管理工具 配置管理工具(SCM,Software Configuration Management)可以将代码.软件方式实现的基础设施配置信息保存,也可以根据需求变化反复进行变更. 相关工 ...
- Fbric、Ansible、Docker、Chaos Monkey:DevOps工具的年中回顾
Fbric.Ansible.Docker.Chaos Monkey:DevOps工具的年中回顾 [编者按]近日,Cyber Engineering Solutions Group 技术经理 Hasan ...
- 利用ansible书写playbook在华为云上批量配置管理工具自动化安装ceph集群
首先在华为云上购买搭建ceph集群所需云主机: 然后购买ceph所需存储磁盘 将购买的磁盘挂载到用来搭建ceph的云主机上 在跳板机上安装ansible 查看ansible版本,检验ansible是否 ...
- 自动化运维工具Ansible之Roles测验详解
Ansible Roles 详解与实战案例 主机规划 添加用户账号 说明: 1. 运维人员使用的登录账号: 2. 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务数据乱放: 3. 该用 ...
随机推荐
- [随时更新][Android]小问题记录
此文随时更新,旨在记录平时遇到的不值得单独写博客记录的细节问题,当然如果问题有拓展将会另外写博客. 原文地址请保留http://www.cnblogs.com/rossoneri/p/4040314. ...
- git 入门教程之1分钟快速了解 git
git 入门教程 git 是分布式版本控制系统,是文本文档管理的利器,是帮助你管理文件动态的好帮手. 如果你曾经手动管理过文档,一定有这样的经历,比如你正在编辑文档,想删除某段落,又担心不久后可能会恢 ...
- Python GUI编程实例
import os from time import sleep from tkinter import * from tkinter.messagebox import showinfo class ...
- ALTER SYSTEM ARCHIVELOG CURRENT挂起案例
最近两天,一台ORACLE数据库的作业执行delete_ob_get_epps.sh脚本清理过期备份时,执行下面SQL语句就会被阻塞,在监控工具DPA里面部分截图如下(图片分开截断) sql 'alt ...
- DBA思考系列——学会拒绝不合理的需求
DBA思考系列--学会拒绝不合理的需求 一直以来,个性都比较随意,一般很少拒绝开发人员的一些需求(有点老好人的感觉). 这点一直被老大诟病,也一直在反省!最近又有一件事情,让我觉得:应该学会拒绝不 ...
- SqlServer 线下讲座
2017年有幸在某互联网公司及其子公司进行了一次技术分享性质的讲座,讲座内容主要针对sqlserver 2017以及azure sql 的一些技术特性,进一步展示sql server 及其相关产品的新 ...
- Windows Server 2016-增强IPAM
Windows Server 2016网络功能可能没有像Docker容器或Nano Server那样得到关注,但是管理员应该了解新的域名系统服务器和IP地址管理功能如何帮助他们获得对网络环境的更多控制 ...
- [Hive_9] Hive 的排序
0. 说明 全排序(order by) | 部分排序(sort by) | hash 分区(distribute by) | cluster by 1. 前期准备 1.1 建表 create tab ...
- KVM使用
这里使用的是Ubuntu18.04桌面版虚拟机 关于KVM可以看一下我之前的博客,有一些简单的介绍. 1.在打开虚拟机之前先开启此虚拟机的虚拟化功能. 2.安装KVM及其依赖项 wy@wy-virtu ...
- [福大软工] Z班 第6次成绩排行榜
作业要求 http://www.cnblogs.com/easteast/p/7668890.html 作业评分 本次作业从引言(5 ') . 用户场景(15 ').类图(10 ').界面原型(15 ...