前面已经介绍过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中的部分代码。
注意:
gather_facts
是一个play级别的指令设置,是负责收集目标主机信息的任务,由setup
模块提供。默认情况下,每个play都会先执行这个特殊的任务,收集完信息之后才开始执行其它任务。但是,收集目标主机信息的效率很低,如果能够确保playbook中不会使用到所收集的信息,可以显式指定gather_facts: no
来禁止这个默认执行的收集任务。- 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