playbook

实施playbook

playbook-剧本 介绍

playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的

YAML语法

  1. YAML的语法和其他高阶语言类似并且可以简单表达清单、散列表、标量等数据结构。(列表用横杆表示,键值对用冒号分割,键值对里又可以嵌套另外的键值对)
  2. YAML文件扩展名通常为.yaml或者.yml。
  3. 一定要对齐,只能使用空格
  4. 处于层次结构中同一级别的数据元素(例如同一列表中的项目)必须具有相同的缩进量。
  5. 如果项目属于其他项目的子项,其缩进量必须大于父项

核心元素

  • hosts:主机清单

  • tasks:任务

  • vars:变量

  • handlers:特定条件触发的任务(例如启动一个服务,如果配置文件没有发生改变,则不重启)

  • template:包含了模板语法的文本文件

  • name:任务名称

  • notify:监控当前任务,如果修改后就触发对应的命令

临时写法

[root@localhost ansible]# ansible 172.16.100.42 -m user -a 'name=aaa uid=10101 state=present'

playbook写法

[root@localhost ansible]# vim playbook/user.yml   //这是用playbook写的一个剧本, 意思是创建用户
---
- name: abc
  hosts: 192.168.100.42   //受管主机执行的IP地址
  tasks:      //任务
    - name: create user aaa  //任务名,创建用户
      user:            //利用user模块
        name: aaa       //用户名
        uid: 10101       //指定id,也可以不指定,让其默认
        state: present   //状态
        
 [root@localhost ansible]# ansible-playbook playbook/user.yml    //运行

PLAY [abc] ************************************************************************

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

TASK [create user aaa] ************************************************************
changed: [192.168.100.42]

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

[root@localhost ansible]#

[root@localhost ~]# id aaa  //在受管主机上查看
uid=10101(aaa) gid=10101(aaa) 组=10101(aaa)

运行playbook

absible-playbook命令可用于运行playbook。该命令在控制节点上执行,要运行的playbook的名称则作为参数传递。

[root@localhost ansible]# ansible-playbook playbook/user.yml     //我们在执行的时候, 文件在哪里,我们就要去指定它的路径,然后进行执行

在运行playbook时,将生成输出来显示所执行的play和任务。输出中也会报告执行的每一项任务的结果。

[root@localhost ansible]# vim playbook/user.yml 

hosts: 192.168.100.42
tasks:

  - name: vsftpd
    yum:
      name: vsftpd
      state: latest

  - name: service vsftpd
    service:
      name: vsftpd
      state: started
      enabled: yes  
  - name: config vsftpd
    copy:         
      src: ansible-playbook/vsftpd.conf     
      dest: /etc/vsftpd/vsftpd.conf 

[root@localhost ansible]# ansible-playbook playbook/user.yml 

PLAY [192.168.100.42] *********************************************************************************************

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

TASK [vsftpd] ******************************************************************************************************
ok: [192.168.100.42]

TASK [service vsftpd] **********************************************************************************************
ok: [192.168.100.42]

TASK [config vsftpd] ***********************************************************************************************
changed: [192.168.100.42]

PLAY RECAP *********************************************************************************************************
192.168.100.42            : ok=4   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

请注意,在playbook运行时,屏幕中会显示每个play和任务的name键的值。(Gathering Facts任务是一项特别的任务,setup模块通常在play启动时自动运行这项任务。)对于含有多个play和任务的playbook,设置name属性后可以更加轻松地监控playbook执行的进展。

通常而言,Ansible Playbook中的任务是幂等的,而且能够安全地多次运行playbook。如果目标受管主机已处于正确的状态,则不应进行任何更改。如果再次运行这个playbook,所有任务都会以状态OK传递,且不报告任何更改。1.4 提高输出的详细程度

ansible-playbook命令提供的默认输出不提供详细的任务执行信息。ansible-playbook -v命令提供了额外的信息,总共有四个级别。

提高输出的详细程度

ansible-playbook命令提供的默认输出不提供详细的任务执行信息。

ansible-playbook -v命令提供了额外的信息,总共有四个级别。

通俗一点就是-v越多,显示的信息也就月详细,日常中我们一般只使用-v

配置Playbook执行的输出详细程序

