[Ansible系列⑤]Ansible-Playbook解析

一.    简介

         ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写。playbook命令根据自上而下的顺序依次执行。同时,playbook开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。

        playbook通过ansible-playbook命令使用,它的参数和ansible命令类似,如参数-k(–ask-pass) 和 -K (–ask-sudo) 来询问ssh密码和sudo密码,-u指定用户,这些指令也可以通过规定的单元写在playbook 。

        ansible-playbook的简单使用方法: ansible-playbook example-play.yml 。

 二.    Playbook 结构说明

         playbook是由一个或多个"play"组成的列表。play的主要功能就是对一组主机应用play中定义好的task。从根本上来讲一个task就是对ansible一个module的调用。而将多个play按照一定的顺序组织到一个playbook中,我们称之为编排。

playbook主要有以下四部分构成:

  • Target section: 用于定义将要执行playbook的远程主机组及远程主机组上的用户,还包括定义通过什么样的方式连接远程主机(默认ssh)
  • Variable section: 定义playbook运行时需要使用的变量
  • Task section: 定义将要在远程主机上执行的任务列表
  • Handler section: 定义task执行完成以后需要调用的任务

 2.1    Target  section

         playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
        playbook中的远程用户和ad-hoc中的使用没有区别,默认不定义,则直接使用ansible.cfg配置中的用户相关的配置。也可在playbook中定义如下:

- name: /etc/hosts is up to date
  hosts: datacenter
  remote_user: automation
  become: yes
  become_mothod: sudo
  become_user: root

  vars:  
  tasks:
  handler:


说明:工作中我们在playbook的target section部分,我们一般只定义hosts,来指定inventory中定义的主机或主机组。其他的参数都默认使用ansible.cfg中所定义的,即:


- name: /etc/hosts is up to date
  hosts: datacenter

  vars:  
  tasks:
  handler:

        playbook中的hosts即inentory中的定义主机与主机组,在《ansible inventory详解》中我们讲到了如何选择主机与主机组,在这里也完全适用。

 2.2    Task  section 

        playbook的主体部分是任务列表。任务列表中的各任务按次序逐个在hosts中指定的所有主机上执行,在所有主机上完成第一个任务后再开始第二个。在自上而下运行某playbook时,如果中途发生错误,则整个playbook会停止执行,由于playbook的幂等性,playbook可以被反复执行,所以即使发生了错误,在修复错误后,再执行一次即可。
        定义task可以使用action: module options或module: options的格式,推荐使用后者以实现向后兼容。

- hosts:webserver

  tasks:
    - name: make sure apache is running
      service: 
        name: httpd
        state: started
      
    - name: disable selinux
      command: /sbin/setenforce 0  

2.3    Handler  section

         在Ansible Playbook中,handler事实上也是个task,只不过这个task默认并不执行,只有在被触发时才执行。
        handler通过notify来监视某个或者某几个task,一旦task执行结果发生变化(注意:有的时候task有被执行,但是没有实质性的改变,执行结果为绿色,也是无法触发handler来执行的),则触发handler,执行相应操作。
        handler会在所有的play都执行完毕之后才会执行,这样可以避免当handler监视的多个task执行结果都发生了变化之后而导致handler的重复执行(handler只需要在最后执行一次即可)。
 

tasks:
  - name: start memcached
    service:
      name: memcached
      state: started
    notify: restart memcached

  - name: start apache
    service
      name: httpd
      state: started
    notify: restart apache

handlers:
  - name: restart memcached
    service:
      name: memcached
      state: restarted

  - name: restart apache
    service:
      name: httpd
      state: restarted

##在notify中定义内容一定要和handler中定义的 - name 内容一样,这样才能达到触发的效果,否则会不生效。

        默认情况下,在一个playbook中,只要有task执行失败,则playbook终止,即使是与handler关联的task在失败的task之前运行成功了,handler也不会被执行。如果希望在这种情况下handler仍然能够执行,则需要添加force_handlers参数,配置如下:

