目录
[3.1 定义变量](#3.1 定义变量)
[3.2 制定任务](#3.2 制定任务)
[3.3 调用角色模块](#3.3 调用角色模块)
[2.1 编写mysql模块文件](#2.1 编写mysql模块文件)
[2.2 编写php模块](#2.2 编写php模块)
引言
Ansible 是一款强大的自动化运维工具,它通过简单的配置文件(playbooks)和可复用的模块(modules)以及角色(roles)来描述 IT 基础架构的配置和部署过程。下面我将详细介绍如何编写一个Ansible Playbook,并展示如何使用模块和角色来组织和简化配置管理
一、templates模块
在 Ansible 中,templates 模块不是一个直接可调用的模块,而是通过 template 操作(action)来实现模板文件处理的功能。template 操作是 Ansible 的核心功能之一,它允许用户使用 Jinja2 模板语言来动态生成配置文件或其他文本文件,并将这些文件分发到远程主机上
Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记
(一)关键信息
模板文件:模板文件需要存储在 playbook 目录下的 templates 子目录中,并且文件名以 .j2 结尾,表明这是 Jinja2 模板文件。例如,一个名为 httpd.conf.j2 的文件可能包含了 Apache 配置,其中包含了一些由 Ansible 变量填充的占位符。
变量注入:Jinja2 模板支持从 Ansible 的变量中提取值,这些变量可以是 playbook 中定义的,也可以是从 inventory、角色默认变量、主机变量等来源获取的。变量使用双大括号 {{ variable_name }} 进行引用。
动态生成配置:当 playbook 运行时,Ansible 会处理这些模板文件,用实际的变量值替换模板中的占位符,从而生成最终的配置文件内容。
(二)实际操作
1.定义主机组
[root@ansible opt]#sed -n '32,34p' /etc/ansible/hosts
[web]
192.168.83.80 http_port=192.168.83.80:10000 server_name=www.pla.com:10000 dir_path=/data/html/
192.168.83.90 http_port=192.168.83.90:10001 server_name=www.china.com:10001 dir_path=/data/html/
[web]
#主机组名
第一条记录:
IP地址:192.168.83.80
HTTP端口配置:http_port=192.168.83.80:10000
#定义httpd_port变量值为192.168.83.80:10000,在后面通过编写.j2文件调用
#意味着这个服务器上的Web服务将在IP地址192.168.83.80的10000端口上监听
服务器名称:server_name=www.pla.com:10000
#同样定义变量值,在后面通过编写.j2文件调用
#表示通过域名www.pla.com和端口10000可以访问到这个服务器。
根目录:dir_path=/data/html/
#指出该Web服务器存储网页文件的根目录位于/data/html/下。
第二条记录:
IP地址:192.168.83.90
HTTP端口配置:http_port=192.168.83.90:10001
#这个服务器上的Web服务将在IP地址192.168.83.80的10001端口上监听
服务器名称:server_name=www.pla.com:10001
#与第一条记录相同
根目录:dir_path=/data/html/
#与第一个服务器意思相同
2.设置免密登录
[root@ansible opt]#ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:NMIiOsO4IB4KL4WshtpL8gk/U+uY6a1rT9nE3xKqZlE root@ansible
The key's randomart image is:
+---[RSA 2048]----+
| |
| . |
| . . o o |
|+o . oEo . |
|X+. .o S |
|O*. o+ o o |
|Ooo.ooo o . |
|oO+B+. . |
|.o&@= |
+----[SHA256]-----+
[root@ansible opt]#sshpass -p '123' ssh-copy-id root@192.168.83.80
[root@ansible opt]#sshpass -p '123' ssh-copy-id root@192.168.83.90
3.分别建立访问目录
[root@ansible opt]#echo "welcome to 192.168.83.80" >index.html
[root@ansible opt]#echo "welcome to 192.168.83.90" >/data/index.html
4.定义模板文件
[root@ansible data]#ls
httpd.conf
[root@ansible data]#cp httpd.conf httpd.conf.j2
[root@ansible data]#ls
httpd.conf httpd.conf.j2
[root@ansible data]#vim httpd.conf.j2
[root@ansible data]#cat -n httpd.conf.j2| sed -n '42p;95p;118,125p'
42 Listen {{http_port}}
95 ServerName {{server_name}}
118 #
119 DocumentRoot "{{dir_path}}"
120
121 #
122 # Relax access to content within /var/www.
123 #
124 <Directory "{{dir_path}}">
125 AllowOverride None
#所有的变量,取自于/etc/ansible/hosts文件中主机后面定义的变量值
-------------------------------------------------------------------------------------
Listen {{http_port}}
#指定HTTP服务监听的端口,这里使用模板变量{{http_port}}动态设定
ServerName {{server_name}}
#设置服务器的主机名或IP与端口号,同样使用模板变量{{server_name}}动态设定
DocumentRoot "{{dir_path}}"
#设置访问目录
<Directory "{{dir_path}}">
#同样设置访问目录,给目录授权,使httpd程序可以访问站点目录
5.创建playbook文件
name: httpd
#指定了剧本名称,
hosts: web
#指定了操作的目标为主机组web,且以root用户身份远程登录执行任务。
Vars:
#变量定义部分,用于设定剧本中将会引用的变量值。
#这里定义了两个变量:package为需要安装的软件包名(httpd),service为服务名(也是httpd)
tasks:
- name: firewalld
service: name=firewalld state=stopped
#关闭防火墙服务firewalld,以便HTTP服务可以无障碍地接收外部请求。
- name: install httpd
yum: name={{package}}
#使用YUM包管理器安装package定义的变量名的服务
- name: config
template: src=/data/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
#使用template模板功能将/data/httpd.conf.j2模板文件复制并到/etc/httpd/conf/httpd.conf
#作为HTTP服务器的配置文件。template模板会自动将httpd.conf.j2模板文件中定义的变量,替换为
#ansible的hosts文件中定义的各个变量值
notify: restart httpd
#此步骤通过notify: restart httpd来通知处理程序在配置更改后重启httpd服务。
- name: dir_path
file: path=/data/html/ state=directory
#确保/data/html/目录存在,用于存放网页文件。
- name: start httpd
service: name=httpd state=started
#启动httpd服务。
- name: index01
copy: src=/opt/index.html dest=/data/html/
when: ansible_default_ipv4.address == '192.168.83.80'
- name: index02
copy: src=/data/index.html dest=/data/html/
when: ansible_default_ipv4.address == '192.168.83.90'
#根据远程主机的IPv4地址条件性地从不同源路径拷贝index.html文件到/data/html/目录下。
#如果主机IP为192.168.83.80,则从/opt/index.html拷贝;
#如果为192.168.83.90,则从/data/index.html拷贝。
handlers:
- name: restart httpd
service: name={{service}} state=restarted
#handlers处理程序块,定义了在特定条件下执行的操作。这里只有一个处理程序restart httpd,
#当有任务通知(通过notify: restart httpd)时,会重启httpd服务,确保配置变更生效。
6.执行剧本
7.验证结果
7.1 访问验证
7.2 查看配置文件
二、tags模块
在Ansible中,tags模块并不是一个实际的模块,而是Playbooks中一个非常有用的功能,它允许用户为任务或者播放(plays)分配标签(tags)。这些标签可以帮助你在执行Playbook时,有选择性地执行特定的任务集,而不是默认执行所有任务。这对于大型Playbook的管理和维护特别有帮助,因为你可以在不同的场景下,快速执行或跳过某些任务
(一)创建playbook文件
[root@ansible data]#vim tags.yaml
[root@ansible data]#cat tags.yaml
---
- name: tags_server
hosts: web
tasks:
- name:
file: path=/opt/test/ state=directory
tags:
- dir #设置标签名称为dir
- name:
file: path=/opt/test01/ state=directory
tags:
- dira #设置标签名称为dira
- name:
file: path=/opt/test02/ state=directory
tags:
- dirb #设置标签名称为dirb
(二)调用标签
当你运行Playbook时,可以通过**--tags**选项指定你想要执行的标签。Ansible将仅执行那些匹配指定标签的任务
ansible-playbook 剧本名 --tags="标签名"
去远程主机查看
[root@client01 opt]#ls
rh test01
#只执行了指定标签的任务,建立了test01目录文件
(三)跳过标签
如果你想执行除了某些标签之外的所有任务,可以使用**--skip-tags** 选项
在远程主机查看
(四)特殊标签
Ansible还支持一些特殊标签,如always和never。带有always标签的任务总会被执行,而带有never标签的任务则永远不会被执行,无论命令行中指定了哪些标签
重新定义一个playbook剧本
执行剧本
指定执行标签名为dir的的任务,即使不指定always标签,它的任务也同样会执行
执行顺序默认时从上往下执行,即使你指定标签,如果always标签在指定标签的上方,那么它就会先执行always标签的任务
当指定never标签,它的任务才会被执行
(五)play级标签
除了在任务级别,还可以在Play级别定义标签,这样该Play下的所有任务(除非被特定任务的标签覆盖)都将继承该Play的标签
指定需要执行的play任务
只会执行指定的play任务,下面的任务并不会被执行
三、roles模块
在Ansible中,roles 是一种强大的组织和复用配置管理代码的方法,它从 Ansible 版本1.2 开始被引入。角色设计的目的是为了实现配置的层次化和结构化,使得 Playbooks 更加清晰、易于管理和重复利用
(一)角色的优势
- 模块化: 角色使得复杂的配置任务得以分解,每个角色负责一部分功能,便于管理和维护。
- 重用性: 可以在多个项目或不同环境中重用相同的角色。
- 团队协作: 团队成员可以独立开发和测试各自负责的角色,然后集成到更大的自动化流程中。
- 清晰性: Playbooks 变得更简洁,因为具体的配置细节被封装在角色中
(二)基本构成
ansible的角色目录,yum安装默认存放在/etc/ansible/目录下
一个典型的 Ansible 角色目录结构可能包含以下几个部分
files: 用来存放由 copy 模块或 script 模块调用的文件。
**templates:**存放Jinja2模板文件,用于动态生成配置文件。
**tasks: (tasks/main.yml) :此目录应当包含一个 main.yml 文件。**包含了该角色需要执行的任务列表。
**handlers: (handlers/main.yml):此目录应当包含一个 main.yml 文件 。**定义了在特定条件触发时执行的操作,如服务重启。
**vars: (vars/main.yml): 此目录应当包含一个 main.yml 文件 。**定义角色内部使用的变量。
**defaults: (defaults/main.yml):此目录应当包含一个 main.yml 文件 。**提供角色的默认变量值,这些值可以被覆盖。
**meta: (meta/main.yml):此目录应当包含一个 main.yml 文件 。**包含角色的元数据,比如角色的依赖关系。
(三)模块使用
1.定义主机组
[root@ansible data]#vim /etc/ansible/hosts
[root@ansible data]#sed -n '32,35p' /etc/ansible/hosts
[web]
192.168.83.80
[webserver]
192.168.83.90
2.创建目录组件
[root@ansible data]#mkdir -p /etc/ansible/roles/nginx/{files,templates,tasks,handlers,vars,defaults,meta}
[root@ansible data]#ll /etc/ansible/roles/
总用量 0
drwxr-xr-x 9 root root 105 5月 8 21:29 nginx
[root@ansible data]#ll /etc/ansible/roles/nginx/
总用量 0
drwxr-xr-x 2 root root 6 5月 8 21:29 defaults
drwxr-xr-x 2 root root 6 5月 8 21:29 files
drwxr-xr-x 2 root root 6 5月 8 21:29 handlers
drwxr-xr-x 2 root root 6 5月 8 21:29 meta
drwxr-xr-x 2 root root 6 5月 8 21:29 tasks
drwxr-xr-x 2 root root 6 5月 8 21:29 templates
drwxr-xr-x 2 root root 6 5月 8 21:29 vars
3.编写各类文件
3.1 定义变量
定义变量,需要在vars目录下建立mian.yml文件
[root@ansible data]#vim /etc/ansible/roles/nginx/vars/main.yml
[root@ansible data]#cat /etc/ansible/roles/nginx/vars/main.yml
epel: epel-release.noarch
package: nginx
3.2 制定任务
制定任务需要在tasks目录下建立main.yml文件
[root@ansible data]#vim /etc/ansible/roles/nginx/tasks/main.yml
[root@ansible data]#cat /etc/ansible/roles/nginx/tasks/main.yml
- name: install epel
yum: name={{epel}} #调用vars中定义的变量,下载epel源
- name: install nginx
yum: name={{package}} state=latest #下载nginx服务
- name: start nginx
service: enabled=true name={{package}} state=started #启动nginx服务
3.3 调用角色模块
在/etc/ansible/目录下,编写yml文件
[root@ansible data]#vim /etc/ansible/nginx.yml
[root@ansible data]#cat /etc/ansible/nginx.yml
---
- hosts: web #指定主机组
remote_user: root #指定远程连接用户
roles: #使用roles模块
- nginx #使用模块目录名,为nginx
4.执行模块
访问测试
(四)多角色搭建服务
1.创建目录
[root@ansible data]#mkdir -p /etc/ansible/roles/{mysql,php}/{files,templates,tasks,handlers,vars,defaults,meta}
[root@ansible data]#ls /etc/ansible/roles/mysql/
defaults files handlers meta tasks templates vars
[root@ansible data]#ls /etc/ansible/roles/php/
defaults files handlers meta tasks templates vars
[root@ansible data]#ls /etc/ansible/roles/nginx/
defaults files handlers meta tasks templates vars
2.编写模块文件
2.1 编写mysql模块文件
2.1.1 定义变量
[root@ansible data]#cat /etc/ansible/roles/mysql/vars/main.yml
package:
- mariadb
- mariadb-server
server: mariadb
2.1.2 制定任务
[root@ansible data]#cat /etc/ansible/roles/mysql/tasks/main.yml
- name: install mariadb
yum: name={{package}} state=latest
- name: start mariadb
service: enabled=true name={{server}} state=started
2.2 编写php模块
2.1.1 定义变量
[root@ansible data]#vim /etc/ansible/roles/php/vars/main.yml
[root@ansible data]#cat /etc/ansible/roles/php/vars/main.yml
package:
- php
- php-fpm
server: php-fpm
2.1.2 制定任务
[root@ansible data]#vim /etc/ansible/roles/php/tasks/main.yml
[root@ansible data]#cat /etc/ansible/roles/php/tasks/main.yml
- name: install php
yum: name={{package}} state=latest
- name: start php-fpm
service: enabled=true name={{server}} state=started
3.调用角色模块
[root@ansible data]#vim /etc/ansible/nmp.yml
[root@ansible data]#cat /etc/ansible/nmp.yml
---
- hosts: webserver
remote_user: root
roles:
- nginx #按顺序,依次执行,先执行nginx角色模块
- mysql
- php
4.执行模块
远端主机查看是否安装