一、Playbook简介

Playbook 是由一个或多个play组成的列表,主要功能是将task定义好的角色归并为一组进行统一管理,也就是通过Ansible的模板将多个play组织在一个Playbook中运行。

二、playbook格式

playbook由YMAL语言编写。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl等。MAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。以下为playbook常用到的YMAL格式。

  • YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。就像这样- host。
  • 同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。
  • playbook中hosts,variables,roles,tasks等对象的表示方法都是键值中间以”:”分隔,”:”后面还要增加一个空格。
  • 剧本以.yml后缀

三、Playbook的核心元素

Playbook本身由以下各部分组成:
(1)Hosts:运行指定任务的目标主机;
(2)Tasks:任务,即调用模块完成的操作;
(3)Variables:变量;
(4)Templates:模板;
(5)Handles:处理器,当某条件满足时,触发执行的操作;
(6)Roles:角色

四、任务列表的元素介绍

Play的主体是任务列表。任务列表中的任务依照次序逐个在hosts中指定的所有主机上执行,如果发生错误会将所有已执行任务回滚。

1.模块、模块参数格式

task的任务是按照指定的参数去执行模块。

(1)action:moudle options

(2)moudle:options,其中后者可以实现向后兼容。

注意:在Ansible自带模块中,command模块和shell模块只需要一个列表定义即可,无需使用key=value格式。

2.Handles和tags的使用

Handlers用于当关注的资源发生变化时所采取的操作。使用tags让用户选择跳过没有变化的代码,只运行Playbook中发生变化的部分代码。

(1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;

(2) 任务可以通过“tags“打标签,通过 ansible-playbook命令 使用 --tags选项能实现仅运行指定的tasks。

示例:

vim /etc/ansible/nginx.yml

- hosts: nginx
  remote_user: root
  tasks:
    - name:yum install epel-release -y    #安装epel源
      yum: name=epel-release state=latest
    - name: yum install nginx -y  #安装nginx
      yum: name=nginx state=latest
    - name: copy nginx.conf   #拷贝配置文件
      copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
      notify:
        - reload     #会触发handlers中名字为reload的任务
      tags: 
        - reloadnginx
    - name: start nginx   #启动nginx服务
      service: name=nginx state=started
      tags: 
        - startnginx
  handlers:
    - name: reload  #重载配置
      service: name=nginx state=reloaded

执行:ansible-playbook nginx.yml 

[自动化] Ansible之使用Playbooks详解_第1张图片
[自动化] Ansible之使用Playbooks详解_第2张图片

修改配置文件内容之后执行时调用标签ansible-playbook nginx.yml --tags= "reloadnginx",就会跳过安装步骤直接重载配置文件并启动服务。
[自动化] Ansible之使用Playbooks详解_第3张图片
[自动化] Ansible之使用Playbooks详解_第4张图片

3.variables:变量

(1) facts:可直接调用

注意:可使用setup模块直接获取目标主机的facters

ansible xxx -m setup

[自动化] Ansible之使用Playbooks详解_第5张图片
(2) 用户自定义变量:

  • 通过命令行传递变量

    ansible-playbook xxx.yml -extra-vars "host-www user-mageedu"
  • 在playbook中定义变量的方法
    vars:
    - var1: value1
    - var2: value2

(3)通过roles传递变量

(4)Host Inventory(主机清单)

- 主机变量

示例

[webservers] 
www1.accp.com  http_port=80    #添加主机变量http_port
www2.accp.com  http_port=8080

- 组变量

示例

[servers-vars]
ntp_server=ntp.example.org  #指定主机变量
nfs_server=nfs.example.org

- 组嵌套

示例

[apache]
httpd1.example.org
httpd2.example.org

[nginx]
ngx1.example.org
ngx2.example.org

[webservers:children]
apache
nginx

示例:使用变量package来代替软件包,变量service来代替服务名。

- hosts: nginx
  remote_user: root
  vars:
    - package: vsftpd
    - service: vsftpd
  tasks:
    - name: install httpd package
      yum: name={{package}} state=latest   ##安装最新版本的httpd
    - name: start httpd server
      service: name={{service}} enabled=true state=started     ##开启服务

[自动化] Ansible之使用Playbooks详解_第6张图片

4.Templates:模板文件以.j2后缀

Jinja是基于 Python的模板引擎。 Template类是 Jinja的另一个重要组件,可以看
作是一个编译过的模板文件,用来产生目标文本,传递 Python的变量给模板去替换模
板中的标记。

示例

从被管理端复制一份httpd.conf到管理端/opt/template
并做如下修改
mkdir /opt/template
cp /opt/template/httpd.conf  /opt/httpd.conf.j2
vim /opt/httpd.conf.j2      

 Listen {{http_port}}
 ServerName {{server_name}}

vim /etc/ansible/hosts
[httpd]
192.168.100.144 http_port=192.168.100.144:808 server_name=www.yun.com:808
# 在hosts文件为主机配置变量

vim httpd.yml

- hosts: httpd
  remote_user: root
  vars:
    - package: httpd
    - service: httpd
  tasks:
    - name: install httpd package
      yum: name={{package}} state=latest   #安装最新版本的httpd
    - name: install configure file
      template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf  #使用模板并根据变量进行配置
      notify:
        - restart httpd   #调用handler
    - name: start httpd server
      service: name={{service}} enabled=true state=started     #开启服务
  handlers:
    - name: restart httpd
      service: name={{service}} state=restarted

[自动化] Ansible之使用Playbooks详解_第7张图片
[自动化] Ansible之使用Playbooks详解_第8张图片

5.循环:迭代,即需要重复执行的任务。

(1) when 语句:只需要在task之后添加when语句即可。

示例:

vim /etc/ansible/when.yml

- hosts: nginx
  remote_user: root
  vars:
    - username: user10
  tasks:
    - name: create {{username}} user
      user: name={{username}}
      when: ansible_fqdn=="promote.cache-dns.local"
执行:ansible-playbook when.yml 就会创建在nginx组的主机上。

[自动化] Ansible之使用Playbooks详解_第9张图片
(2)迭代:直接将需要迭代的内容定义为item变量并进行引用,然后通过with_items语句来指明迭代的元素。

示例:

vim /etc/ansible/items.yml

- hosts: nginx
  remote_user: root
  tasks:
    - name: install packages  #安装with_items中列出的包
      yum: name={{ item }} state=latest
      with_items:
        - php
        - php-mysql

执行:ansible-playbook items.yml 就会安装列表中的包

[自动化] Ansible之使用Playbooks详解_第10张图片
示例:

vim adduser.yml

- hosts: httpd
  remote_user: root
  tasks:
    - name: add some groups         #添加一些组
      group: name={{ item }} state=present
      with_items:
         - group1
         - group2
         - group3
    - name: add some user       #创建用户到对应的组
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'user1', group: 'group1' }
        - { name: 'user2', group: 'group2' }
        - { name: 'user3', group: 'group3' }

 执行:ansible-playbook adduser.yml 就会创建对应的用户及组

