浅谈Ansible之playbook
playbook介绍
- playbook 剧本是由一个或多个“play”组成的列表
- play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。
- Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
- Playbook 文件是采用YAML语言编写的
YAML介绍:
- playbook采用YAML格式
- YAML:Yet Another Markup Language,一个可读性高,用来表达数据序列的格式
- YAML能表达的基本数据结构:标量、数组、关联数组
- yaml语法特性
- 以 — (三个减号)开始,必须顶行写;
- 次行开始写Playbook的内容,但是一般要求写明该playbook的功能;
- 严格缩进,并且不能用Tab键缩进;
- 缩进级别必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
- K/V的值可同行写,也可换行写。同行使用 :分隔,换行写需要以 - 分隔;
- 一个完整的代码块功能需最少元素需包括 name 和 task
- 一个name只能包括一个task
- YAML文件扩展名通常为yml或yaml
playbook的运用
playbook的核心元素:
- Hosts 执行的远程主机列表
- Tasks 任务集
- Variables 内置变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
playbook的基础组件:
-
hosts:运行指定任务的目标主机
-
remoute_user:在远程主机上执行任务的用户,权限提升时可能要用到
sudo_user
-
tasks:任务列表
格式:
(1)action: module arguments
(2)module: arguments
建议使用
注意:shell
和command
模块后面直接跟命令,而非key=value
类的参数列表;
某任务的状态在运行后为changed时,可通过notify通知给相应的handlers;
任务可以通过tags打标签,而后可在ansible-playbook命令上使用-t指定进行调用; -
handlers:处理器,在特定条件下触发任务接收到其它任务的通知时被触发
-
notify: HANDLER TASK NAME
变量:variables
1️⃣直接调用
注意:可使用setup
模块直接获取目标主机的facters
2️⃣用户自定义变量:
-
方法一:
ansible-playbook
命令行中指定
-e VARS, --extra-vars=VARS
-
方法二:在playbook中定义变量
- var1: value1
变量引用:{{ variable }}
,注意变量名前后均有空格 -
方法三:通过
roles
传递变量 -
方法四:
Host Inventory
,主机清单- 用户自定义变量
- 向不同的主机传递不同的变量
IP/HOSTNAME varaiable=value var2=value2
- 向组中的主机传递相同的变量
[groupname:vars]
variable=value
- 注意:优先级低于playbook中的定义
- 向不同的主机传递不同的变量
- 用户自定义变量
-
invertory参数
用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量
IP/HOSTNAME [ ansible_ssh_host | ansible_ssh_port | ansible_ssh_user | ansible_ssh_pass | ansbile_sudo_pass]
,危险不建议使用
3️⃣变量优先级
上述这些变量定义的方法,它们的优先级如下:
- 在命令行中定义的变量(即用-e或–extra-vars定义的变量);
- 在Inventory中定义的连接变量(比如:ansible_ssh_user);
- 大多数的其他变量(命令行转换、play中的变量、included的变量、role中的变量等);
- 在Inventory中定义的其他变量;
- Facts变量;
“Role”默认变量,这个是默认的值,很容易丧失优先权。
4️⃣测试playbook:
ansible-playbook --check|-C
只检测可能会发生的改变,但不真正执行操作ansible-playbook --list-hosts
列出运行任务的主机ansible-playbook --list-tasks
列出要运行的任务列表ansible-playbook --syntax-check
语法检查--limit
主机列表 #只针对主机列表中的主机执行-v -vv -vvv
#显示过程
示例: playbook实现远程安装httpd
- 安装httpd.yaml
---
- hosts: testsrv
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: install configure fire
copy: src=/etc/ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start service
service: name=httpd state=started enabled=yes
- 卸载干净httpd
---
- hosts: testsrv
remote_user: root
tasks:
- name: remove httpd package
yum: name=httpd state=absent
- name: remove apache user
user: name=apache state=absent
- name: remove apache file
fiel: name=/etc/httpd state=absent
- 引入变量以及notify安装httpd.yaml
---
- hosts: testsrv
remote_user: root
vars:
- pkg: httpd
tasks:
- name: install httpd package
yum: name={{ pkg }}
- name: copy configure fie
copy: name=/etc/ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart / 注意这一块必须跟上面notify名字必须一模一样
service: name=httpd state=restarted
playbook进阶roles角色
Roles是一种利用在大型Playbook中的剧本配置模式,它有着自己特定的结构。用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。
简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
- 剧本roles设计思路:将公共任务、资源、变量等对象尽可能独立。
playbook中角色的调用
- 调用角色的语法:
---
- hosts: testsrv
remote_user: root
roles:
- mysql
- httpd
- 调用角色方法2:
键role用于指定角色名称,后续的k/v用于传递变量给角色
---
- hosts: testsrv
remote_user: root
roles:
- mysql
- { role: nginx, username: nginx }
- 调用角色方法3:还可基于条件测试实现角色调用
---
- hosts: testsrv
remote_user: root
roles:
- { role: nginx, username: nginx, when: ansible_distribution_major_version
== ‘7’ }
roles中tags使用
#nginx-role.yml
---
- hosts: testsrv
remote_user: root
roles:
- { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6“ }
- { role: httpd ,tags: [ 'httpd', 'web' ] }
- { role: mysql ,tags: [ 'mysql', 'db' ] }
- { role: mariadb ,tags: [ 'mariadb', 'db' ] }
ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
实验:使用roles安装配置nginx
- 创建目录结构
[root@ansible /etc/ansible]#mkdir -pv /etc/ansible/roles/nginx/{tasks,handlers,vars,files,templates}
[root@ansible /etc/ansible]#tree roles/
roles/
└── nginx
├── files
├── handlers
├── tasks
├── templates
└── vars
- 定义tasks目录文件执行顺序
[root@ansible /etc/ansible/roles]#vim nginx/tasks/main.yml
- nclude: install.yml
- include: config.yml
- include: index.yml
- include: service.yml
- 准备main目录下属文件的内容
[root@ansible /etc/ansible/roles]#vim nginx/tasks/install.yml
- name: install nginx package
yum: name=nginx state=latest
[root@ansible /etc/ansible/roles]#vim nginx/tasks/config.yml
- name: install conf file
template: src=web.conf.j2 dest=/etc/nginx/conf.d/web.conf
notify: reload nginx service
tags: instconf
[root@ansible /etc/ansible/roles]#vim nginx/tasks/index.yml
- name: create doc root
file: path={{ ngx_doc_root }} state=directory
tags: instconf
[root@ansible /etc/ansible/roles]#vim nginx/tasks/service.yml
- name: start nginx service
service: name=nginx state=started enabled=yes
- 编辑模板templates文件
[root@ansible /etc/ansible/roles]#vim nginx/templates/web.conf.j2
server {
listen {{ ngx_server_port }};
server_name {{ ngx_server_name }};
location / {
root {{ ngx_doc_root }};
}
}
- 编辑变量vars配置文件
[root@ansible /etc/ansible/roles]#vim nginx/vars/main.yml
ngx_server_port: 80
ngx_server_name: www.testlinux.com
ngx_doc_root: /app/webdata
- 编辑handlers文件
[root@ansible /etc/ansible/roles]#vim nginx/handlers/main.yml
- name: reload nginx service
service: name=nginx state=reloaded
- 编辑playbook文件
[root@ansible /etc/ansible/roles]#vim /etc/ansible/yamls/install_nginx.yml
---
- hosts: testsrv
remote_user: root
roles:
- nginx
- 测试并执行playbook
ansible-playbook -C /etc/ansible/yamls/install_nginx.yml
ansible-playbook /etc/ansible/yamls/install_nginx.yml
- 执行后可以看到配置文件中的信息按照定义的变量值配置
[root@Centos7 tmp]# cat /etc/nginx/conf.d/web.conf
server {
listen 80;
server_name www.testlinux.com;
location / {
root /app/webdata;
}
}
- 在运行playbook时指定变量值,优先级高于配置文件,同时指定只执行标签instconf处的任务
ansible-playbook -e "ngx_server_port=1080" -t instconf /etc/ansible/yamls/install_nginx.yml
- 查看修改后的配置文件
[root@Centos7 tmp]# cat /etc/nginx/conf.d/web.conf
server {
listen 1080;
server_name www.testlinux.com;
location / {
root /app/webdata;
}
}
- 也可以在playbook中直接传递变量给角色
vim /etc/ansible/yamls/install_nginx.yml
---
- hosts: testsrv
remote_user: root
roles:
- { role: nginx, ngx_server_port: 9000 } // 指定传入的角色,变量名:变量值
ansible-playbook -t instconf /etc/ansible/yamls/install_nginx.yml