Ansible-playbook 应用梳理

前面已经介绍过Ansible的安装配置及常见模块的使用 --《Linux下使用Ansible处理批量操作

Palybook简介

palybook是由一个或多个paly组成的列表,play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓 task 无非是调用 ansible 的一个 module。将多个play组织在一个 playbook 中,即可以让它们联同起来按事先编排好的机制同唱一台大戏。

一个playbook由以下几个部分组成

  • hosts:运行执行任务(task)的目标主机。
  • remote_user:在远程主机上执行任务的用户。
  • tasks:任务集。
  • varniables: 内置变量或自定义变量在playbook中调用,变量替换{{ variable_name }}。
  • templates:模板,即使用模板语法的文件,比如配置文件等,使用jinja2语法。
  • handlers:和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行。
  • tags:标签,指定某条任务执行,用于选择运行playbook中的部分代码。

注意:

  1. gather_facts是一个play级别的指令设置,是负责收集目标主机信息的任务,由setup模块提供。默认情况下,每个play都会先执行这个特殊的任务,收集完信息之后才开始执行其它任务。但是,收集目标主机信息的效率很低,如果能够确保playbook中不会使用到所收集的信息,可以显式指定gather_facts: no来禁止这个默认执行的收集任务。
  2. handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。

为什么引入Playbook?

  • playBook功能比ad-hoc更全,是对ad-hoc的一种编排。
  • playBook能很好的控制先后执行顺序,以及依赖关系。
  • playBook语法展现更加的直观。
  • playbook可以持久使用,ad-hoc无法持久使用。

YAML的基本语法规则

  • playbook文件扩展名可以是yaml,也可以是yml。使用"#"号表示注释至行尾。
  • 在playbook文件中,可以连续三个减号(---)区分多个play。还有选择性的连续三个点(...)用来表示play的结尾,也可省略。
  • 第二行开始正常写playbook的内容,一般都会写上描述该playbook的功能。建议尽量为每个play和每个task都命名,且名称具有唯一性。
  • 只允许使用空格,缩进的级别必须是一致的,同样的缩进代表同样的级别,不能用Tab键缩进;程序判别配置的级别是通过缩进结合换行实现的。
  • YAML文件内容是区分大小写的,key/value的值均需大小写敏感。多个key/value可同行写也可换行写。同行使用分号(😃 分隔,换行写需要以减号(-)分隔。

YAML支持以下常用几种数据类型

  • 标量:单个的、不可再分的值 ;不可在分的量。包括字符串,布尔值,整数,浮点数,Null,时间,日期。key对应value
  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)

三种常见的数据格式

  • XML:Extensible Markup Language,可扩展标记语言,可用于数据交换和配置。
  • JSON:JavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注释。
  • YAML:YAML Ain't Markup Language YAML 不是一种标记语言, 主要用来配置,大小写敏感,不支持tab。

Playbook命令及用法

ansible-playbook  <filename.yml> ... [options]

ansible-playbook官方命令选项:https://docs.ansible.com/ansible/2.9/cli/ansible-playbook.html

[root@AnsibleControl ~]# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]

[root@AnsibleControl ~]# ansible-playbook --h
optional arguments:
  --ask-vault-pass      ask for vault password
  #加密playbook文件时提示输入密码
  --flush-cache         clear the fact cache for every host in inventory
  #清除清单中每个主机的缓存  
  --force-handlers      run handlers even if a task fails
  #强制运行handlers的任务,即使任务失败也运行处理程序  
  --list-hosts          outputs a list of matching hosts; does not execute anything else
  #输出匹配主机列表;不执行任何其他操作
  --list-tags           list all available tags
  #列出所有可用的标签
  --list-tasks          list all tasks that would be executed  
  #列出所有将要执行的任务
  --skip-tags SKIP_TAGS  only run plays and tasks whose tags do not match these values  
  #跳过指定的tags任务
  --start-at-task START_AT_TASK  start the playbook at the task matching this name  
  #在匹配此名称的任务处开始运行剧本
  --step                one-step-at-a-time: confirm each task before running  
  #在运行前确认每个任务,逐个执行
  --syntax-check        perform a syntax check on the playbook, but do not execute it  
  #对playbook执行语法检查,并不实际执行
  --vault-id VAULT_IDS  the vault identity to use  
  #使用的密码标识
  --vault-password-file VAULT_PASSWORD_FILES vault password file  
  #密码文件
  --version             show program's version number, config file location,configured module search path, module location,executable location and exit  
  #显示程序的版本号、配置文件位置、配置的模块搜索路径、模块位置、可执行文件位置和退出
  -C, --check           don't make any changes; instead, try to predict some of the changes that may occur  
  #不做任何改变,不会真正在机器上执行(查看执行会产生什么变化),只是测试
  -D, --diff            when changing (small) files and templates, show the differences in those files; works great with --check  
  #更改(小)文件和模板时,显示这些文件中的差异;与-C配合使用效果更好
  -M MODULE_PATH, --module-path MODULE_PATH
                        prepend colon-separated path(s) to module library (def
                        ault=~/.ansible/plugins/modules:/usr/share/ansible/plu
                        gins/modules)  
  #将冒号分隔的路径添加到模块库
  -e EXTRA_VARS, --extra-vars EXTRA_VARS set additional variables as key=value or YAML/JSON, if filename prepend with @  
  #在Playbook中引入外部参数变量
  -f FORKS, --forks FORKS  specify number of parallel processes to use (default=5)  
  #指定要使用的并行进程数(默认值=5)FORKS被指定为一个整数
  -h, --help            show this help message and exit
  -i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated  
  #指定清单主机路径或逗号分隔的主机列表,代替--inventory-file
  -l SUBSET, --limit SUBSET  further limit selected hosts to an additional pattern  
  #限制选定的主机
  -t TAGS, --tags TAGS  only run plays and tasks tagged with these values  
  #只运行带有tags标记的任务
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                        connection debugging)

