YAML语言简介
YAML是一个可读性高的用来表达资料序列的格式。
YAML参考了其他多种语言,包括:XML、C语言、Python以及电子邮件格式RFC2822等。
YAML特性:
1 | YAML的可读性好 |
YAML语法简介
1 | 在单一档案中,可用连续三个连字号(-)区分多个档案。另外,还有选择性的连续三个点号( ... )用来表示档案结尾,次行开始正常写Playbook的内容,一般建议写明该Playbook的功能 |
List:列表,其所有元素均使用”-“开头
示例:
1 | # A list of tasty fruits |
Dictionary:字典,通常由多个key与value构成
示例:
1 | --- |
也可以将key:value放置于{}中进行表示,用,分割多个key:value
例如:
1 | --- |
YAML的语法和其他高阶语言类似,并且可以简单的表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用”-“来代表,Map里的键值对用”:”分割
示例:
1 | name: John Smith |
playbook
playbook核心元素
1 | Hosts 执行的远程主机列表 |
playbook基础组件
hosts
1 | Hosts: |
remote_user
1 | remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户 |
task列表和action
1 | play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务 |
tasks:任务列表
1 | 两种格式: |
是某些返回值不为0的任务不报错的方法
方法一:
1 | tasks: |
方法二:
1 | tasks: |
运行playbook
运行playbook的方式
1 | ansible-playbook filename.yml ... [options] |
常见option
1 | --check -C 只检测可能会发生的改变,但不真正执行操作 |
示例
1 | ansible-playbook file.yml --check 只检测 |
handlers和notify结合使用触发条件
1 | Handlers |
在playbook中使用标签
Ansible 允许给playbook里面的资源通过自定义的关键字打上标签,然后只运行与关键字一致的部分代码
多个动作可以使用同一个标签
只执行特定tags
1 | ansible-playbook -t tags file.yml |
使用示例:playbook实现安装配置运行httpd服务,并且当配置发生更改时重启服务
1 | [root@ansible ~/playbook]#cat httpd_install.yml |
playbook中的变量
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源
1 | 1、ansible setup facts远程主机的所有变量都可直接调用 |
变量的生效顺序:
变量使用
1 | 通过{{ variable_name }}调用变量,且变量名前后必须有空格,有时用"{{ variable_name }}"才能生效 |
变量使用示例
使用ansible命令定义变量
在playbook中调用变量
1 | [root@ansible ~]#cat /root/playbook/vars_test.yml |
在执行playbook时定义给变量赋值
1 | [root@ansible ~]#ansible-playbook /root/playbook/vars_test.yml -e app_name=vsftpd |
在playbook中直接定义变量,并调用变量
1 | [root@ansible ~/playbook]#cat vars_test.yml |
使用专门的文件存放变量
将变量存放在专门的文件中
1 | [root@ansible ~/playbook]#cat vars.yml |
在playbook中调用存放变量的文件
1 | [root@ansible ~/playbook]#cat vars_test.yml |
在主机清单中定义变量
1 | [root@ansible ~/playbook]#cat /etc/ansible/hosts |
在playbook中调用变量
1 | [root@ansible ~]#cat /root/playbook/changename.yml |
模板templates
1 | 文本文件,嵌套有脚本(使用模板编程语言编写) |
1 | templates功能:根据模块文件动态生成对应的配置文件 |
模板使用示例
以安装nginx为例
模板文件必须放在templates文件夹下,templates文件夹与调用该模板的playbook需要是平级的关系。
将NGINX配置文件作为模板放入templates中
1 | [root@ansible ~]#cp /etc/nginx/nginx.conf /root/playbook/templates/nginc.conf.j2 |
在playbook中使用模板
1 | [root@ansible ~/playbook]#cat nginx_install.yml |
此时的目录结构如下
1 | [root@ansible ~/playbook]#tree |
此例即为使用模板批量配置多台主机,模板文件中可以使用变量。
plabook中的template for if语句的用法示例
变量示例
写一个测试用playbook
1 | [root@ansible ~/playbook]#cat for_test3.yml |
增加一个对应的模板文件
1 | [root@ansible ~/playbook]#cat templates/test_for3.conf.j2 |
执行该playbook
1 | [root@ansible ~/playbook]#ansible-playbook for_test3.yml |
查看效果
1 | [root@ansible ~/playbook]#ansible appsrvs -a 'cat /data/test_for3.conf' |
字典示例
写一个测试用paybook
1 | [root@ansible ~/playbook]#cat for_test2.yml |
增加一个对应的模板文件
1 | template: src=test_for2.conf.j2 dest=/data/test_for2.conf |
执行该playbook
1 | [root@ansible ~/playbook]#ansible-playbook for_test2.yml |
到客户端查看执行效果
1 | [root@ansible ~/playbook]#ansible appsrvs -a 'cat /data/test_for2.conf' |
列表示例
写一个测试用playbook
1 | [root@ansible ~/playbook]#cat for_test.yml |
增加一个模板
1 | [root@ansible ~/playbook]#cat templates/test_for.conf.j2 |
执行playbook
1 | [root@ansible ~/playbook]#ansible-playbook for_test.yml |
取被控端主机检查执行效果
1 | [root@ansible ~/playbook]#ansible appsrvs -a 'cat /data/tes*' |
在playbook中使用when判断
1 | 条件测试:如果需要根据变量、facts或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法格式 |
when条件测试使用示例
1 | [root@ansible ~/playbook]#cat nginx_install.yml |
在playbook文件夹下的templates文件夹中,存放了nginx6.conf.j2、nginx7.conf.j2两个配置文件。其目录结构如下
1 | [root@ansible ~/playbook]#tree |
playbook中的迭代
with_items:当有需要重复执行的任务时,可以使用迭代机制
1 | 对迭代选项的引用,固定变量名为"item" |
with_items使用示例
字符串
1 | [root@ansible ~/playbook]#cat with_items.yml |
字典
1 | [root@ansible ~/playbook]#cat with_items.yml |
roles
ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中
复杂场景:建议使用roles,代码复用度高
1 | 变更指定主机或主机组 |
roles的文件结构
需要执行的yml文件和roles文件夹是同级的关系,在roles问价下有实现各种不同功能的子目录如httpd等,在httpd下又有子目录如tasks、files、vars等目录。如下所示
1 | [root@ansible ~/playbook]#tree |
示例:用角色的方式实现httpd的安装
将各个task分别写成文件放入tasks文件夹下,将模板文件放到files文件夹下,tasks文件夹中的main.yml文件内写入各个task的执行次序
1 | [root@ansible httpd]#tree |
1 | root@ansible httpd]#cat tasks/main.yml |
在与roles同级别目录下写一个playbook,调用该role
1 | [root@ansible playbook]#tree |
1 | [root@ansible playbook]#cat httpd_role.yml |
示例:用角色的方式定制memcached的缓存大小
1 |
roles之间的相互调用
以安装NGINX为例示范roles之间的相互调用
文件结构如下
1 | [root@ansible nginx]#pwd |
其中data.yml文件调用httpd角色中的文件
1 | [root@ansible nginx]#cat tasks/data.yml |
在config.yml中使用notify-handler组合
1 | [root@ansible nginx]#cat tasks/config.yml |
1 | [root@ansible nginx]#cat handlers/main.yml |
注意 :handlers文件夹下必须以main.yml为文件名,不然会报错,因为找不到执行handler的入口