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的官方网站:http://www.yaml.org
在单一档案中,可用连续三个连字号(——)区分多个档案。另外,还有选择性的连续三个点号,( … )用来表示档案结尾
次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
使用#号注释代码
缩进必须是统一的,不能空格和tab混用
缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
YAML文件内容和Linux系统大小写判断方式保持一致,是区别大小写的,k/v的值均需大小写敏感
k/v的值可同行写也可换行写。同行使用:分隔
v可是个字符串,也可是另一个列表
一个完整的代码块功能需最少元素需包括 name: task
一个name只能包括一个task
YAML文件扩展名通常为yml或yaml
[列表]
List:列表,其所有元素均使用“-”打头
示例:
# A list of tasty fruits
– Apple
– Orange
– Strawberry
– Mango
[字典]
Dictionary:字典,通常由多个key与value构成
示例:
---
# An employee record
name: Example Developer
job: Developer
skill: Elite
也可以将key:value放置于{}中进行表示,用,分隔多个key:value
示例:
---
# An employee record
{ name: Example Developer, job: Developer, skill: Elite }
实例:
---
- 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
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
ansible all -m setup 远程主机的所有变量都可直接调用
在/etc/ansible/hosts中定义
普通变量:主机组中主机单独定义,优先级高于公共变量
host分组变量:针对主机组中所有主机定义统一变量
通过命令行指定变量,优先级最高
例如:ansible-playbook –e varname=value
在playbook中定义
vars:
– var1: value1
– var2: value2
在role中定义
变量定义:key=value
示例:http_port=80
变量调用方式:
通过{{ variable_name }} 调用变量,且变量名前后必须有空格,
有时用”{{ variable_name }}”才生效
变量调用优先级:
命令行-e > playbook定义 > hosts普通变量 > host分组变量
实例
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
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
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
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
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
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
功能:根据模块文件动态生成对应的配置文件
使用方法:
templates文件必须存放在templates目录下,且以.j2为后缀
templates模块只能被playbook调用
yam文件需和templates目录平级,目录结构如下:
./
├── temnginx.yml
└── templates
└── nginx.conf.j2
字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
算术运算:+, -, *, /, //, %, **
比较操作:==, !=, >, >=, <, <=
逻辑运算:and, or, not
流表达式:For If When
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
执行结果:运行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
执行结果:再次运行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
}
条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与
否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法
查看发行版本系统变量:
ansible srv -m setup filter=”*distribution”
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
执行结果:当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
执行结果:当系统版本为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’ }
执行结果:所有主机上创建user1,user2,user3用户,且主组为g1,g2,g3
示例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
执行结果:每台主机生成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
执行结果:每台主机生成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
执行结果:每台主机生成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
执行结果:每台主机生成for3.conf文件,内容如下,
web1与web3的name没赋值,所有跳过,web2的name被赋值,文件中输出结果
角色(roles):角色集合
roles
|-- filecopy
|-- httpd
|-- memcached
|-- mysql
`-- nginx
/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文件
建议:roles创建在ansible目录
如:
mkdir roles
mkdir roles/{httpd,mysql,memcache,nginx} -pv
实例
1:定义nginx角色
niginx
1.group:nginx
2.user:nginx
3.yum:nginx
4.template:nigin.conf.j2
5.service:nginx
目录结构如下:
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
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
示例3:同时调用两个roles角色
cp niginx_role.yml some_role.yml
vim some_role.yml
– hosts: websrvs
romete_user: root
roles:
– role: httpd
– role: nginx
示例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
示例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
执行结果:只执行标签为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
执行结果:至执行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
示例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
远程查看配置文件,确认生效:
ansible os6 -a 'cat /etc/sysconfig/memcached'