Ansible Playbooks
Playbooks是Ansible的配置/部署/任务编排使用的语言。
- Ansible modules是负责具体任务的工具,playbooks负责设计和安排如何使用这些工具
- Ansible playbooks的内容基于YAML语法
- Ansible playbooks的官方配置用例请参考:https://github.com/ansible/ansible-examples
- Ansible官方文档请参考:http://docs.ansible.com/ansible/index.html
Ansible Playbooks配置用例说明
- 为了更好地理解Ansible playbooks的结构,此处将选用官方配置中的lamp_simple来做些简单的说明
- 官方用例地址:https://github.com/ansible/ansible-examples/tree/master/lamp_simple
lamp_simple的目录层次如下,README.md包含一些简单的说明
lamp_simple├── LICENSE.md├── README.md├── group_vars│ ├── all│ └── dbservers├── hosts├── roles│ ├── common│ │ ├── handlers│ │ │ └── main.yml│ │ ├── tasks│ │ │ └── main.yml│ │ └── templates│ │ └── ntp.conf.j2│ ├── db│ │ ├── handlers│ │ │ └── main.yml│ │ ├── tasks│ │ │ └── main.yml│ │ └── templates│ │ └── my.cnf.j2│ └── web│ ├── handlers│ │ └── main.yml│ ├── tasks│ │ ├── copy_code.yml│ │ ├── install_httpd.yml│ │ └── main.yml│ └── templates│ └── index.php.j2└── site.yml
文件hosts是inventory file,定义了需要被playbooks配置的节点信息
# []内定义了组名称,一般可以把相同用途的节点放在一个组里[webservers]# 节点名称,需要能被解析为IP地址;也可以直接填写IP地址web3[dbservers]web2
目录roles定义了节点需要被配置的角色类型,例如web,db(可以根据服务类型自定义名称)等;每个角色可以包含一份或者多份playbooks, 此处定义了三种角色类型:common,db,web
roles/├── common│ ├── handlers│ │ └── main.yml│ ├── tasks│ │ └── main.yml│ └── templates│ └── ntp.conf.j2├── db│ ├── handlers│ │ └── main.yml│ ├── tasks│ │ └── main.yml│ └── templates│ └── my.cnf.j2└── web├── handlers│ └── main.yml├── tasks│ ├── copy_code.yml│ ├── install_httpd.yml│ └── main.yml└── templates└── index.php.j2
每种角色类型的目录下可以定义handlers/tasks/templates/files这4个子目录,.yml的文件就是playbook
- tasks目录内的playbook用作多任务编排
- handlers目录内的playbook定义的任务一般只有在执行变更动作的时候才被触发(比如tasks目录的playbook内的任务变更了nginx配置, 可以触发handlers的playbook内重启nginx服务任务的执行)
- templates目录内定义了配置模板,在远程主机上会根据配置模板生成配置文件
- files目录内定义了配置文件,内容会直接同步到远程主机的配置文件
roles/common/handlers/main.yml定义了多个可被触发的任务;任务通过module来定义
执行ansible-doc -l列出所有内置的module
执行ansible-doc [module]获取module的选项和用法---# Handler to handle common notifications. Handlers are called by other plays.# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.# 定义任务名称,执行playbook时会显示- name: restart ntp# 调用`service`module重启ntpdservice: name=ntpd state=restarted- name: restart iptablesservice: name=iptables state=restarted
roles/common/tasks/main.yml定义了多个相互依赖的任务(安装ntp包 -> 配置ntp -> 启动ntpd -> 检查selinux是否运行), 任务根据文件内容从上往下顺序执行;一个playbook内定义的多个任务实际就是配置一个服务执行的相关步骤
---# This playbook contains common plays that will be run on all nodes.- name: Install ntpyum: name=ntp state=present# 可以对任务做标记(tags),运行playbook的时候可以加上-t参数执行指定tag的任务tags: ntp- name: Configure ntp filetemplate: src=ntp.conf.j2 dest=/etc/ntp.conftags: ntp# notify就是触发handlers目录内playbook定义的`restart ntp`任务执行notify: restart ntp- name: Start the ntp serviceservice: name=ntpd state=started enabled=yestags: ntp- name: test to see if selinux is runningcommand: getenforce# registry把getenforce执行的结果保存到sestatus变量register: sestatus# 此处定义只有当`setstatus`值是`false`时才会执行变更changed_when: false
配置模板基于Jinja2模板引擎解析,可以加上
.j2后缀作为标识- 模板引擎查找group_vars里的变量文件
- group_vars里存放多份变量文件时,如果存在和节点所在组名称相同的文件,在此文件中查找变量替换值
- group_vars/all是默认的变量文件
# roles/web/templates/index.php.j2<html><head><title>Ansible Application</title></head><body></br># {{ }}内定义了变量# `ansible_default_ipv4.address`是远程主机的系统信息,可以通过`setup`modules获取所有系统信息# 具体参考官方文档:http://docs.ansible.com/ansible/setup_module.html<a href=http://{{ ansible_default_ipv4.address }}/index.html>Homepage</a></br><?phpPrint "Hello, World! I am a web server configured using Ansible and I am : ";echo exec('hostname');Print "</BR>";echo "List of Databases: </BR>";# Jinja2支持{% %}内定义简单的条件和循环# `groups`/`hostvars`是Ansible内置变量# `groups['dbservers']`是inventory file里定义的[dbservers]# `hostvars[host]`可以查询对应主机的变量值{% for host in groups['dbservers'] %}$link = mysqli_connect('{{ hostvars[host].ansible_default_ipv4.address }}', '{{ hostvars[host].dbuser }}', '{{ hostvars[host].upassword }}') or die(mysqli_connect_error($link));{% endfor %}$res = mysqli_query($link, "SHOW DATABASES;");while ($row = mysqli_fetch_assoc($res)) {echo $row['Database'] . "\n";}?></body></html>
playbook支持
- include: another.yml,可以写多份playbook,然后在main.yml中include其他playbook
playbook支持在module里使用变量,执行时在group_vars里查找变量文件
playbook支持循环,参考:http://docs.ansible.com/ansible/playbooks_loops.html
playbook支持条件判断,参考:http://docs.ansible.com/ansible/playbooks_conditionals.html文件site.yml是全局playbook,定义了节点组和角色类型的对应关系
---# This playbook deploys the whole application stack in this site.- name: apply common configuration to all nodeshosts: all# ssh远程执行用户remote_user: root# 节点组对应的角色roles:- common- name: configure and deploy the webservers and application codehosts: webserversremote_user: rootroles:- web- name: deploy MySQL and configure the databaseshosts: dbserversremote_user: rootroles:- db
执行playbook
$ cd lamp_simple$ ansible-playbook site.yml -i hosts