选项 描述
-v 显示任务结果
-vv 任务结果和任务配置都会显示
-vvv 包含关于与受管主机连接的信息
-vvvv 增加了连接插件相关的额外详细程序选项,包括受管主机上用于执行脚本的用户以及所执行的脚本
[root@localhost ansible]# ansible-playbook -v  playbook/user.yml 
Using /etc/ansible/ansible.cfg as config file

PLAY [abc] ************************************************************************

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

TASK [create user bbb] ************************************************************
changed: [192.168.100.42]

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

执行空运

可以使用-C选项对playbook执行空运行。这会使Ansible报告在执行该playbook时将会发生什么更改,但不会对受管主机进行任何实际的更改。

下例演示了一个playbook的空运行,它包含单项任务,可确保在受管主机上安装了最新版本的httpd软件包。注意该空运行报告此任务会对受管主机产生的更改。

[root@localhost ansible]#  ansible-playbook -C playbook/user.yml 

PLAY [abc] ************************************************************************

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

TASK [create user aaa] ************************************************************
changed: [192.168.100.42]

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

[root@localhost ansible]# 

实施多个play

缩写多个play

Playbook是一个YAML文件,含有由一个或多个play组成的列表。记住一个play按顺序列出了要对清单中的选定主机执行的任务。因此,如果一个playbook中有多个play,每个play可以将其任务应用到单独的一组主机。

在编排可能涉及对不同主机执行不同任务的复杂部署时,这会大有帮助。我们可以这样进行编写:对一组主机运行一个play,完成后再对另一组主机运行另一个play。

缩写包含多个play的playbook非常简单。Playbook中的各个play编写为playbook中的*列表项。各个play是含有常用play关键字的列表项。

以下示例显示了含有两个play的简单playbook。第一个play针对172.16.100.142运行,第二个play则针对172.16.100.143运行。

- name: first play
  hosts: 172.16.100.42  
  tasks:
    - name: first task
      yum:
        name: httpd
        status: present

    - name: second task
      service:
        name: httpd
        enabled: true

- name: second play
  hosts: 172.16.100.43
  tasks:
    - name: first task
      service:
        name: mariadb
        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上下文内要用于特权升级的用户帐户。

