Ansible Playbook:自动化配置管理的利器
- 前言
- [一、 Playbook 的结构](#一、 Playbook 的结构)
- [二、 Ansible Playbook 示例](#二、 Ansible Playbook 示例)
- [三、 命令行运行 Playbook](#三、 命令行运行 Playbook)
- [四、 变量和引用](#四、 变量和引用)
- [五、 条件判断 `when`](#五、 条件判断
when
) - [六、 迭代:使用 `with_items` 或 `loop`](#六、 迭代:使用
with_items
或loop
) - [七、 Templates 模块](#七、 Templates 模块)
- [八、 Tags 模块](#八、 Tags 模块)
- [九、 Roles 模块](#九、 Roles 模块)
-
-
- [9.1 Roles 概念](#9.1 Roles 概念)
- [9.2 roles 内各目录含义解释](#9.2 roles 内各目录含义解释)
- [9.3 在一个 playbook 中使用 roles 的步骤](#9.3 在一个 playbook 中使用 roles 的步骤)
- [9.4 案列](#9.4 案列)
-
- [9.4.1 创建项目目录](#9.4.1 创建项目目录)
- [9.4.2 编写httpd模块](#9.4.2 编写httpd模块)
- [9.4.3 编写mysql模块](#9.4.3 编写mysql模块)
- [9.4.4 编写php模块](#9.4.4 编写php模块)
- [9.4.5 编写roles](#9.4.5 编写roles)
-
- 结语
前言
在当今的IT运维领域,自动化工具的应用已经成为提升效率和减少人为错误的关键手段。Ansible,作为一款开源的自动化引擎,以其简洁的语法、强大的功能和易于上手的特点,受到了广大运维工程师和开发者的青睐。特别是在配置管理和应用部署方面,Ansible通过其独特的Playbook机制,实现了对多台服务器的高效管理。本文将深入探讨Ansible Playbook的编写技巧,旨在帮助读者掌握这一强大的自动化工具,提升运维效率。
一、 Playbook 的结构
Ansible 的 Playbook 是一个包含多个 Play 的 YAML 文件,每个 Play 负责对指定的 主机组 执行一系列的任务。Playbook 通常由以下几部分组成:
- Tasks:每个任务会调用一个模块来在目标主机上执行操作。
- Variables:通过定义和使用变量,使 Playbook 更具灵活性和可重用性。
- Templates:通过 Jinja2 模板动态生成配置文件。
- Handlers :用于响应任务执行后的变更(
notify
触发)。 - Roles:把多个任务、变量、模板、文件、处理程序组织成模块化结构,便于复用。
二、 Ansible Playbook 示例
下面的示例展示了一个简单的 Playbook,演示了基本的任务执行流程和 Ansible 模块使用。
yaml
- name: install httpd
gather_facts: false
hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
- name: disable selinux
command: '/sbin/setenforce 0'
ignore_errors: True
- name: disable firewalld
service: name=firewalld state=stopped
- 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
notify: "restart httpd"
- name: start httpd service
service: enabled=true name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
三、 命令行运行 Playbook
在运行 Playbook 时,可以使用一些常用参数来调整执行行为:
bash
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' # 从指定任务开始执行
如果要使用 SSH 密码 或 sudo 密码,可以使用以下选项:
bash
ansible-playbook test1.yaml -k # 提示输入 SSH 密码
ansible-playbook test1.yaml -K # 提示输入 sudo 密码

四、 变量和引用
变量在 Playbook 中非常有用,它们可以通过 vars
或命令行进行定义。
yaml
- name: second play
hosts: dbservers
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
在命令行中,变量也可以通过 -e
参数传递:
bash
ansible-playbook test1.yaml -e "username=nginx"
五、 条件判断 when
when
用于根据条件执行任务。它的常见用法包括:
- 根据主机的 IP 地址来执行任务:
yaml
- name: shutdown host
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.10.14"

- 或根据主机名来执行:
yaml
when: inventory_hostname == "<主机名>"
六、 迭代:使用 with_items
或 loop
Ansible 支持使用 with_items
或 loop
进行迭代。两者作用相同,loop
是较新的推荐用法。
yaml
- name: play1
hosts: dbservers
gather_facts: false
tasks:
- name: create directories
file:
path: "{{item}}"
state: directory
with_items:
- /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
yaml
- name: loop
hosts: dbservers
gather_facts: false
tasks:
- name: create dir
file:
path: "{{item}}"
state: touch
loop:
- /opt/t1.txt
- /opt/t2.txt
- /opt/t3.txt

七、 Templates 模块
Jinja2 模板引擎在 Ansible 中用来动态生成文件。例如,在配置 Apache 时,可以使用模板文件来替换动态值。
- 创建 Jinja 模板文件 (
.j2
):
bash
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
vim /opt/httpd.conf.j2
Listen {{http_port}}
ServerName {{server_name}}
DocumentRoot "{{root_dir}}"
- 定义变量并在主机清单中指定:
ini
[webservers]
192.168.10.40 http_port=80 server_name=www.accp.com root_dir=/etc/httpd/conf
- Playbook 示例:
yaml
- 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
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 模块
Tags 允许你指定只执行某些特定任务。通过命令行传入 --tags
参数来执行带有特定标签的任务。
yaml
- hosts: webservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
tags:
- always

执行时指定 --tags
参数:
bash
ansible-playbook webhosts.yaml --tags="only"
九、 Roles 模块
9.1 Roles 概念
Roles 是将复杂的 Playbook 组织成独立的、更小的剧本和文件,提供了一种从外部文件加载任务、处理程序和变量的方法。Roles 可以编写成满足普通用途需求,并且能被重复利用。
9.2 roles 内各目录含义解释
- files: 用来存放由 copy 模块或 script 模块调用的文件。
- templates: 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件。
- tasks: 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表。
- handlers: 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作。
- vars: 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量。
- defaults: 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。
- meta: 此目录应当包含一个 main.yml 文件,用于定义此角色的特殊设定及其依赖关系。
9.3 在一个 playbook 中使用 roles 的步骤
- 创建以 roles 命名的目录。
- 创建全局变量目录(可选)。
- 在 roles 目录中分别创建以各角色名称命令的目录。
- 在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录。
- 在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件。
- 修改 site.yml 文件,针对不同主机去调用不同的角色。
- 运行 ansible-playbook。
9.4 案列
9.4.1 创建项目目录
yml
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml

9.4.2 编写httpd模块
yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apache
yum: name={{pkg}} state=latest
- name: start apache
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
9.4.3 编写mysql模块
yml
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
yum: name={{pkg}} state=latest
- name: start mysql
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
- mariadb
- mariadb-server
svc: mariadb
9.4.4 编写php模块
yml
vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
yum: name={{pkg}} state=latest
- name: start php-fpm
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/php/vars/main.yml
pkg:
- php
- php-fpm
svc: php-fpm
9.4.5 编写roles
yml
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- mysql
- php
cd /etc/ansible
ansible-playbook site.yml

结语
通过对Ansible Playbook编写技巧的全面介绍,我们可以看到,Ansible不仅能够简化复杂的运维任务,还能通过模块化的设计,提高脚本的复用性和可维护性。从基础的结构和示例,到变量、条件判断、迭代、模板、标签和角色等高级功能,Ansible Playbook提供了一套完整的解决方案,以满足各种自动化需求。希望本文的介绍能够帮助读者更好地理解和应用Ansible,从而在自动化运维的道路上走得更远。