Connection Options:
  control as whom and how to connect to hosts

  --private-key PRIVATE_KEY_FILE, --key-file PRIVATE_KEY_FILE  use this file to authenticate the connection
  #使用此文件来验证连接
  --scp-extra-args SCP_EXTRA_ARGS  specify extra arguments to pass to scp only (e.g. -l)
  #指定仅传递给scp的额外参数
  --sftp-extra-args SFTP_EXTRA_ARGS  specify extra arguments to pass to sftp only (e.g. -f,-l)
  #指定仅传递给sftp的额外参数
  --ssh-common-args SSH_COMMON_ARGS  specify common arguments to pass to sftp/scp/ssh (e.g.ProxyCommand)
  #指定要传递给 sftp/scp/ssh 的常用参数
  --ssh-extra-args SSH_EXTRA_ARGS  specify extra arguments to pass to ssh only (e.g. -R)
  #指定仅传递给 ssh 的额外参数
  -T TIMEOUT, --timeout TIMEOUT override the connection timeout in seconds (default=10)
  #SSH连接超时时间设定,默认10s
  -c CONNECTION, --connection CONNECTION connection type to use (default=smart)
  #指定连接方式
  -k, --ask-pass        ask for connection password
  -u REMOTE_USER, --user REMOTE_USER connect as this user (default=None)
  #指定远程主机以什么用户身份运行命令

Privilege Escalation Options:
  control how and which user you become as on target hosts

  --become-method BECOME_METHOD  privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices.
  #要使用的权限提升方法 (default=%(default)s),使用ansible-doc -t become -l列出有效选项。
  --become-user BECOME_USER  run operations as this user (default=root)
  #以该用户身份运行操作(默认=root)
  -K, --ask-become-pass  ask for privilege escalation password
  #要求输入提权密码
  -b, --become          run operations with become (does not imply password prompting)
  #使用指定用户运行操作(不暗示密码提示)

在inventory中定义主机及主机组, 默认/etc/ansible/hosts文件中

[root@AnsibleControl ansible]# pwd
/etc/ansible
[root@AnsibleControl ansible]# tail -11 hosts
[ansible]
ansible-01 ansible_host=172.16.70.181 
ansible-02 ansible_host=172.16.70.182
AnsibleControl ansible_ssh_host=172.16.70.37

[webservers]
ansible-01    ansible_host=172.16.70.181
ansible-02    ansible_host=172.16.70.182

[control]
AnsibleControl    ansible_ssh_host=172.16.70.37

示例:服务器初始化 init.yaml

[root@AnsibleControl ansible]# cat init.yaml
---
- name: Set Hostname    #PLAY名称
  hosts: webservers     #在inventory中定义主机及主机组,等其他组合
  gather_facts: false    #禁止执行默认setup模块,不收集目标主机信息
  vars:            #设置变量,可在play级别,也可在task级别
    hostnames:
      - host: 172.16.70.181
        name: ansible-01
      - host: 172.16.70.182
        name: ansible-01
  tasks: 
    - name: set hostname  #TASK名称
      hostname: 
        name: "{{ item.name }}"
      when: item.host == inventory_hostname
      loop: "{{ hostnames }}"

- name: Disable Selinux
  hosts: all
  gather_facts: false
  tasks: 
    - block: 
        - name: disable on the fly
          shell: setenforce 0
        
        - name: disable forever in config
          lineinfile: 
            path: /etc/selinux/config
            line: "SELINUX=disabled"
            regexp: '^SELINUX='
      ignore_errors: true

- name: Modify sshd_config
  hosts: webservers
  gather_facts: false
  tasks:
    - name: backup sshd config
      shell: 
        /usr/bin/cp -f {{path}} {{path}}.bak
      vars: 
        - path: /etc/ssh/sshd_config

    - name: disable root login
      lineinfile: 
        path: "/etc/ssh/sshd_config"
        line: "PermitRootLogin no"
        insertafter: "^#PermitRootLogin"
        regexp: "^PermitRootLogin"
      notify: "restart sshd"

    - name: disable password auth
      lineinfile: 
        path: "/etc/ssh/sshd_config"
        line: "PasswordAuthentication no"
        regexp: "^PasswordAuthentication yes"
      notify: "restart sshd"

  handlers: 
    - name: "restart sshd"
      service: 
        name: sshd
        state: restarted