[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False

示例

---
- name: aaa
  hosts: 192.168.100.42
  remote_user: a
  tasks:
    - name: test
      lineinfile:
        path: /etc/ansible/test
        line: 192.168.100.42 root
        state: present
[root@localhost ansible]# ansible-playbook test/test.yml 

PLAY [aaa] ***********************************************************************

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

TASK [test] **********************************************************************
changed: [192.168.100.42]

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

[root@localhost ansible]#

查找模块

对于每一个模块,Ansible官网提供了其功能摘要,以及关于如何通过模块的选项来调用各项具体功能的说明。文档还提供了实用的示例,演示各个模块的用法,以及任务中关键字的设置方法。

前面我们用到过ansible-doc -l命令。这将显示模块名称列表以及其功能的概要。

[root@localhost ansible]# ansible-doc -l
a10_server                                                    Manage A10 Netw...
a10_server_axapi3                                             Manage A10 Netw...
a10_service_group                                             Manage A10 Netw...
a10_virtual_server                                            Manage A10 Netw...
aci_aaa_user                                                  Manage AAA user...
aci_aaa_user_certificate                                      Manage AAA user...
aci_access_port_block_to_access_port                          Manage port blo...
aci_access_port_to_interface_policy_leaf_profile              Manage Fabric i...
aci_access_sub_port_block_to_access_port                      Manage sub port...
aci_aep                                                       Manage attachab...
aci_aep_to_domain                                             Bind AEPs to Ph...
aci_ap                                                        Manage top leve...
aci_bd                                                        Manage Bridge D...
。。。。。。

使用ansible-doc [module name]命令来显示模块的详细文档。与Ansible官网一样,该命令提供模块功能的概要、其不同选项的详细信息,以及示例。

[root@localhost ansible]# ansible-doc yum
> YUM    (/usr/lib/python3.6/site-packages/ansible/modules/packaging/os/yum.py)

        Installs, upgrade, downgrades, removes, and lists packages and
        groups with the `yum' package manager. This module only works
        on Python 2. If you require Python 3 support see the [dnf]
        module.

  * This module is maintained by The Ansible Core Team
  * note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):
。。。。。。

ansible-doc命令还提供-s选项,它会生成示例输出,可以充当如何在playbook在使用特定模块的示范。此输出可以作为起步模板,包含在实施该模块以执行任务的playbook中。输出中包含的注释,提醒管理员各个选项的用法。下例演示了yum模块的这种输出

[root@localhost ansible]# ansible-doc -s yum
- name: Manages packages with the `yum' package manager
  yum:
      allow_downgrade:       # Specify if the named package and version is
                               allowed to
                               downgrade a maybe
                               already installed
                               higher version of
                               that package. Note
                               that setting allow_
                               downgrade=True can
                               make this module
                               behave in a non-
                               idempotent way. The
                               task could end up
。。。。。。

playbook语法

YAML注释

​ 注释可以用于提高可读性。在YAML中,井号(#)右侧的所有内容都是注释。如果注释的左侧有内容,请在该编号符号的前面加一个空格。

---
- name: test
  hosts: 192.168.100.42        # This is a line of comments 
  tasks:
    - name: Add SELinux = disabled
      lineinfile:
         path: /etc/selinux/config 
         line: SELinux = disabled 

YAML字符串

YAML中的字符串通常不需要放在引号里,即使字符串中包含空格。字符串可以用双引号或单引号括起符

this is a string

'this is another string'

"this is yet another a string"

编写多行字符串有两种方式。可以使用管道符表示要保留字符串中的换行字符

---
- name: aaa
  hosts: 192.168.100.42
  remote_user: a
  tasks:
    - name: tesAdd SELinux = disabled
      lineinfile:
        path: /etc/selinux/config
        line: |
                 SELinux = permissive
                 SELinux = disabled
                 SELinux = enabled
                 
[root@localhost ansible]# ansible 192.168.220.8 -m shell -a 'cat /etc/selinux/config' 
# SELINUXTYPE= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

SELinux = permissive 
SELinux = disabled
SELinux = enabled

要编写多行字符串,还可以使用大于号字符来表示换行字符转换成空格并且行内的引导空白将被删除。这种方法通常用于将很长的字符串在空格字符处断行,使它们跨占多行来提高可读性。

---
- name: aaa
  hosts: 192.168.100.42
  remote_user: a
  tasks:
    - name: tesAdd SELinux = disabled
      lineinfile:
        path: /etc/selinux/config
        line: >
                 SELinux = permissive
                 SELinux = disabled
                 SELinux = enabled
                 
[root@localhost ansible]# ansible 192.168.220.8 -m shell -a 'cat /etc/selinux/config' 
# SELINUXTYPE= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

SELinux = permissive SELinux = disabled SELinux = enabled 

YAML字典

大多数情况下应避免内联块格式,因为其可读性较低。不过,至少有一种情形中会较常使用它。当playbook中包含角色列表时,较常使用这种语法,从而更加容易区分play中包含的角色和传递给角色的变量。

下面是一个简单的字典形式:

 name: svcrole
 svcservice: httpd
 svcport: 80

字典也可以使用以大括号括起的内联块格式编写

 {name: svcrole, svcservice: httpd, svcport: 80}

YAML列表

最简单的列表

text:

 -ttxx1

 -ttxx2

 -ttxx3

列表也有以中括号括起的内联格式

 tetx: [ttxx1,ttxx2,ttxx3]

过时得“键=值”palybook简写

某些playbook可能使用较旧的简写方法,通过将模块的键值对放在与模块名称相同的行上来定义任务。例如,你可能会看到这种语法:

tasks:
  - name: shorthand form
    service: name=httpd enabled=yes state=started

通常我们应该将这样的语法编写为

tasks:
  - name: normal form
    service:
      name: httpd
      enabled: yes
      state: started

通常我们应避免简写形式,而使用普通形式。普通形式的行数较多,但更容易操作。任务的关键字垂直堆叠,更容易区分。阅读play时,眼睛直接向一扫视,左右运动较少。而且,普通语法是原生的YAML。

你可能会在文档和他人提供的旧playbook中看到这种语法,而且这种语法仍然可以发挥作用。

上一篇:Ansible-playbook


下一篇:Ansible-Playbook实现Mysql读写分离