[自动化] Ansible之使用Playbooks详解_第11张图片
[自动化] Ansible之使用Playbooks详解_第12张图片

6.角色列表: Roles

Ansible为了层次化、结构化地组织 Playbook,使用了角色( roles),可以根据层
次结构自动装载变量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include
指令即可使用 roles。简单来讲, roles就是通过分别将变量、文件、任务、模块及处理
器设置于单独的目录中,便捷地使用他们。

创建roles时的注意事项:

(1)目录名同角色名的定义

(2)目录结构有固定的格式:

  • files:用来存放由copy模块或script模块调用的文件。
  • templates:用来存放jinjia2模板。
  • tasks:至少有一个main.yml文件,定义各tasks。
  • handlers:有一个main.yml文件,定义各handlers。
  • vars:有一个main.yml文件,定义变量。
  • default:有一个main.yml文件,定义默认变量。
  • meta:有一个main.yml文件,定义此角色的特殊设定及其依赖关系。

注意:在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、default和vars目录,用不到的目录可以创建为空目录,但不可以不创建。

示例:定制三个角色:httpd、mysql、php

(1)在roles目录下生成对应的目录结构

mkdir -pv /etc/ansible/roles/{httpd,mysql,php}/{files,templates,vars,tasks,handlers,meta,default}

[自动化] Ansible之使用Playbooks详解_第13张图片

(2)在每个角色的handlers、tasks、meta、default、vars目录下创建main.yml文件,千万不能自定义。

touch /etc/ansible/roles/{httpd,mysql,php}/{default,vars,tasks,meta,handlers}/main.yml

(3)定义每个角色中tasks/main.yml的配置文件。

------编写httpd模块------

vim /etc/ansible/roles/httpd/tasks/main.yml   
- name: ensure apache is at the latest version 
  yum: name={{item}} state=latest
  with_items:
    - httpd
    - httpd-devel
- name: conf
  template: src=/etc/ansible/roles/httpd/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  tags: 
    - httpdconf
  notify: 
    - new conf to reload
  tags:
    - reload
- name: start service
  service: name=httpd enabled=true state=started
-------编写mysql模块-------

vim /etc/ansible/roles/mysql/tasks/main.yml
- name: ensure mysql is at the latest version 
  yum: name={{item}} state=latest
  with_items:
    - mariadb
    - mariadb-server
    - mariadb-libs
    - mariadb-devel
- name: start service
  service: name=mariadb enabled=true state=started

-------编写php模块-----

vim /etc/ansible/roles/php/tasks/main.yml
- name: ensure php is at the latest version
  yum: name={{item}} state=latest
  with_items:
    - php
    - php-mysql
    - php-gd
    - php-ldap
    - php-odbc
    - php-pear
    - php-xml
    - php-xmlrpc
    - php-mbstring
    - php-snmp
    - php-soap
    - curl
    - curl-devel 
    - php-bcmath

(4)修改变量文件vars/main.yml

vim /etc/ansible/roles/httpd/vars/main.yml
    http_port : 80    #添加变量
    server_name : www.yun.com:80

(5)定义handlers文件handlers/main.yml

vim /etc/ansible/roles/httpd/handlers/main.yml

- name: new conf to reload
  service: name=httpd state=reloaded

(6)定义/etc/ansible/lamp.yml的playbook文件

-----编写roles示例-----
vi /etc/ansible/lamp.yml

- hosts: lamp
  remote_user: root
  roles:
    - httpd
    - mysql
    - php

(7)执行lamp.yml的playbook文件

ansible-playbook lamp.yml

[自动化] Ansible之使用Playbooks详解_第14张图片
(8)前往部署lamp的主机上编写php测试页,打开浏览器看网页是否正常。

vim /var/www/html/index.php
    

打开浏览器输入http://192.168.100.145/index.php
[自动化] Ansible之使用Playbooks详解_第15张图片
综上步骤,lamp架构部署成功。