ansible--playbook
playbook语法
playbook使用YAML语法描述配置文件,总的来说具有以下特性:
- 需要以“---”开始,且需顶行手写
- 此行开始正常些playbook的内容
- 使用 # 号注释代码
- 缩进必须是统一的,不能讲空格和Tab混用。
- 缩进的级别必须是一致的。
- 大小写敏感。
- key/value值可同行写也可以换行写,同行使用
:
,换行需要以-分隔
- 一个name只能包括一个task。
playbook小技巧
限定执行范围
--limit
可以使用该关键字限定一台或多台主机
ansible-playbook playbook.yml --limit local
--list-hosts
如果想知道在执行playbook时哪些主机受到影响,可以使用该关键字
用户与权限设置
--remote-user
指定用户
--ask-sudo-pass
传递sudo密码到远程主机
--sudo
强制play使用sudo用户
ansible-playbook playbook.yml --sudo --sudo-user=docker --ask-sudo-pass
Handlers
Handlers类似于编程语言中的钩子函数,可以在某一task执行完毕后,使用notify关键字进行调用。
Handlers的使用
Handlers的基本使用
Handlers应定义在任务之前,使用notify关键字进行调用后,会自动读取名称相同的Handlers。
handlers:
- name: restart apache
service: name=apache2 state=restarted
tasks:
- name: 开启apache rewrite模块
apache2_module: name=rewrite state=present
notify: restart apache
调用多个
notify:
- restart apache
- restart memcached
嵌套调用
handlers:
- name: restart apache
service: name=apache2 state=restarted
notify: restart memcached
Handlers的一些注意事项
- Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务重定义了
notify
调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。 - Handlers只会在
Play
的末尾运行一次;如果想在一个Playbook的中间运行Handlers,则需要使用meta模块来实现,例如:- meta: flush_handlers
- 如果一个Play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用mega模块的--force-handlers选项来强制执行Handlers,即使是Handlers所在的Play中途运行失败也能运行。
变量
Playbook变量
在Playbook中,最常见的定义变量的方法是使用vars代码块。
---
- hosts: local
vars:
key: value
tasks:
- debug: msg="Variable 'key' is set to {{ key }}"
同时,变量的定义也可以在一个独立的文件中完成,方法是在Playbook中使用vars_files
代码块来引用。
---
- hosts: local
vars_files:
- vars.yml
tasks:
- debug: msg="Variable 'key' is set to {{ key }}"
# vars.yml内容如下
---
key: value
利用Ansible的内置环境变量实现变量配置未见的有条件导入。
当前生产环境中又多台主机,分别安装了CentOS系统和Debian系统,同时为两套系统设置两个变量定义文件:apache_CentOS.yml和apache_default.yml,进行如下配置
---
- hosts: local
var_files:
- ["apache_{{ ansible_os_family }}.yml", "apache_default.yml"]
tasks:
- service: name={{ apache }} state=running
在执行Playbook过程中,Ansible会先尝试读取对应名称的变量定义文件,如果没找到,会读取apache_default.yml
注册变量
注册变量,其实就是将操作的结果,包括标准输出和标准错误输出,保存到变量中,然后再根据这个变量的内容来决定下一步的操作,在这个过程中用来保存操作结果的变量就叫注册变量。
注册变量使用register
关键字进行注册,注册完毕后可以通过stdout
标准输出和stderr
错误输出来读取注册变量的内容。
主机变量和组变量
主机变量和组变量的定义有两种方式,第一种可以直接定义在inventory文件中
# 主机变量,只对对应的主机生效
[local]
server1 key=value
# 组变量,只对当前组生效
[local:vars]
key=value
第二种方式定义在group_vars和host_vars目录中
在Ansible目录中新建目录group_vars
和host_vars
,变量文件的名称要对应组或者主机的名称,然后在文件中以key:value的形式定义变量。
同时也可以在这两个文件夹下定义all.yml
文件,来为所有主机组合主机定义变量。
要获取某一远程主机的变量可以使用{{ hostvars['server1']['key'] }}
的方式
变量的优先级
以下变量优先级由高到低
- 命令行中定义的变量(用-e定义的变量)
- 在Inventory中定义的连续变量(比如ansible_ssh_user)
- 大多数的其他变量(命令行装换、play中的变量、included的变量、role中的变量等)
- 在Inventory中定义的其他变量
- 有系统通过gather_facts方法发现的Facts
- “Role默认变量”
if/then/when——流程控制
when关键字
需要在特定条件下才能执行的语句,使用when
关键字进行定义。
- shell: php --version
register: php_version
-shell: yum -y downgrade php*
when: "'7.0' in php_version.stdout"
changed_when、failed_when
有时候Ansible的任务返回结果无论成功失败都是changed,我们可以使用changed_when
手动标识任务的成功状态。
---
- hosts: local
tasks:
-name: Install dependencies
command: "composer global require phpunit/phpunit --prefer-dist"
register: composer
changed_when: "'Nothing to install or update' not in composer.stdout"
Tags标签
默认情况下,Ansible在执行一个Playbook时,会执行Playbook中定义的所有任务。Ansible的标签功能可以给角色(Roles)、文件、单独的任务甚至整个Playbook打上标签,然后利用这些标签来指定要运行Playbook中的个别任务,或不执行指定的任务。
---
- hosts: local
# 给整个Playbook所有任务打标签
tags: deploy
roles:
# 给角色打标签
- { role: tomcat, tags: ['tomcat', 'app'] }
tasks:
- name: ping
command: "ECHO 'Hello World'"
# 给单独的任务打标签
tags:
- hello
执行特定的Tags任务
# 执行标签任务
ansible-playbook test.yml --tags "hello"
# 不执行标签任务
ansible-playbook test.yml --skip-tags "hello"
Block块
块功能可以将任务进行分组,可以在块级别上应用任务变量。
---
- hosts: local
tasks:
# Install and configure Apache on RedHat/CentOS hosts.
- block:
- yum: name=httpd state=present
- template: src=httpd.comf.j2 dest=/etc/httpd/conf/httpd.conf
- service: name=httpd state=started enabled=yes
when: ansible_os_family == 'RedHat'
sudo: yes
# Install and configure Apache on Debian/Ubuntu hosts.
- block:
- apt: name=apache2 state=present
- template: src=httpd.conf.j2 dest=/etc/apache2/apache2.conf
- service: name=apache2 state=started enabled=yes
when: ansible_os_family == 'Debian'
sudo: yes
使用块功能处理任务的异常
---
- hosts: local
tasks:
- block:
- name: test
script: monitoring-connect.sh
rescue:
- name: 只有脚本报错时才执行
debug: msg="error"
always:
- name: 无论结果如何都执行
debug: msg="always"
Includes
Includes可以引用文件,已达到代码复用的效果,不仅可以引用YML文件,还可以引用Vars、Handlers、Files文件
---
- hosts: local
tasks:
- include: included.yml
# 带条件引入
when: 1 in [1, 2, 3]
Roles
Roles可以通过特定的目录结构自动引入和该Roles相关的文件,已达到解耦和复用的目的。
基本用法
# 在根目录下创建对应文件夹,在创建main.yml,添加Roles后,会自动读取Main.yml的内容
mkdir -p roles/deploy/tasks
cd roles/deploy/tasks
touch main.yml
# 引入Roles
---
- hosts: local
roles:
- deploy
变量
Roles会自动读取同名Roles目录同名目录下的vars目录的main.yml文件中定义的变量,无需引入。