前言

在现代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 play1
gather_facts: false
hosts: host2
remote_user: root
tasks: #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
- name: test connection #自定义任务名称
ping: #使用 module: [options] 格式来定义一个任务
- name: disable selinux
command: '/sbin/setenforce 0' #command模块和shell模块无需使用key=value格式
ignore_errors: True # 如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
- name: disable firewalld
service: name=firewalld state=stopped #使用 module: options 格式来定义任务,option使用key=value格式
- name: install httpd
yum: name=httpd state=latest #安装多个
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件
notify: "restart httpd" # #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作 
- name: start httpd service
service: enabled=true name=httpd state=started
handlers: #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 play
hosts: host2
remote_user: root
vars:
groupname: mysql
username: nginx
tasks:
- name: create group
group: name={
{ groupname
}
} system=yes gid=306
- name: create user
user: name={
{ username
}
} uid=306 group={
{ groupname
}
}
- name: copy file
copy: content="{
{ ansible_default_ipv4
}
}" dest=/opt/vars.txt

在这里插入图片描述

4.2 命令行传递变量

ansible-playbook test1.yaml -e "username=nginx"

五、流程控制

5.1 条件判断when

when指令提供条件执行能力,当值为true时执行任务:

- hosts: all
remote_user: root
tasks:
- 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: play1
hosts: host2
gather_facts: false
tasks:
- name: create directories
file:
path: "{{item}}"
state: directory
with_items: # 等同于loop:
- /tmp/test1
- /tmp/test2
- name: add users
user: name={
{item.name
}
} state=present groups={
{item.groups
}
}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
---
- name: play3
hosts: host2
gather_facts: false
remote_user: root
tasks:
- name: dir
file:
path: "{{item}}"
state: touch
loop:
- /opt/1.txt
- /opt/2.txt
- /opt/3.txt

在这里插入图片描述

六、模板技术

6.1 Jinja2模板基础

Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。
Jinja2是基于Python的模板引擎,用于动态生成配置文件:

  1. 创建模板文件(.j2):
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
  1. 在模板中定义变量占位符:
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: all
remote_user: root
vars:
package: httpd
service: httpd
tasks:
- name: install httpd package
yum: name={
{ package
}
} state=latest
- name: install configure file
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #jinja2去hosts中拿参数,拿到后修改.j2文件,修改完后进行传输
notify:
- restart httpd
- name: create root dir
file: path=/etc/httpd/htdocs state=directory
- name: start httpd server
service: name={
{ service
}
} enabled=true state=started
handlers:
- name: restart httpd
service: name={
{ service
}
} state=restarted

在这里插入图片描述

七、Tags标签系统

7.1 Tags的作用

Tags允许选择性执行特定任务,提高执行效率:

- name: demo9
hosts: host2
tasks:
- name: copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- hhh
- name: touch
file:
path: /opt/hhh.txt
state: touch
tags:
- wow
- name: print
debug:
msg: "我运行了"
tags:
- always

在使用时有前置要求的步骤可以加上-alawys

7.2 标签执行命令

ansible-playbook webhosts.yaml --tags="only"

在这里插入图片描述

八、Roles模块化系统

8.1 Roles概念与优势

Roles 数据中心有各种不同类型的主机。如web服务器、数据库服务器,基于开发环境的服务器。随着时间的推移,具有处理所有这些情况的任务和人员的Ansible playbook将变得庞大而复杂。

  1. 角色允许将复杂的剧本组织成独立的、更小的剧本和文件
  2. 角色提供了一种从外部文件加载任务、处理程序和变量的方法
  3. 角色也可关联和引用静态的文件和模板
  4. 角色可以编写成满足普通用途需求,并且能被重复利用

​ 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使用步骤

  1. 创建roles目录结构:
mkdir /etc/ansible/roles/{httpd,mysql,php
}/{files,templates,tasks,handlers,vars,defaults,meta
} -p

在这里插入图片描述

  1. 创建main.yml文件:
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers
}/main.yml

在这里插入图片描述

  1. 创建全局变量目录(可选)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定义,引用的时候注意
  1. 编写角色任务(以nginx为例):
# /etc/ansible/roles/httpd/tasks/main.yml
- name: install httpd
yum: name={
{pkg
}
} state=latest
- name: start apache
service: enabled=true name={
{svc
}
} state=started
  1. 定义角色变量:
# /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
  1. 编写顶层playbook:
# /etc/ansible/site.yml 修改 site.yml 文件,针对不同主机去调用不同的角色
- hosts: webservers
remote_user: root
roles:
- httpd
- hosts: dbservers
remote_user: root
roles:
- mysql
  1. 执行playbook:
cd /etc/ansible
ansible-playbook site.yml

在这里插入图片描述

总结

Ansible Playbook是自动化运维的核心工具,通过本文的详细解析,我们可以看到其强大的功能和灵活的应用方式。从基础的任务编写到高级的Roles模块化设计,Playbook提供了完整的自动化解决方案。

关键要点总结:

  1. Playbook采用YAML格式,结构清晰易读,支持多种控制结构
  2. 变量系统和模板技术使配置管理更加灵活和动态
  3. Tags系统提供了精确的任务执行控制能力
  4. Roles架构实现了代码的模块化和复用,大大提高了维护效率

通过合理运用这些特性,我们可以构建出高效、可靠且易于维护的自动化运维体系,适应各种复杂的部署和管理场景。掌握Ansible Playbook的编写技巧,将为您的自动化运维工作带来极大的便利和效率提升。


posted on 2025-10-10 10:20  ycfenxi  阅读(16)  评论(0)    收藏  举报