- hosts: all
  force_handlers: yes                    ##

  tasks:
    - name: a task which always notifies its handler
      command: /bin/true
      notify: restart the database
    - name: a task which fails because the package doesn't exist
      yum:
        name: notapkg
        state: latest
      
  handlers:
    - name: restart the database
      service:
        name: mariadb
        state: restarted

##如果与handler关联的task还未执行,在其前的task已经失败,整个play终止,则handler未被触发,也不会执行。

2.3.1    meta模块

         默认情况下,所有task执行完毕后,才会执行各个handler,并不是执行完某个task后,立即执行对应的handler,如果你想要在执行完某些task以后立即执行对应的handler,则需要使用meta模块,示例如下。

- hosts: web

  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: present
      notify:  httpd
    
    - name: install mariadb
      yum:
        name: mariadb
        state: present
      notify: mariadb
    
    - meta: flush_handlers                ##重点

    - name: install vim 
      yum:
        name: vim 
        state: present
  
  handlers:
    - name: httpd
      systemd:
        name: httpd
        state: started

    - name: mariadb
      systemd:
        name: mariadb
        state: started

        这个任务使用meta模块,meta任务是一种特殊的任务,meta任务可以影响ansible的内部运行方式,上例中,meta任务的参数值为flush_handlers,”meta: flush_handlers”表示立即执行之前的task所对应handler,**什么意思呢?意思就是,在当前meta任务之前,一共有两个任务,task1与task2,它们都有对应的handler,当执行完task1与task2以后,立即执行对应的handler,而不是像默认情况那样在所有任务都执行完毕以后才能执行各个handler。

[Ansible系列⑤]Ansible-Playbook解析_第1张图片

 这里执行虽然有报错,但是看执行步骤确实是在task1和task2执行之后,就接着执行了对应的handler。

 2.3.2    多个handler调用一个task

         我们还可以在一个task中一次性notify多个handler,怎样才能一次性notify多个handler呢?你可能会尝试将多个handler使用相同的name,但是这样并不可行,因为当多个handler的name相同时,只有一个handler会被执行,所以,我们并不能通过这种方式notify多个handler,如果想要一次notify多个handler,则需要借助另一个关键字,它就是’listen’,你可以把listen理解成”组名”,我们可以把多个handler分成”组”,当我们需要一次性notify多个handler时,只要将多个handler分为”一组”,使用相同的”组名”即可,当notify对应的值为”组名”时,”组”内的所有handler都会被notify,这样说可能还是不容易理解,我们来看个小示例,示例如下:

---
- hosts: web

  tasks:
  - name: task1
    file: path=/testdir/testfile
          state=touch
    notify: handler group1               ##

  handlers:
  - name: handler1
    listen: handler group1
    file: path=/testdir/ht1
          state=touch
  - name: handler2
    listen: handler group1                ##
    file: path=/testdir/ht2
          state=touch

2.4    vars  section

         定义playbook运行时需要使用的变量,在这里我们先简单说下ansible-playbook变量的种类:自定义变量(inventory中定义,playbook中定义,变量文件中定义等等),魔法变量.....等多种,后面我们将用单独的一篇文章来展开说ansible的变量。

三.    playbook 基础示例

 下面通过playbook管理一个httpd服务器来简单了解下playbook的应用:

1.  创建playbook
# cat manage_apache.yml
- name: play to setup web server
  hosts: all
  tasks:
    - name: latest httpd version installed
      yum:
        name: httpd
        state: latest
        
    - name: correct index.html is present
      copy: 
        src: files/index.html
        dest: /var/www/html/index.html
        
    - name: start httpd service
      service:
        name: httpd
        state: started
        enabled: true

2.   检查playbook的语法
ansible-playbook  manage_apache.yml  --syntax-check

#    执行playbook
ansible-playbook  manage_apache.yml

 

你可能感兴趣的:(运维,ansible系列,ansible,linux,服务器,运维,架构)