Ansible任务剧本Playbook之变量、模板、角色介绍

前言

上篇介绍了 Ansible 单模块(AD-Hoc)的相关内容Ansible自动化运维工具单模块介绍-CSDN博客,Ad-Hoc 命令是一次性的、即时执行的命令,用于在远程主机上执行特定任务,这些命令通常用于快速执行简单的任务。当需要在执行多个任务、配置复杂场景或需要可重复使用操作时,就需要用到任务剧本(Playbook)来定义复杂的任务流程和处理重复执行的操作。

Playbook 也通常被大家翻译成剧本。可以认为它是 Ansible 自定义的一门语言(可以将 Playbook 比作 Linux 中的 shell,而 Ansible 中的 Module 可以比作为 Linux 中的各种命令。

目录

一、主机清单

1. 概述

2. 主机定义

2.1 inventory 中的变量

2.2 主机变量

2.3 组变量

2.4 组嵌套

二、YAML 非标记语言

1. 概述

2. Yaml 特点

3. 基本语法

3.1 字符串 

3.2 列表

3.3 字典

3.4 混合结构

三、任务剧本 Playbook

1. 概述

2. 组成

3. Play 常用属性 

4. tasks 属性中任务的多种写法

5. Playbook 校验与执行

5.1 语法检验

5.2 列出任务

5.3 列出主机

5.4 单步跟重调试

5.5 测试运行

5.6 执行

6. 编写一个 Playbook

6.1 定义主机清单

6.2 编写 Yaml 文件

7. 定义、引用变量

7.1 定义剧本

7.2 执行剧本

8. 指定远程主机 sudo 切换用户 

8.1 通过 visudo 来管理用户权限

8.2 sudo提权操作

9. when 条件判断

10. 迭代 

11. Templates 模块

11.1 概述

11.2 示例

12. Tags 模块

12.1 概述

12.2 示例

13. Roles 模块

13.1 概述

13.2 目录介绍

13.2.1 在一个 playbook 中使用 roles 的步骤

13.3 示例:简单的LNMP

13.3.1 定义 nginx 角色变量

13.3.2 编写 nginx 模块

13.3.3 定义 mysql 角色变量

13.3.4 编写 mysql 模块

13.3.5 定义 php 角色变量

13.3.6 编写 php 模块

13.3.7 定义主机清单

13.3.8 编写 roles

13.3.9 启动剧本

13.3.10 查看服务


一、主机清单

1. 概述

在 Ansible 中,inventory 主机清单是一个关键概念,用于定义 Ansible 将要管理的主机和主机组。主机清单可以包含主机的 IP 地址、主机名、主机组等信息,以便 Ansible 可以根据清单中的定义来执行任务。

2. 主机定义

一般情况下,可以修改 /etc/ansible/hosts 文件内容,来对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机内。示例如下:

[root@control ~]# vim /etc/ansible/hosts
[webs]
192.168.190.100:2222		# 冒号后定义远程连接端口,默认是ssh的22端口
192.168.190.20[0:9]         # 代表200~209

[dbs]
db-[a:d].example.org	    # 支持匹配a~d,支持域名

2.1 inventory 中的变量

Inventory变量名含义
ansible_hostansible连接节点时的IP地址
ansible_port连接对方的端口号,ssh连接时默认为22
ansible_user连接对方主机时使用的主机名。不指定时,将使用执行ansible或ansible-playbook命令的用户
ansible_password连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效
ansible_ssh_private_key_file指定密钥认证ssh连接时的私钥文件
ansible_ssh_common_args提供给ssh、sftp、scp命令的额外参数
ansible_become允许进行权限提升
ansible_become_method指定提升权限的方式,例如可使用sudo/su/runas等方式
ansible_become_user提升为哪个用户的权限,默认提升为root
ansible_become_password提升为指定用户权限时的密码

2.2 主机变量

[webs]
192.168.190.100 ansible_port=2222 ansible_user=root ansible_password=123456
# ansible_port=2222:指定 SSH 连接的端口号为 2222。
# ansible_user=root:指定 SSH 连接的用户名为 root。
# ansible_password=123456:指定 SSH 连接的密码为 123456。

2.3 组变量

[webs:vars]			        # 表示为webs组内所有主机定义变量
ansible_user=root
ansible_password=123456

[all:vars]					# 表示为所有组内的所有主机定义变量
ansible_port=22
# vars是一个关键字,用于定义变量。在主机清单文件中,可以使用vars关键字为主机组或单个主机定义变量

2.4 组嵌套

[nginx]
192.168.190.100
192.168.190.101
192.168.190.102

[apache]
192.168.190.20[0:2]

[webs:children]		#表示为webs主机组中包含了nginx组和apache组内的所有主机
nginx
apache
# children是一个特殊的关键字,用于定义主机组之间的父子关系
# 当你在主机清单中使用[webs:children]这样的语法时,表示webs主机组是一个父组,包含了nginx组和apache组内的所有主机。

二、YAML 非标记语言

1. 概述

YAML 是一种人类可读的数据序列化格式,常用于配置文件和数据传输。它以缩进、换行和符号结构来表示数据,具有简洁、清晰的特点。YAML 旨在成为一个易于阅读和编写的数据格式,同时也适合机器解析和生成。它使用空格缩进来表示层级关系,不需要显式的标记符号(如 XML 或 JSON 中的尖括号或大括号),这使得它更加直观和易读。

2. Yaml 特点

YAML文件

  • 以 #为注释符
  • 以 .yml 或者 .yaml 结尾
  • 以 --- 开始,以 ... 结束,但开始和结束标志都是可选的

3. 基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时是使用Tab键还是使用空格一定要达到统一,建议使用空格
  • 相同层级的元素必须左侧对齐即可

 YAML 支持的数据结构有三种:

  • 字符串
  • 列表
  • 字典

3.1 字符串 

---
# YAML 中的字符串可以不使用引号,即使里面存在空格的时候,当然了使用单引号和双引号也可以
this is a string
'this is a string'
"this is a string"
# YAML 中若一行写不下要表述的内容,可以进行折行。写法如下:
long line: |
Example 1
Example 2
Example 3
# 或者
long line: >
Example 1
Example 2
Example 3
...

3.2 列表

在 YAML 中,列表使用短横线 - 表示,后面跟着一个空格。列表可以包含任意类型的元素,例如字符串、数字、布尔值或者其他嵌套的列表。

---
#可以认为它就是 python 中的 List,可以认为它是 c 语言中的数组。
# 如何定义:以短横线开头 + 空格 + 具体的值
- red
- green
- blue
# 以上的值假如转换成 python 的 List 会是这样:
# ['red', 'green', 'blue']
...

3.3 字典

字典在 YAML 中使用键值对的形式表示,使用冒号 : 将键和值分隔开,键值之间需要有一个空格。字典可以包含嵌套的字典或者列表作为值。 

---
# 可以认为它就是 python 中的 Dict (字典)
# 如何定义:key + 冒号(:) + 空格 + 值(value),即 key: value
name: Using Ansible
code: D1234
#转换为 python 的 Dict
#{'name': 'Using Ansibel','code': 'D1234'}
...

3.4 混合结构

但在日常生产中,往往需要的数据结构会特别复杂,有可能会是字符串、列表、字典的组合形式。这里举一个例子:学校里是以班级为单位。使用列表和字典的形式去描述一个班级的组成:

---
class:
  - name: stu1
    num: 001
  - name: stu2
    num: 002
  - name: stu3
    num: 003
#{'class': [{'name': 'stul, 'num': 1},{'name': 'stu2', 'num': 2), ...]}
...

三、任务剧本 Playbook

1. 概述

Ansible playbook 是一个用 YAML 格式编写的文件,其中包含了一系列任务(tasks)和其他配置信息,用于描述 Ansible 在远程主机上执行的自动化任务和操作步骤;是一种通过 YAML 语言方式编写的一种策略。

2. 组成

  • Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
  • Variables:变量
  • Templates:模板
  • Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
  • Roles:角色

3. Play 常用属性 

  • name 属性:每个play的名字
  • hosts 属性:每个play涉及的被管理服务器,同 ad-hoc 中的资产选择器
  • tasks 属性:每个play 中具体要完成的任务,以列表的形式表达
  • become 属性:如果需要提权,则加上become相关属性
  • becomekuser 属性:若提权的话,提权到哪个用户上
  • remote_user 属性:指定连接到远程节点上的用户,即远程服务器上执行操作的用户。若不指定,则默认使用当前执行 ansible Playbook 的用户

4. tasks 属性中任务的多种写法

# 以启动 apache 服务,并增加开机启动为例
#一行的形式:
service: name=apache enabled=true state=started
#多行的形式:
sefvice: name=apache
         enabled=true
         state=started
#多行写成字典的形式:
service:
  name: apache
  enabled: true
  state: started

5. Playbook 校验与执行

5.1 语法检验

ansible-playbook example.yaml  --syntax-check

5.2 列出任务

ansible-playbook example.yaml --list-tasks

5.3 列出主机

ansible-playbook example.yaml --list-hosts

5.4 单步跟重调试

指定从某个 task 开始运行,需要手动确认是否往下执行。

ansible-playbook example.yaml --step
示例:
ansible-playbook example.yaml --start-at-task='install httpd'

5.5 测试运行

会执行完整的 Playbook,但是所有 task 中的行为都不会在远程被管理节点服务器上执行,所有的操作都是模拟。

ansible-playbook apache.yaml --C  #大写的C

5.6 执行

ansible-playbook example.yaml
补充参数:
# -k(–ask-pass):用来交互输入ssh密码
# -K(-ask-become-pass):用来交互输入sudo密码
# -u:指定用户

6. 编写一个 Playbook

6.1 定义主机清单

[root@control ~]# vim /etc/ansible/hosts
[webs]
192.168.190.104

[dbs]
192.168.190.105

[servers:children]
webs
dbs

6.2 编写 Yaml 文件

批量安装apache

① 准备工作,卸载目标主机网站服务

管理节点:
[root@control ~]# ansible all -m yum -a "name=httpd state=removed"
#在Ansible中,all是一个用于指代所有主机的特殊关键字。当你在使用Ansible命令时,使用all会将命令应用到所有已定义的主机上。卸载httpd相关服务。
 
被管理节点:
[root@managed1 ~]# yum list | grep httpd | grep @
httpd-tools.x86_64                       2.4.6-99.el7.centos.1         @updates 
#检查是否还有安装httpd相关包。
 
管理节点:
[root@control ~]# ansible all -m yum -a "name=httpd-tools state=removed"
#卸载httpd工具包,避免影响安装httpd。
 
管理节点:
[root@control ~]# yum install -y httpd
#Ansible服务器安装网站服务
[root@control ~]# cp -rf /etc/httpd/conf/httpd.conf /opt/

② 编写剧本

---                    # #yaml文件以---开头,以表明这是一个yaml文件,可省略
- name: install apache # 定义一个play的名称,可省略
  gather_facts: false  # 设置不进行facts信息收集,这可以加快执行速度,可省略
  hosts: servers       # 指定要执行任务的被管理主机组,如多个主机组用冒号分隔,不可省略
  remote_user: root    # 指定被管理主机上执行任务的用户,默认root,可选择省略
  tasks:               # 定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
    - name: ping       # 自定义任务名称
      ping:            # 使用module: [options]格式来定义一个任务
    - name: disable firewalld
      service: name=firewalld state=stopped # 使用module: options格式来定义任务,option使用key=value格式
    - name: disable selinux
      command: '/sbin/setenforce 0' # command模块和shell模块无需使用key=value格式
      ignore_errors: True           # 如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
    - name: install httpd
      yum: name=httpd state=latest
    - name: copy apache conf
      copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf # 这里需要一个事先准备好的/opt/httpd.conf文件
      notify: "restart httpd"  # 如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
    - name: start http 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,从而避免多次重启。

③ 检查测试 

[root@control ~]# ansible-playbook apache.yml --syntax-check # 检查语法

playbook: apache.yml
[root@control ~]# ansible-playbook apache.yml --list-tasks   # 列出任务

playbook: apache.yml

  play #1 (servers): install apache	TAGS: []
    tasks:
      ping	TAGS: []
      disable firewalld	TAGS: []
      disable selinux	TAGS: []
      install apache	TAGS: []
      copy apache conf	TAGS: []
      start http service	TAGS: []
[root@control ~]# ansible-playbook apache.yml --list-hosts   # 列出主机

playbook: apache.yml

  play #1 (servers): install apache	TAGS: []
    pattern: [u'servers']
    hosts (2):
      192.168.190.105
      192.168.190.104

④ 执行剧本

[root@control ~]# ansible-playbook apache.yml 
[root@control ~]# ansible all -a 'systemctl status httpd'
192.168.190.105 | CHANGED | rc=0 >>
 Main PID: 51200 (httpd)
192.168.190.104 | CHANGED | rc=0 >>
 Main PID: 8465 (httpd)

7. 定义、引用变量

是一种定义的任务方式,在编写 playbook 时,可以使用变量来传输数据;playbook 引用变量值的是在 playbook 中使用变量代理静态常量值,来实现动态的配置过程;通过引用变量,可以使 playbook 更具有灵活性和可重复性。

7.1 定义剧本

[root@control ~]# vim vars.yml
- hosts: webs
  vars:                   # 定义变量
    - username: zhangsan  # 格式为 key: value
    - groupname: student
  tasks:
    - name: create group
      group: name={{groupname}} system=yes gid=1500 # 使用 {{key}} 引用变量的值
    - name: create user
      user: name={{username}} uid=1500 group={{groupname}}
    - name: copy file
      copy: content="{{ansible_default_ipv4}}" dest=/opt/1.txt
# 在setup模块中可以获取facts变量信息

7.2 执行剧本

由此可见,在命令行里定义变量,优先级大于 playbook 中的。

8. 指定远程主机 sudo 切换用户 

8.1 通过 visudo 来管理用户权限

在 managed1 操作:

[root@managed1 opt]# su - lisi
[lisi@managed1 ~]$ cd /opt/
[lisi@managed1 opt]$ ls
1.txt  a.txt  rh  script.txt
[lisi@managed1 opt]$ rm -rf a.txt 
rm: 无法删除"a.txt": 权限不够
[lisi@managed1 opt]$ exit
登出

[root@managed1 ~]# visudo
lisi    ALL=(ALL)       ALL
[root@managed1 ~]# passwd lisi
123456

8.2 sudo提权操作

在 control 节点操作:

① 编写剧本

[root@control ~]# vim sudo.yml
- hosts: webs
  remote_user: lisi
  become: yes
  become_user: root
  tasks:
    - name: rm
      command: /usr/bin/rm -f /opt/a.txt
[root@control ~]# ansible-playbook sudo.yml --syntax-check

playbook: sudo.yml

或者:
- hosts: webs
  remote_user: lisi
  become: yes
  become_user: root
  tasks:
    - name: rm
      file: name=a.txt state=absent

② 执行剧本

[root@control ~]# sshpass -p '123456' ssh-copy-id lisi@192.168.190.104
[root@control ~]# ansible-playbook sudo.yml -K
BECOME password: 123456

PLAY [webs] ***************************************************************************************

TASK [Gathering Facts] ****************************************************************************
ok: [192.168.190.104]

TASK [rm] *****************************************************************************************
ok: [192.168.190.104]

PLAY RECAP ****************************************************************************************
192.168.190.104            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

9. when 条件判断

在 Ansible 中,提供的唯一一个通用的条件判断是 when 指令,当 when 指令的值为 true 时,则该任务执行,否则不执行该任务。

when 是一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务。

① 编写剧本

[root@control ~]# vim when.yml
- hosts: all
  tasks:
    - name: shutdown host
      command: /usr/sbin/shutdown -r now
      when: ansible_default_ipv4.address == "192.168.190.105"
或者:
      when: inventory_hostname == "主机名"
# when指令中的变量名不需要手动加上 {{}}
[root@control ~]# ansible-playbook when.yml --syntax-check

playbook: when.yml

② 执行剧本

[root@control ~]# ansible-playbook when.yml

查看 105 机器已重启:

10. 迭代 

Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环。loop 是一种用于循环执行任务的结构,它允许在 playbook 中遍历一个列表,并对每个元素执行相同的任务。

① 编写剧本

示例:同时创建多个文件夹、同时创建多个用户

[root@control ~]# vim items.yml
- hosts: dbs
  tasks:
    - name: mkdir
      file: path="{{item}}" state=directory
      with_items:
        - /opt/a1
        - /opt/a2
    - name: useradd
      user: name={{item.name}} state=present groups={{iteam.groups}}
      with_items:
        - name: a1
          groups: root
        - name: a2
          groups: root
或者: 
      with_items:
        - {name:'a1', groups:'root'}
        - {name:'a2', groups:'root'}
[root@control ~]# ansible-playbook items.yml --syntax-check

playbook: items.yml

② 执行剧本

[root@control ~]# ansible-playbook items.yml 

PLAY [dbs] ****************************************************************************************

TASK [Gathering Facts] ****************************************************************************
ok: [192.168.190.105]

TASK [mkdir] **************************************************************************************
ok: [192.168.190.105] => (item=/opt/a1)
ok: [192.168.190.105] => (item=/opt/a2)

TASK [useradd] ************************************************************************************
changed: [192.168.190.105] => (item={u'name': u'a1', u'groups': u'root'})
changed: [192.168.190.105] => (item={u'name': u'a2', u'groups': u'root'})

PLAY RECAP ****************************************************************************************
192.168.190.105            : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

③ 查看结果

[root@control ~]# ansible dbs -a 'ls -l /opt/'
192.168.190.105 | CHANGED | rc=0 >>
总用量 4
drwxr-xr-x  2 root root   6 5月   7 18:54 a1
drwxr-xr-x  2 root root   6 5月   7 18:54 a2
-rwxrwxrwx  1 fql  fql  465 5月   6 22:03 fstab.bak
lrwxrwxrwx  1 root root  14 5月   6 22:14 fstab.link -> /opt/fstab.bak
drwxr-xr-x. 2 root root   6 3月  26 2015 rh
# a1、a2文件夹已创建

[root@control ~]# ansible dbs -a 'id a1'
192.168.190.105 | CHANGED | rc=0 >>
uid=2001(a1) gid=2001(a1) 组=2001(a1),0(root)
[root@control ~]# ansible dbs -a 'id a2'
192.168.190.105 | CHANGED | rc=0 >>
uid=2002(a2) gid=2002(a2) 组=2002(a2),0(root)
# 用户已创建

11. Templates 模块

11.1 概述

是一种创建配置文件的工具,在配置文件中,会有一些数据(如:ip 地址、主机名、端口、用户、页面路径等)会动态的改变,需要使用变量来表示;

template 模块就是将变量和动态文件结合起来,最终生成一个配置文件(需要动态改变)。文件使用 jinjia2 模块语言来编写,结尾(后缀)一定是 j2(xxx.j2)。

11.2 示例

使用 template 模块配置相关变量,通过 playbook 安装 apache。

① 先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量

[root@control yml]# cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
[root@control yml]# vim /opt/httpd.conf.j2
 42 Listen {{http_port}}
 96 ServerName {{server_name}}
120 DocumentRoot "{{html_path}}"
125 <Directory "{{html_path}}">

② 修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量

[root@control yml]# vim /etc/ansible/hosts
[apache1]
192.168.190.104 http_port=666 server_name=www.abc.com html_path=/opt/

[apache2]
192.168.190.105 http_port=888 server_name=www.efg.com html_path=/opt/

③ 编写 playbook 

[root@control yml]# pwd
/root/yml
[root@control yml]# vim httpd.yml
---
- hosts: apache1,apache2
  vars:
    - {package: httpd, service: httpd}
  tasks:
    - name: install package
      yum: name={{package}} state=latest
    - name: copy configure j2
      template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      notify: restart httpd
    - name: copy html file
      copy: src=/root/yml/index.html dest=/opt/ mode=644
      notify: restart httpd
    - name: start httpd server
      service: name={{service}} enabled=true state=started
  handlers:
    - name: restart httpd
      service: name={{service}} state=restarted
...
[root@control yml]# ansible-playbook httpd.yml --syntax-check

playbook: httpd.yml

④ 准备工作,卸载目标主机网站服务

管理节点:
[root@control ~]# ansible all -m yum -a "name=httpd state=removed"
#在Ansible中,all是一个用于指代所有主机的特殊关键字。当你在使用Ansible命令时,使用all会将命令应用到所有已定义的主机上。卸载httpd相关服务。
 
被管理节点:
[root@managed1 ~]# yum list | grep httpd | grep @
httpd-tools.x86_64                       2.4.6-99.el7.centos.1         @updates 
#检查是否还有安装httpd相关包。
 
管理节点:
[root@control ~]# ansible all -m yum -a "name=httpd-tools state=removed"
#卸载httpd工具包,避免影响安装httpd。
 
管理节点:
[root@control ~]# yum install -y httpd
#Ansible服务器安装网站服务
[root@control ~]# cp -rf /etc/httpd/conf/httpd.conf /opt/

⑤ 执行 playbook 

[root@control yml]# echo welcome apache > index.html
[root@control yml]# ansible-playbook httpd.yml
[root@control yml]# ansible all -a 'systemctl status httpd'
192.168.190.105 | CHANGED | rc=0 >>
 Main PID: 9400 (httpd)
192.168.190.104 | CHANGED | rc=0 >>
 Main PID: 18585 (httpd)

⑥ 访问域名及对应端口

[root@control yml]# vim /etc/hosts
192.168.190.104 managed1 www.abc.com
192.168.190.105 managed2 www.efg.com

[root@control yml]# curl www.abc.com:666/index.html
welcome apache
[root@control yml]# curl www.efg.com:888/index.html
welcome apache

12. Tags 模块

12.1 概述

可以在一个 playbook 中为某个或某些任务定义“标签”,在执行此 playbook 时通过 ansible-playbook 命令使用 --tags 选项能实现仅运行指定的 tasks。playbook 还提供了一个特殊的 tags 为 always。作用就是当 tasks 中的 tags 为 always 时,无论执行哪一个 tags 时,定义有 always 的 tags 都会执行。且执行顺序从上往下。

是一种标记任务或一系列的任务的功能,通过任务或一个命令的任务列表上定义标记,可以在运行 playbook 时去选择你需要执行的任务或列表。

12.2 示例

① 编写 playbook

[root@control yml]# vim tag.yml
- hosts: apache2
  tasks:
    - name: copy file
      copy: src=/etc/hosts dest=/opt/1.txt
      tags:
        - a
    - name: touch file
      file: path=/opt/2 state=touch
      tags:
        - always
    - name: mkdir
      file: path=/opt/3 state=directory
      tags:
        - b
[root@control yml]# ansible-playbook tag.yml --syntax-check

playbook: tag.ym

② 执行 playbook 

[root@control yml]# ansible-playbook tag.yml --tags="b"

[root@control yml]# ansible apache2 -a 'ls -l /opt/'
192.168.190.105 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root   0 5月   8 16:15 2
drwxr-xr-x 2 root root   6 5月   8 16:15 3

13. Roles 模块

13.1 概述

Ansible 为了层次化、结构化地组织 Playbook,使用了角色(roles),roles 可以根据层次型结构自动装载变量文件、task 以及 handlers 等。简单来讲,roles 就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地 include 它们。roles 一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。

13.2 目录介绍

13.2.1 在一个 playbook 中使用 roles 的步骤

① 创建以 roles 命名的目录

mkdir /etc/ansible/roles/ -p # yum装完默认就有

② 创建全局变量目录(可选)

mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all     # 文件名自己定义,引用的时候注意

③ 在 roles 目录中分别创建以各角色名称命令的目录,如 nginx、mysql

[root@control ~]# mkdir /etc/ansible/roles/nginx
[root@control ~]# mkdir /etc/ansible/roles/mysql
[root@control ~]# mkdir /etc/ansible/roles/php

④ 在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建

[root@control ~]# mkdir /etc/ansible/roles/nginx/{files,templates,tasks,handlers,vars,defaults,meta}
[root@control ~]# mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
[root@control ~]# mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta}

⑤ 在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件,千万不能自定义文件名

[root@control ~]# touch /etc/ansible/roles/nginx/{defaults,vars,tasks,meta,handlers}/main.yml
[root@control ~]# touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
[root@control ~]# touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml

⑥ 查看 roles 的目录结构

[root@control ~]# tree /etc/ansible/roles/
/etc/ansible/roles/
├── mysql
│   ├── defaults
│   │   └── main.yml
│   ├── files
│   ├── handlers
│   │   └── main.yml
│   ├── meta
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   ├── templates
│   └── vars
│       └── main.yml
├── nginx
│   ├── defaults
│   │   └── main.yml
│   ├── files
│   ├── handlers
│   │   └── main.yml
│   ├── meta
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   ├── templates
│   └── vars
│       └── main.yml
└── php
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    └── vars
        └── main.yml

roles 内各目录含义解释:

files:

  • 用来存放由 copy 模块或 script 模块调用的文件

templates:

  • 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件 

tasks:

  • 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件 

handlers:

  • 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作 

vars:

  • 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量 

defaults:

  • 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量 

meta:

  • 此目录应当包含一个 main.yml 文件,用于定义此角色的特殊设定及其依赖关系 

⑦ 编辑 yml 剧本针对不同主机去调用不同的角色

vim /etc/ansible/example.yml

⑧ 运行 ansible-playbook

cd /etc/ansible
ansible-playbook example.yml

13.3 示例:简单的LNMP

13.3.1 定义 nginx 角色变量

定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中

[root@control ansible]# vim /etc/ansible/roles/nginx/vars/main.yml
epel:
  - epel-release.noarch
page:
  - nginx
service: nginx
13.3.2 编写 nginx 模块
[root@control ansible]# vim /etc/ansible/roles/nginx/tasks/main.yml
- name: install epel-release.noarch
  yum: name={{epel}} state=latest
- name: install nginx
  yum: name={{page}} 
- name: start nginx
  service: enabled=true name={{service}} state=started
13.3.3 定义 mysql 角色变量
[root@control ansible]# vim /etc/ansible/roles/mysql/vars/main.yml
page: 
  - mariadb
  - mariadb-server
service: mariadb
13.3.4 编写 mysql 模块
[root@control ansible]# vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
  yum: name={{page}} state=latest
- name: start mysql
  service: enabled=true name={{service}} state=started
13.3.5 定义 php 角色变量
[root@control ansible]# vim /etc/ansible/roles/php/vars/main.yml
page:
  - php
  - php-fpm
service: php-fpm
13.3.6 编写 php 模块
[root@control ~]# vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
  yum: name={{page}} state=latest
- name: start php-fpm
  service: enabled=true name={{service}} state=started
13.3.7 定义主机清单
[root@control ~]# vim /etc/ansible/hosts
[nginx]
192.168.190.104 

[mysql]
192.168.190.105 

[php]
192.168.190.106

[lnmp:children]
nginx
mysql
php
13.3.8 编写 roles
[root@control ~]# cd /etc/ansible/
[root@control ansible]# vim roles.yml
- hosts: nginx
  roles:
    - nginx
- hosts: mysql
  roles:
    - mysql
- hosts: php
  roles:
    - php
[root@control ansible]# ls
ansible.cfg  hosts  roles  roles.yml
13.3.9 启动剧本
所有机器添加DNS解析域名加速:
vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.190.103 control
192.168.190.104 managed1 www.abc.com
192.168.190.105 managed2 www.efg.com
192.168.190.106 managed3

[root@control ansible]# ssh 192.168.190.106
[root@control ansible]# sshpass -p '123' ssh-copy-id root@192.168.190.106

[root@control ansible]# ansible-playbook roles.yml
13.3.10 查看服务
[root@control ansible]# ansible nginx -a 'systemctl status nginx'
192.168.190.104 | CHANGED | rc=0 >>
 Main PID: 26243 (nginx)
[root@control ansible]# ansible mysql -a 'systemctl status mariadb'
192.168.190.105 | CHANGED | rc=0 >>
 Main PID: 16321 (mysqld_safe)
[root@control ansible]# ansible php -a 'systemctl status php-fpm'
192.168.190.106 | CHANGED | rc=0 >>
 Main PID: 2772 (php-fpm)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/603656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AI绘画】Midjourney 工笔画 水蓝色衣服的少女

using Midjourney 提示词&#xff1a; highly detailed,细节刻画细腻,超高清晰度,32k,HD,大师作品,高质量,动漫少女,水墨人像,20岁年轻身材很好的中国少女,惊人的美貌,五官精致,精致的妆容,华丽的水蓝色衣服,古风服饰,华丽的珠宝,飞扬的黑色长发,大风吹起头发,宝石发光,黄金装饰…

如何给正弦信号添加12V直流偏置

一个有趣问题的探究&#xff1a; 运放在单电源的情况下只能输出正电压&#xff08;单方向的&#xff09;&#xff0c;这就使得有正负值的信号电压只能输出一半&#xff1a; 【单电源供电的运放如何增加直流偏置】&#xff08;电阻分压法&#xff09;&#xff1a; 单电源供电的…

某云eHR PtFjk.mob 任意文件上传漏洞复现

0x01 产品简介 某云eHR是大中型企业广泛采用人力资源管理系统。某云是国内顶尖的HR软件供应商,是新一代eHR系统的领导者。 0x02 漏洞概述 某云EHR系统PtFjk.mob接口处存在未授权文件上传漏洞,攻击者可上传webshell来命令执行,获取服务器权限。 0x03 复现环境 FOFA:bod…

算法-并查集

目录 什么是并查集 并查集基础 &#xff08;1&#xff09;原理 &#xff08;2&#xff09;初始化 &#xff08;3&#xff09;查询 &#xff08;4&#xff09;合并 &#xff08;5&#xff09;判断是否同一集合 并查集优化 路径压缩 启发式合并 并查集模板 模板 例题…

线下订单平台操作步揍

收款管理 1微信收款查询 1. 获取微信数据 获取微信数据。通过时间范围 查找微信数据调用第三方接口如下&#xff1a; Map map HttpPost.doPost("https://qyapi.weixin.qq.com/cgi-bin/externalpay/get_bill_list?access_token"ApiUtils.getWxtoken(),args); 其中…

如何缩小图片尺寸不改变清晰度?几个方法教你解决

在平时对图片进行处理的时候&#xff0c;最害怕的就是修改过的图片质量下降&#xff0c;导致清晰度不够&#xff0c;尤其是缩小图片尺寸的时候&#xff0c;所以今天小编就来告诉大家几个关于修改图片尺寸又不改变清晰度的方法。 修改图片大小是非常普遍的图片编辑需求&#xf…

【SpringMVC 】什么是SpringMVC(三)?基于springmvc的文件上传、基于springmvc的拦截器、基于springmvc的邮件发送

文章目录 SpringMVC第五章1、SpringMVC文件上传1、基本步骤1-2345-82、邮件发送1、基本步骤1-234-5567-8 简单邮件带附件的邮件第六章1、拦截器的使用使用步骤232、调度的使用基本步骤1-56-8调度规则3、shiro安全框架核心概念基本语法1、基于ini文件的认证**测视类**2、基于rea…

计算机组成原理网课笔记

无符号整数的表示与运算 带符号整数的表示与运算 原反补码的特性对比 移码

基于 docker-compose 部署 LNMP 架构

目录 前言 1、任务要求 2、Nginx 2.1 建立工作目录并上传相关安装包 2.2 编写 Nginx Dockerfile 脚本 2.3 准备 nginx.conf 配置文件 3、Mysql 3.1 建立工作目录并上传相关安装包 3.2 编写 Mysql Dockerfile 脚本 3.3 编写 my.cnf 配置文件 4、PHP 4.1 建立工作目录…

Spring MVC(一)

1 Spring MVC概述 我们在之前学习Servlet的时候&#xff0c;认识了在WEB开发中MVC设计模式&#xff0c;其最为经典的设计就是&#xff0c;通过控制器&#xff08;Controller&#xff09;分离模型&#xff08;Model&#xff09;和视图&#xff08;View&#xff09;。在具体的WEB…

提高谷歌抓取成功率:代理IP的7个使用误区

在当今数字化时代&#xff0c;数据采集和网络爬取已成为许多企业和个人必不可少的业务活动。对于爬取搜索引擎数据&#xff0c;特别是Google&#xff0c;使用代理IP是常见的手段。然而&#xff0c;使用代理抓取Google并不是一件轻松的事情&#xff0c;有许多常见的误区可能会导…

在IDEA中通过模块创建新项目的时候,出现无法连接的错误

1.找到IDEA中的设置 2.在设置搜索HTTP,选择自动检测代理设置 选择URL: 输入https://start.spring.io 3.点击应用&#xff0c;即可完成

面试算法-链表-反转链表(golang、c++)

目录 1、题目 2、解题思路 2.1 遍历、迭代 2.2 递归 3、源代码 3.1 c 3.2 golang 4、复杂度分析 4.1 遍历、迭代法 4.2 迭代法 1、题目 链表是一种常用的数据结构&#xff0c;链表的特点是插入、删除节点的效率非常高&#xff0c;因为他不需要移动其他任何元素&…

nginx--防盗链

盗链 通过在自己网站里面引用别人的资源链接,盗用人家的劳动和资源 referer referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息 正常的referer信息 none&#xff1a;请求报文首部没有referer首部&#xff0c;比如用户直接在浏览器输入域名访问web网站&…

使用 Cython 加密 Python 代码防止反编译

文章目录 前言使用 Cython 加密 Python 代码环境Python 源代码编写 Cython 编译配置文件 编译查看输出文件使用 问题error: Microsoft Visual C 14.0 or greater is requiredpyconfig.h(59): fatal error C1083: 无法打开包括文件: “io.h”: No such file or directorydynamic…

【已解决】‘pip‘ 不是内部或外部命令问题

&#x1f60e; 作者介绍&#xff1a;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff0c;视频号&#xff1a;AI-行者Sun &#x1f388; 本文专栏&#xff1a;本文收录于《AI实战中的各种bug…

大模型微调之 在亚马逊AWS上实战LlaMA案例(三)

大模型微调之 在亚马逊AWS上实战LlaMA案例&#xff08;三&#xff09; 使用 QLoRA 增强语言模型&#xff1a;Amazon SageMaker 上 LLaMA 2 的高效微调 语言模型在自然语言处理任务中发挥着关键作用&#xff0c;但训练和微调大型模型可能会占用大量内存且耗时。在本文中&…

Springboot整合飞书向群组/指定个人发送消息/飞书登录

Springboot整合飞书向群组发送消息 飞书开放平台创建企业自建应用 添加应用能力-机器人 创建完成后&#xff0c;进入应用详情页&#xff0c;可以在首页看到 App Id 和 App Secret 在飞书pc端创建一群机器人 此处可以拿到该机器人的webhook地址,通过https的方式,也可以调用发送…

为什么说RK3562可以碾压PX30?

在如今的科技市场中&#xff0c;处理器的性能直接决定了设备的运行速度和用户体验。今天&#xff0c;我们将对比瑞芯微旗下的两款处理器&#xff1a;PX30与RK3562。RK3562比PX30的性价比究竟高在哪里&#xff1f; PX30 瑞芯微PX30是一款高性能的四核应用处理器&#xff0c;专…