一、YAML语法简介
YAML介绍:
YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、
Python、Perl以及电子邮件格式RFC2822等。
Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者
YAML特性:
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
更多的内容及规范参见YAML的官方网站:http://www.yaml.org
YAML语法格式:
在单一档案中,可用连续三个连字号(——)区分多个档案。另外,还有选择性的连续三个点号,( … )用来表示档案结尾
次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
使用#号注释代码
缩进必须是统一的,不能空格和tab混用
缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
YAML文件内容和Linux系统大小写判断方式保持一致,是区别大小写的,k/v的值均需大小写敏感
k/v的值可同行写也可换行写。同行使用:分隔
v可是个字符串,也可是另一个列表
一个完整的代码块功能需最少元素需包括 name: task
一个name只能包括一个task
YAML文件扩展名通常为yml或yaml
YAML语法简介:
[列表]
List:列表,其所有元素均使用“-”打头
示例:
# A list of tasty fruits
– Apple
– Orange
– Strawberry
– Mango
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
[字典]
Dictionary:字典,通常由多个key与value构成
示例:
---
# An employee record
name: Example Developer
job: Developer
skill: Elite
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
也可以将key:value放置于{}中进行表示,用,分隔多个key:value
示例:
---
# An employee record
{ name: Example Developer, job: Developer, skill: Elite }
- 1
- 2
- 3
- 4
二、Ansible中的剧本Playbook用法
Playbook核心元素:
- Hosts:执行的远程主机列表
- Tasks:任务列表
- remote_user:远程登录用户名,作用于host和task
- Varniables:内置变量或自定义变量在playbook中调用
- Templates:模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers:和notify结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags:标签,指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性。
因此会自动跳过没有变化的部分。此时,如果确信其没有变化,就可以通过tags跳过此些代码片段
实例:
---
- hosts: websrvs # 主机分组
remote_user: root # 远程访问登录的用户名
tasks: # 执行任务列表
- name: install httpd # 执行任务名
yum: name=httpd # 执行任务ansible命令
- name: copy config file
copy: src=/app/httpd.conf dest=/ect/httpd/conf/ backup=yes
tags: start_httpd # 任务执行指定标签
notify: restart httpd # 触发特性条件,跳过以下命令,执行指定handlers任务
- name: start httpd
tags: start_httpd # 任务标签名
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd state=restarted
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
三、Playbook中变量的使用
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
ansible all -m setup 远程主机的所有变量都可直接调用
在/etc/ansible/hosts中定义
普通变量:主机组中主机单独定义,优先级高于公共变量
host分组变量:针对主机组中所有主机定义统一变量
通过命令行指定变量,优先级最高
例如:ansible-playbook –e varname=value
- 1
在playbook中定义
vars: – var1: value1 – var2: value2
- 1
- 2
- 3
- 4
- 5
在role中定义
变量定义:key=value
示例:http_port=80
变量调用方式:
通过{{ variable_name }} 调用变量,且变量名前后必须有空格, 有时用”{{ variable_name }}”才生效
- 1
- 2
- 3
变量调用优先级:
命令行-e > playbook定义 > hosts普通变量 > host分组变量
- 1
实例
1:命令行变量赋值vim var2.yml —-- – hosts: websrvs remote_user: root tasks: – name: install package yum: name={{ pkname }} – name: start service service: name={{ pkname }} state=started enabled=yes ansible-playbook -e ‘pkname=vsftpd’ var2.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
2:playbook中赋值变量
vim var1.yml --- – hosts: websrvs remote_user: root vars: – pkname1: httpd – pkname2: vsftpd tasks: – name: install package yum: name={{ pkname1 }} – name: install package yum: name={{ pkname2 }} ansible-playbook var1.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
3:hosts文件中定义普通变量
vim /etc/ansible/hosts 192.168.30.11 httpd_port=81 192.168.30.12 httpd_port=82 vim hostname.yml --- – hosts: websrvs remote_user: root tasks: – name: set hostname hostname: name=web-{{ httpd_port }} ansible-playbook -C hostname.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
4:hosts文件中定义分组变量
vim /etc/ansible/hosts [websrv:vars] nodename=www domainname=wxlinux.com vim hostname2.yml --- – hosts: websrvs remote_user: root tasks: – name: set hostname hostname: name={{nodename}}{{http_port}}.{{domainname}} ansible-playbook hostname.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
5:引用系统自带变量
ansible all -m setup |grep ansible_fqdn 查看系统自带变量 vim var.yml --- – hosts: websrvs remote_user: root tasks: – name: create log file file: name=/data/{{ ansible_fqdn }}.log state=touch ansible-playbook var.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
6:定义变量到一个文件中
vim vars.yml var1: httpd var2: vsftpd vim testvar.yml --- – hosts: websrvs remote_user: root vars_files: – vars.yml tasks: – name: install package yum: name={{ var1 }} – name: create file file: name=/data/{{ var2 }}.log state=touch ansible-playbook testvar.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
四、Playbook中模板的用法
templates模板简介:
功能:根据模块文件动态生成对应的配置文件
使用方法:
templates文件必须存放在templates目录下,且以.j2为后缀
templates模块只能被playbook调用
yam文件需和templates目录平级,目录结构如下:
./ ├── temnginx.yml └── templates └── nginx.conf.j2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
templates使用形式:
字符串:使用单引号或双引号 数字:整数,浮点数 列表:[item1, item2, …] 元组:(item1, item2, …) 字典:{key1:value1, key2:value2, …} 布尔型:true/false 算术运算:+, -, *, /, //, %, ** 比较操作:==, !=, >, >=, <, <= 逻辑运算:and, or, not 流表达式:For If When
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
实例:
1:使用template传输配置文件
cp /etc/nginx/nginx.conf templates/nginx.conf.j2 vim testtemplate.yml --- – hosts: os6 remote_user: root tasks: – name: install package yum: name=nginx – name: copy template template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf – name: start service service: name=nginx state=started enabled=yes ansible-playbook testtemplate.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
执行结果:运行playbook后,我们发现work process进程数量与虚拟机cpu内核数量是一致的,
接下来我们将把配置模板中的work process进程数量与系统自带变量结合起来引用。
2:template引用系统变量ansible websrvs -m setup |grep ‘cpu’ vim templates/nginx.conf.j2 worker_processes {{ ansible_processor_vcpus+2 }}; vim testtemplate.yml --- – hosts:os6 remote_user: root tasks: – name: install package yum: name=nginx – name: copy template template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: restart service – name: start service service: name=nginx state=started enabled=yes handlers: – name: restart service service:name=nginx state=restarted ansible-playbook testtemplate.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
执行结果:再次运行playbook后,我们发现worker process进程数量等于cpu核心数量加2,这样template
就能帮我们实现根据不同主机性能定制相应的配置。
3:hosts文件普通变量修改nginx服务端口vim /etc/ansible/hosts 192.168.30.101 httpd_port=81 192.168.30.102 httpd_port=82 vim templates/nginx.conf.j2 server { listen {{ http_port }} default server listen [::]:{{ http_prot }} default server }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
五、Playbook中逻辑语句的用法
When:
条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与
否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法
查看发行版本系统变量:ansible srv -m setup filter=”*distribution”
- 1
1: 使用when匹配系统版本
vim testtemplate.yml --- – hosts: all remote_user: root tasks: – name: install package yum: name=nginx – name: copy template for centos7 template: src=nginx.conf7.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version == “7” notify: restart service – name: copy template for centos6 template: src=nginx.conf6.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version == “6” notify: restart service – name: start service service: name=nginx state=started enabled=yes handlers: – name: restart service service:name=nginx state=restarted
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
执行结果:当when语句不匹配时,将skipping直接跳过,仅执行与when语句匹配的语句内容,
最终CentOS6,7根据不同的版本号生成对应的配置并启动服务。
2:使用迭代创建组
vim testitem2.yml --- – hosts: all remote_user: root tasks: – name: create some groups group: name={{ item }} when: ansible_distribution_major_version == “7” with_items: – g1 – g2 – g3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
执行结果:当系统版本为CentOS7时,创建g1,g2,g3组
3:使用迭代配合字典创建用户与组vim testitem2.yml --- – hosts: all remote_user: root tasks: – name: create some groups group: name={{ item }} with_items: – g1 – g2 – g3 – name: create some users user: name={{ item.name }} group={{ item.group }} with_items: – { name: ‘user1’,group: ‘g1’ } – { name: ‘user2’,group: ‘g2’ } – { name: ‘user3’,group: ‘g3’ }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
执行结果:所有主机上创建user1,user2,user3用户,且主组为g1,g2,g3
for 与 if
示例1:template,for
vim for1.conf.j2 {% for port in ports %} server{ listen {{ port }} } {% endfor %} vim testfor.yml --- – hosts: websrvs remote_user: root vars: ports: – 81 – 82 – 83 tasks: – name: copy conf template: src=for1.conf.j2 dest=/data/for1.conf
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
执行结果:每台主机生成for1.conf文件,内容如下
示例2:template,for,引用字典
vim for2.conf.j2 {% for port in ports %} server{ listen {{ port.listen_port }} } {% endfor %} cp testfor.yml testfor2.yml vim testfor2.yml --- – hosts: websrvs remote_user: root vars: ports: – listen_port: 81 – listen_port: 82 – listen_port: 83 tasks: – name: copy conf template:src=for2.conf.j2 dest/data/for2.conf
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
执行结果:每台主机生成for2.conf文件,内容如下
示例3:for循环中调用字典vim for3.conf.j2 {% for p in ports %} server{ listen {{ p.port }} servername {{ p.name }} documentroot {{ p.rootdir }} } {% endfor %} cp testfor2.yml testfor3.yml vim testfor3.yml --- – hosts: websrvs remote_user: root vars: ports: – web1: port: 81 name: web1.magedu.com rootdir: /data/website1 – web2: port: 82 name: web2.magedu.com rootdir: /data/website2 – web3: port: 83 name: web3.magedu.com rootdir: /data/website3 tasks: – name: copy conf template:src=for3.conf.j2 dest/data/for3.conf
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
执行结果:每台主机生成for3.conf文件,内容如下
示例4:for循环中调用if
vim for4.conf.j2 {% for p in ports %} server{ listen {{ p.port }} {% if p.name is defined %} servername {{ p.name }} {% endif %} documentroot {{ p.rootdir }} } {% endfor %} cp testfor3.yml testfor4.yml vim testfor4.yml --- – hosts: websrvs remote_user: root vars: ports: – web1: port: 81 #name: web1.magedu.com rootdir: /data/website1 – web2: port: 82 name: web2.magedu.com rootdir: /data/website1 – web3: port: 83 #name: web3.magedu.com rootdir: /data/website1 tasks: – name: copy conf template:src=for4.conf.j2 dest/data/for4.conf
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
执行结果:每台主机生成for3.conf文件,内容如下,
web1与web3的name没赋值,所有跳过,web2的name被赋值,文件中输出结果
六、Roles角色详解
角色(roles):角色集合
roles |-- filecopy |-- httpd |-- memcached |-- mysql `-- nginx
- 1
- 2
- 3
- 4
- 5
- 6
/roles/project/ :项目名称,有以下子目录
nginx |-- files |-- tasks |-- templates |-- handlers |-- meta `-- vars files/ :存放由copy或script模块等调用的文件 templates/:template模块查找所需要模板文件的目录 tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件; 其它的文件需要在此文件中通过include进行包含 handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过 include进行包含 vars/:定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件 中通过include进行包含 meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件, 其它文件需在此文件中通过include进行包含 default/:设定默认变量时使用此目录中的main.yml文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
建议:roles创建在ansible目录
如:mkdir roles mkdir roles/{httpd,mysql,memcache,nginx} -pv
- 1
- 2
- 3
实例
1:定义nginx角色
niginx 1.group:nginx 2.user:nginx 3.yum:nginx 4.template:nigin.conf.j2 5.service:nginx
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
目录结构如下:
cd nginx mkdir tasks templates cd tasks vim group.yml – name: create group group: name=nginx gid=80 vim user.yml – name: create user user: name=nginx group=nginx uid=80 shell=/sbin/noligin vim yum.yml – name: install package yum: name=nginx vim start.yml – name: start service service: name=nginx state=started enabled=yes vim restart.yml – name: restart service service: name=nginx state=restarted cp /etc/nginx/nginx.conf template/nginx.conf.j2 vim template/nginx.conf.j2 worker_processes {{ ansible_processes_vcpus+2 }}; vim templ.yml – name: copy conf template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf vim main.yml – include: group.yml – include: user.yml – include: yum.yml – include: templ.yml – include: start.yml 调用角色的剧本要和roles目录在同一文件夹 vim nginx_roles.yml – hosts: websrvs romete_user: root roles: – role: nginx ansible-playbook -C nginx_role.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
2:增加httpd角色
结构目录如下:
cd httpd/ mkdir tasks cd tasks/ vim user.yml – name: create user user: name=apache system=yes shell=/sbin/nologin cd httpd/ mkdir files cp httpd.conf files/ cd /tasks/ vim copyfile.yml – name: copy files copy: src=httpd.conf dest=/data/ own=apache vim main.yml – incluse: user.yml – incluse: copyfile.yml vim httpd_role.yml – hosts: websrvs romete_user: root roles: – role: httpd
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
示例3:同时调用两个roles角色
目录结构:
cp niginx_role.yml some_role.yml vim some_role.yml – hosts: websrvs romete_user: root roles: – role: httpd – role: nginx
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
示例4:一个roles角色调用另一个roles角色的task任务
目标:nginx调用httpd的copyfile
vim main.yml – include: group.yml – include: user.yml – include: yum.yml – include: templ.yml – include: start.yml – inclide: roles/httpd/tasks/copyfile.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
示例5:roles playbook tags
目录结构如下:
cp -r nginx/ app/ 首先虚构一个app的role vim some_role2.yml – hosts: websrvs romete_user: root roles: – { role: httpd,tags:[‘web’,’httpd’]} – { role: nginx,tags:[‘web’,’nginx’]} – { role: app,tags:’app’} ansible-playbook -t web some_role.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
执行结果:只执行标签为web的role
示例6:roles playbook tags when
cp -r nginx/ app/ 虚构一个role vim some_role3.yml – hosts: all romete_user: root roles: – { role: httpd,tags:[‘web’,’httpd’]} – { role: nginx,tags:[‘web’,’nginx’] when: ansible_distribution_major_version==”7″} – { role: app,tags:’app’} ansible-playbook -t web some_role.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
执行结果:至执行tags标签为web的roles,当主版本号为7时,才执行nginx的role
示例7:综合演示
结构目录:
rm -rf /app mkdir app cd app mkdir tasks templates vars handlers files cd tasks/ vim group.yml – name: create group group: name=app system=yes gid=123 vim user.yml – name: create user user: name=app group=app system=yes shell=/sbin/nologin uid=123 vim yum.yml – name: install package yum: name=httpd cp /etc/httpd/conf/httpd.conf /templates/httpd.conf.j2 vim temlates/httpd.conf.j2 Listen {{ ansible_processor_vcpus*10 }} User {{ username }} Group {{ groupname }} vim /vars/main.yml username: app groupname: app vim templ.yml – name: copy conf temlplate: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf notify: restart service vim start.yml – name: start service service: name=httpd state=started enabled=yes vim handlers/main.yml – name: restart service service: name=httpd state=restarted touch files/vhosts.conf vim copyfile.yml – name: copy config copy: src=vhosts.conf dest=/ect/httpd/conf.d/ vim main.yml – include: group.yml – include: user.yml – include: yum.yml – include: templ.yml – include: copyfile.yml – include: start.yml cd ansible/ vim app_role.yml – hosts: websrvs remote_user: root roles: – role: app
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
示例8:部署memcached,占用内存为物理内存1/4
yum install memcached
目录结构:
cp /etc/sysconfig/memcached templates/memcached.j2 vim memcached.j2 CACHESIZE=”{{ ansible_memtotal_mb//4 }}” vim tasks/yum.yml – name: install package yum: name=memcached vim templ.yum – name: copy conf template: src=memcached.j2 dest=/etc/sysconfig/memcached vim start.yml – name: start service service: name=memcached state=started enabled=yes vim main.yml – include: yum.yml – include: templ.yml – inculde: start.yml vim memcached_role.yml – hosts: os6 remote_user: root roles: – role: memcached ansible-playbook memcached_role.yml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
远程查看配置文件,确认生效:
ansible os6 -a 'cat /etc/sysconfig/memcached'
- 1
转载博主 绿叶