Ansible详解(二)playbook剧本详解
文章目录
- 前言
- 一、Playbook基础概念
- 1.1 什么是Playbook
- 1.2 Playbook的核心组成
- 二、Playbook结构与示例
- 2.1 基本结构解析
- 2.2 完整示例详解
- 三、Playbook执行与管理
- 3.1 常用执行命令
- 3.2 认证相关选项
- 四、变量定义与使用
- 4.1 变量定义方式
- 4.2 命令行传递变量
- 五、流程控制
- 5.1 条件判断when
- 5.2 迭代循环
- 六、模板技术
- 6.1 Jinja2模板基础
- 6.2 主机变量定义
- 6.3 模板使用示例
- 七、Tags标签系统
- 7.1 Tags的作用
- 7.2 标签执行命令
- 八、Roles模块化系统
- 8.1 Roles概念与优势
- 8.2 Roles目录结构
- 8.3 Roles使用步骤
- 总结
前言
在现代IT基础设施管理中,自动化配置和部署已成为不可或缺的一环。Ansible作为一款强大的自动化工具,以其简单易用、功能丰富的特点受到了广泛欢迎。Playbook是Ansible的核心组件之一,它允许我们以声明式的方式定义自动化任务,实现复杂流程的编排与管理。本文将详细解析Ansible Playbook的编写方法,从基础结构到高级应用,帮助您系统地掌握Playbook的编写技巧,提升自动化运维效率。
一、Playbook基础概念
1.1 什么是Playbook
Ansible Playbook是一个采用YAML格式编写的文件,包含一个或多个Play,每个Play负责对指定的主机组执行一系列任务。Playbook是Ansible配置、部署和编排语言的核心表现形式。
1.2 Playbook的核心组成
Playbook通常包含以下几个关键组成部分:
- Tasks:调用模块在目标主机上执行操作的具体任务
- Variables:用于存储和传递参数值的变量系统
- Templates:基于Jinja2模板引擎的动态配置文件生成
- Handlers:用于响应任务执行后变更的特殊任务
- Roles:将任务、变量、模板等组织成模块化结构的复用单元
二、Playbook结构与示例
2.1 基本结构解析
--- #yaml文件以---开头,以表名这是一个yaml文件,可省略
- name: first play # 自定义Play的名称(可选)gather_facts: false # 设置不收集facts信息(可选,可加速执行)hosts: webservers # 指定目标主机组(可以用多个组,多个组用冒号分隔)remote_user: root # 指定远程执行用户tasks: # 定义任务列表- name: test connection # 任务名称ping: # 使用"模块: [选项]"格式定义任务
2.2 完整示例详解
- name: first play1gather_facts: falsehosts: host2remote_user: roottasks: #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行- name: test connection #自定义任务名称ping: #使用 module: [options] 格式来定义一个任务- name: disable selinuxcommand: '/sbin/setenforce 0' #command模块和shell模块无需使用key=value格式ignore_errors: True # 如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务- name: disable firewalldservice: name=firewalld state=stopped #使用 module: options 格式来定义任务,option使用key=value格式- name: install httpdyum: name=httpd state=latest #安装多个- name: install configuration file for httpdcopy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件notify: "restart httpd" # #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作 - name: start httpd serviceservice: enabled=true name=httpd state=startedhandlers: #handlers中定义的就是任务,此处handlers中的任务使用的是service模块- name: restart httpd # notify与handlers名称必须一致service: name=httpd state=restarted #Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
注意:Ansible在执行完所有普通任务后才会执行handler,这样可以避免多次触发导致的重启问题。
三、Playbook执行与管理
3.1 常用执行命令
ansible-playbook test1.yaml # 运行playbook
ansible-playbook test1.yaml --syntax-check # 检查语法正确性
ansible-playbook test1.yaml --list-task # 查看任务列表
ansible-playbook test1.yaml --list-hosts # 查看影响的主机
ansible-playbook test1.yaml --start-at-task='install httpd' # 从指定任务开始执行
3.2 认证相关选项
ansible-playbook test1.yaml -k # 提示输入SSH密码
ansible-playbook test1.yaml -K # 提示输入sudo密码
四、变量定义与使用
4.1 变量定义方式
变量可以通过playbook中的vars部分或命令行参数定义:
- name: second playhosts: host2remote_user: rootvars:groupname: mysqlusername: nginxtasks:- name: create groupgroup: name={{ groupname }} system=yes gid=306- name: create useruser: name={{ username }} uid=306 group={{ groupname }}- name: copy filecopy: content="{{ ansible_default_ipv4 }}" dest=/opt/vars.txt
4.2 命令行传递变量
ansible-playbook test1.yaml -e "username=nginx"
五、流程控制
5.1 条件判断when
when指令提供条件执行能力,当值为true时执行任务:
- hosts: allremote_user: roottasks:- name: shutdown host command: /sbin/shutdown -r now when: ansible_default_ipv4.address == "192.168.10.14"
注意:when指令中的变量名不需要使用{{}}括起来。
5.2 迭代循环
Ansible支持使用with_items或loop进行迭代操作:
- name: play1hosts: host2gather_facts: falsetasks: - name: create directoriesfile:path: "{{item}}"state: directorywith_items: # 等同于loop:- /tmp/test1- /tmp/test2 - name: add usersuser: name={{item.name}} state=present groups={{item.groups}}with_items:- name: test1groups: wheel- name: test2groups: root
---- name: play3hosts: host2gather_facts: falseremote_user: roottasks:- name: dirfile:path: "{{item}}"state: touchloop:- /opt/1.txt- /opt/2.txt- /opt/3.txt
六、模板技术
6.1 Jinja2模板基础
Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。
Jinja2是基于Python的模板引擎,用于动态生成配置文件:
- 创建模板文件(.j2):
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
- 在模板中定义变量占位符:
Listen {{http_port}} # 42行修改
ServerName {{server_name}} # 95行修改
DocumentRoot "{{root_dir}}" # 119行修改
6.2 主机变量定义
在主机清单中定义变量:
[host1]
192.168.10.124 http_port=80 server_name=www.accp.com root_dir=/etc/httpd/htdocs
6.3 模板使用示例
- hosts: allremote_user: rootvars:package: httpdservice: httpdtasks:- name: install httpd packageyum: name={{ package }} state=latest- name: install configure filetemplate: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #jinja2去hosts中拿参数,拿到后修改.j2文件,修改完后进行传输notify:- restart httpd- name: create root dirfile: path=/etc/httpd/htdocs state=directory- name: start httpd serverservice: name={{ service }} enabled=true state=startedhandlers:- name: restart httpdservice: name={{ service }} state=restarted
七、Tags标签系统
7.1 Tags的作用
Tags允许选择性执行特定任务,提高执行效率:
- name: demo9hosts: host2tasks:- name: copy hosts filecopy: src=/etc/hosts dest=/opt/hoststags:- hhh- name: touchfile:path: /opt/hhh.txtstate: touchtags:- wow- name: printdebug:msg: "我运行了"tags:- always
在使用时有前置要求的步骤可以加上-alawys
7.2 标签执行命令
ansible-playbook webhosts.yaml --tags="only"
八、Roles模块化系统
8.1 Roles概念与优势
Roles 数据中心有各种不同类型的主机。如web服务器、数据库服务器,基于开发环境的服务器。随着时间的推移,具有处理所有这些情况的任务和人员的Ansible playbook将变得庞大而复杂。
- 角色允许将复杂的剧本组织成独立的、更小的剧本和文件
- 角色提供了一种从外部文件加载任务、处理程序和变量的方法
- 角色也可关联和引用静态的文件和模板
- 角色可以编写成满足普通用途需求,并且能被重复利用
Ansible为了层次化、结构化地组织Playbook,使用了角色(roles),roles可以根据层次型结构自动装载变量文件、task以及handlers等。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们。roles一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。
8.2 Roles目录结构
标准的Roles目录结构包含以下组件:
roles/
├── web/ # 角色名称
│ ├── files/ # 存放copy/script模块调用的文件
│ ├── templates/ # 存放Jinja2模板文件
│ ├── tasks/ # 定义任务列表的main.yml文件
│ ├── handlers/ # 定义处理程序的main.yml文件
│ ├── vars/ # 定义变量的main.yml文件
│ ├── defaults/ # 设定默认变量的main.yml文件
│ └── meta/ # 定义角色依赖关系的main.yml文件
└── db/ # 另一个角色└── ... # 相同结构
-
files: 用来存放由 copy 模块或 script 模块调用的文件。
-
templates: 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件。
-
tasks: 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件。
-
handlers: 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作。
-
vars: 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量。
-
defaults: 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。
-
meta: 此目录应当包含一个 main.yml 文件,用于定义此角色的特殊设定及其依赖关系。
8.3 Roles使用步骤
- 创建roles目录结构:
mkdir /etc/ansible/roles/{httpd,mysql,php}/{files,templates,tasks,handlers,vars,defaults,meta} -p
- 创建main.yml文件:
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
- 创建全局变量目录(可选)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定义,引用的时候注意
- 编写角色任务(以nginx为例):
# /etc/ansible/roles/httpd/tasks/main.yml
- name: install httpdyum: name={{pkg}} state=latest
- name: start apacheservice: enabled=true name={{svc}} state=started
- 定义角色变量:
# /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
- 编写顶层playbook:
# /etc/ansible/site.yml 修改 site.yml 文件,针对不同主机去调用不同的角色
- hosts: webserversremote_user: rootroles:- httpd
- hosts: dbserversremote_user: rootroles:- mysql
- 执行playbook:
cd /etc/ansible
ansible-playbook site.yml
总结
Ansible Playbook是自动化运维的核心工具,通过本文的详细解析,我们可以看到其强大的功能和灵活的应用方式。从基础的任务编写到高级的Roles模块化设计,Playbook提供了完整的自动化解决方案。
关键要点总结:
- Playbook采用YAML格式,结构清晰易读,支持多种控制结构
- 变量系统和模板技术使配置管理更加灵活和动态
- Tags系统提供了精确的任务执行控制能力
- Roles架构实现了代码的模块化和复用,大大提高了维护效率
通过合理运用这些特性,我们可以构建出高效、可靠且易于维护的自动化运维体系,适应各种复杂的部署和管理场景。掌握Ansible Playbook的编写技巧,将为您的自动化运维工作带来极大的便利和效率提升。