Ansible之Playbook常用详解
Playbook
playbook-剧本 介绍
playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的
YAML语法
- YAML的语法和其他高阶语言类似并且可以简单表达清单、散列表、标量等数据结构。(列表用横杆表示,键值对用冒号分割,键值对里又可以嵌套另外的键值对)
- YAML文件扩展名通常为.yaml或者.yml。
- 一定要对齐,只能使用空格
- 处于层次结构中同一级别的数据元素(例如同一列表中的项目)必须具有相同的缩进量。
- 如果项目属于其他项目的子项,其缩进量必须大于父项
Ansible Playbook的格式化
[root@master opt]# ansible mysql -m user -a 'name=aaa uid=6000 state=present'
[root@master lamp]# vi /opt/lamp/user.yml //这是用playbook写的一个剧本, 意思是创建用户
---
- name: abc
hosts: mysql //受管主机执行的IP地址
tasks: //任务
- name: create user aaa //任务名,创建用户
user: //利用user模块
name: aaa //用户名
uid: 6000 //指定id,也可以不指定,让其默认
state: present //状态
[root@master lamp]# ansible-playbook /opt/lamp/user.yml
PLAY [abc] ***********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.129.135]
TASK [create abc for aaa] ********************************************************************************************
ok: [192.168.129.135]
PLAY RECAP ***********************************************************************************************************
192.168.129.135 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@mysql ~]# id aaa //在受管主机上查看
uid=6000(aaa) gid=6000(aaa) 组=6000(aaa)
运行playbook
absible-playbook命令可用于运行playbook。该命令在控制节点上执行,要运行的playbook的名称则作为参数传递。
[root@master lamp]# ansible-playbook /opt/lamp/user.yml //我们在执行的时候, 文件在哪里,我们就要去指定它的路径,然后进行执行
在运行playbook时,将生成输出来显示所执行的play和任务。输出中也会报告执行的每一项任务的结果。
[root@master lamp]# cat vsftpd.yml
---
- name: vsftpd
hosts: mysql
tasks:
- name: vsftpd
yum:
name: vsftpd
state: latest
- name: service vsftpd
service:
name: vsftpd
state: started
enabled: yes
[root@master lamp]# ansible-playbook /opt/lamp/vsftpd.yml
PLAY [vsftpd] ********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.129.135]
TASK [vsftpd] ********************************************************************************************************
changed: [192.168.129.135]
TASK [service vsftpd] ************************************************************************************************
changed: [192.168.129.135]
PLAY RECAP ***********************************************************************************************************
192.168.129.135 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0
[root@mysql ~]# rpm -qa | grep vsftpd
vsftpd-3.0.3-33.el8.x86_64
[root@mysql ~]# systemctl status vsftpd //查看发现受管主机安装了vsftpd,并且已经设置开机自启
● vsftpd.service - Vsftpd ftp daemon
Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2021-07-20 23:14:21 CST; 2min 19s ago
Process: 809969 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
Main PID: 809970 (vsftpd)
Tasks: 1 (limit: 11159)
-
在playbook运行时,屏幕中会显示每个play和任务的name键的值。(Gathering Facts任务是一项特别的任务,setup模块通常在play启动时自动运行这项任务。)对于含有多个play和任务的playbook,设置name属性后可以更加轻松地监控playbook执行的进展。
-
通常而言,Ansible Playbook中的任务是幂等的,而且能够安全地多次运行playbook。如果目标受管主机已处于正确的状态,则不应进行任何更改。如果再次运行这个playbook,所有任务都会以状态OK传递,且不报告任何更改。
提升输出的详细程度
-
ansible-playbook命令提供的默认输出不提供详细的任务执行信息。
-
ansible-playbook -v命令提供了额外的信息,总共有四个级别。
-
通俗一点就是-v越多,显示的信息也就月详细,日常中我们一般只使用-v
选项 | 描述 |
---|---|
-v | 显示任务结果 |
-vv | 任务结果和任务配置都会显示 |
-vvv | 包含关于与受管主机连接的信息 |
-vvvv | 增加了连接插件相关的额外详细程序选项,包括受管主机上用于执行脚本的用户以及所执行的脚本 |
[root@master lamp]# ansible-playbook /opt/lamp/vsftpd.yml -v
PLAY [vsftpd] ********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.129.135]
TASK [vsftpd] ********************************************************************************************************
ok: [192.168.129.135] => {"changed": false, "msg": "Nothing to do", "rc": 0, "results": []}
TASK [service vsftpd] ************************************************************************************************
ok: [192.168.129.135] => {"changed": false, "enabled": true, "name": "vsftpd", "state": "started", "status": {"ActiveEnterTimestamp": "Tue 2021-07-20 23:14:21 CST", "ActiveEnterTimestampMonotonic": "21010225500", "ActiveExitTimestampMon
PLAY RECAP ***********************************************************************************************************
192.168.129.135 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
语法验证
- 在执行playbook之前,最好要进行验证,确保其内容的语法正确无误。ansible-playbook命令提供了一个–syntax-check选项,可用于验证playbook的语法。
下例演示了一个playbook成功通过语法验证:
[root@master lamp]# ansible-playbook --syntax-check vsftpd.yml
playbook: vsftpd.yml
- 语法验证失败时,将报告语法错误。输出中包含语法问题在playbook中的大致位置。
[root@master lamp]# ansible-playbook --syntax-check vsftpd.yml
ERROR! conflicting action statements: yum, service
The error appears to be in '/opt/lamp/vsftpd.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: vsftpd
^ here
执行空运下
- 可以使用-C选项对playbook执行空运行。这会使Ansible报告在执行该playbook时将会发生什么更改,但不会对受管主机进行任何实际的更改。
下例演示了一个playbook的空运行,它包含单项任务,可确保在受管主机上安装了最新版本的httpd软件包。注意该空运行报告此任务会对受管主机产生的更改
[root@master lamp]# ansible-playbook -C /opt/lamp/vsftpd.yml
PLAY [vsftpd] ********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.129.135]
ASK [vsftpd] ********************************************************************************************************
ok: [192.168.129.135]
TASK [service vsftpd] ************************************************************************************************
ok: [192.168.129.135]
PLAY RECAP ***********************************************************************************************************
192.168.129.135 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
实施多个play
-
Playbook是一个YAML文件,含有由一个或多个play组成的列表。记住一个play按顺序列出了要对清单中的选定主机执行的任务。因此,如果一个playbook中有多个play,每个play可以将其任务应用到单独的一组主机。
-
在编排可能涉及对不同主机执行不同任务的复杂部署时,这会大有帮助。我们可以这样进行编写:对一组主机运行一个play,完成后再对另一组主机运行另一个play。
-
缩写包含多个play的playbook非常简单。Playbook中的各个play编写为playbook中的顶级列表项。各个play是含有常用play关键字的列表项。
以下示例显示了含有两个play的简单playbook。第一个play针对httpd运行,第二个play则针对mariadb运行。
[root@master lamp]# cat play.yml
---
# This is a simple playbook with two play
- name: first play
hosts: httpd
tasks:
- name: first task
yum:
name: vsftpd
status: present
- name: second task
service:
name: vsftpd
enables: true
- name: second play
hosts: mysql
tasks:
- name: first task
service:
name: httpd
enabled: true
play中的远程用户和特权升级
- Play可以将不同的远程用户或特权升级设置用于play,取代配置文件中指定的默认设置。这些在play本身中与hosts或tasks关键字相同的级别上设置。
用户属性
- playbook中的任务通常通过与受管主机的网络连接来执行。与临时命令相同,用于任务执行的用户帐户取决于Ansible配置文件/etc/ansible/ansible.cfg中的不同关键字。运行任务的用户可以通过remote_user关键字来定义。不过,如果启用了特权升级,become_user等其他关键字也会发生作用。
如果用于任务执行的Ansible配置中定义的远程用户不合适,可以通过在play中使用remote_user关键字覆盖。
remote_user: 用户名
特权升级属性
-
Ansible也提供额外的关键字,从而在playbook内定义特权升级参数。become布尔值关键字可用于启用或禁用特权升级,无论它在Ansible配置文件中的定义为何。它可取yes或true值来启用特权升级,或者取no或false值来禁用它。
-
如果启用了特权升级,则可以使用become_method关键字来定义特定play期间要使用的特权升级方法。
-
此外,启用了特权升级时,become_user关键字可定义特定play上下文内要用于特权升级的用户帐户。
以下示例演示了如何在play中使用这些关键字:
//echo一个密码
[root@mysql ~]# id aaa
uid=6000(aaa) gid=6000(aaa) 组=6000(aaa)
[root@mysql ~]# echo "1" | passwd --stdin aaa
更改用户 aaa 的密码 。
passwd:所有的身份验证令牌已经成功更新。
//传输秘钥
[root@master ~]# ssh-copy-id aaa@192.168.129.135 //ansible主机上操作,把秘钥给135主机(mysql)
[root@mysql ~]# visudo //mysql主机
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
aaa ALL=(ALL) NOPASSWD: ALL
//编写任务文件
[root@master lamp]# ansible-playbook /opt/lamp/aaa.yml
PLAY [mysql] *********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.129.135]
TASK [create user aaa] ***********************************************************************************************
ok: [192.168.129.135]
PLAY RECAP ***********************************************************************************************************
192.168.129.135 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
模块文档
使用ansible-doc [module name]命令来显示模块的详细文档
ansible-doc service //显示service模块的帮助文档
[root@master ~]# ansible-doc service
> SERVICE (/usr/lib/python3.6/site-packages/ansible/modules/system/service.py)
OPTIONS (= is mandatory):
- arguments
Additional arguments provided on the command line.
(Aliases: args)[Default: (null)]
type: str
- enabled
Whether the service should start on boot.
*At least one of state and enabled are required.*
[Default: (null)]
type: bool
= name
Name of the service.
type: str
……略
语法变化
语法 | 作用 |
---|---|
YAML注释 | 用于提高可读性,在YAML中,编号或井号字符(#)右侧的所有内容都是注释; 如果注释的左侧有内容,请在该编号符号的前面加一个空格 |
YAML字符串 | YAML中的字符串通常不需要放在引号里,即使字符串中包含空格。字符串可以用双引号或单引号括起; 编写多行字符串有两种方式。可以使用管道符表示要保留字符串中的换行字符; 要编写多行字符串,还可以使用大于号字符来表示换行字符转换成空格并且行内的引导空白将被删除。 这种方法通常用于将很长的字符串在空格字符处断行,使它们跨占多行来提高可读性 |
YAML字典 | 字典也可以使用以大括号括起的内联块格式编写; 大多数情况下应避免内联块格式,因为其可读性较低。 有一种情形中会较常使用它。 当playbook中包含角色列表时,较常使用这种语法, 从而更加容易区分play中包含的角色和传递给角色的变量 |
YAML列表 | 列表也有以中括号括起的内联格式;我们应该避免使用此语法,因为它通常更难阅读 |
特殊用法
YAML注释
注释也可以用于提高可读性。在YAML中,编号或井号字符(#)右侧的所有内容都是注释。如果注释的左侧有内容,请在该编号符号的前面加一个空格。
#This is a YAML comment
[defaults] # This is also a YAML comment
# some basic default values...
YAML字符串
YAML中的字符串通常不需要放在引号里,即使字符串中包含空格。字符串可以用双引号或单引号括起。
This is a string
'This is another string'
"This is yet another a string"
编写多行字符串有两种方式。可以使用管道符表示要保留字符串中的换行字符。
line: |
AddType application x-httpd-php .php
AddType application x-httpd-php-source .phps
要编写多行字符串,还可以使用大于号字符来表示换行字符转换成空格并且行内的引导空白将被删除。这种方法通常用于将很长的字符串在空格字符处断行,使它们跨占多行来提高可读性。
line: >
AddType application x-httpd-php .php,
AddType application x-httpd-php-source .phps
查看:AddType application x-httpd-php .php,AddType application x-httpd-php-source .phps
YAML字典
简单的字典形式:
name: svcrole
svcservice: httpd
svcport: 80
字典也可以使用以大括号括起的内联块格式编写:
{name: svcrole, svcservice: httpd, svcport: 80}
大多数情况下应避免内联块格式,因为其可读性较低。不过,至少有一种情形中会较常使用它。当playbook中包含角色列表时,较常使用这种语法,从而更加容易区分play中包含的角色和传递给角色的变量。
YAML列表
最简单的列表如下:
hosts:
- servera
- serverb
- serverc
列表也有以中括号括起的内联格式,如下所示:
hosts: [servera, serverb, serverc]