我们知道,一些简单的任务,我们可以用Ad-Hoc的模式来完成,但是一些较为复杂的呢?或者多个任务呢?这时候Ad-Hoc就显的有些捉襟见肘了,我们是时候来掌握一些进阶的ansible用法了
嗯,大致是下面这种意思(简单明了?)
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
在单一档案中,可用连续三个连字号(---)区分多个档案。另外,还有选择性的连续三个点号(...)用来表示档案的结尾
次行开始正常写playbook的内容,一般建议写明该playbook的功能,相当于一个tag
使用#号注释代码
缩进必须是统一的,不能空格和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}
YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,
序列(Sequence)里的项用“-”来表示,Map里的键值对用“:”分割
示例:
name: sansan
age: 23
gender: Male
spouse:
name: xiaomei
age: 22
gender: Female
children:
- name: xiaoyao
age: 1
gender: Male
Hosts 执行的远程主机列表
Tasks 任务集
Varniables 内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags 标签 指定某条件任务执行,用于选择运行playbook中的部分代码,ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码
为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过某些代码片段
ansible-playbook -t tagsname useradd.yml
Hosts:
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行任务的主机,需事先定义主机清单中
可以是如下形式:
one.example.com
one.example.com:two.example.com
10.0.194.80
10.0.194.*
test:ceshi 俩个组的并集
test:&ceshi 俩个组的交集
test:!ceshi 在test组中,但不在ceshi组
示例: -Hosts: test:ceshi
remote_user
remote_user:可用于host和task中。也可以通过指定其通过sudo的方式在远端主机上执行任务,其可用于play全局或某任务;
此外,甚至可以再sudo时使用sudo_user指定sudo时切换的用户
-host: test
remote_user: root
tasks:
- name: test connection
ping
remote_user: ceshi
sudo: yes ####默认sudo为root
sudo_user: sansan ####sudo为sansan
tasks:任务列表
格式:(1)action.module arguments
(2)module:arguments 建议使用
注意:shell和command某块后面跟命令,而非key=value
某状态的任务在运行后为changed时,可通过“notify”通知给相应的handlers
任务可以通过“tags”打标签,而后可在ansib-playbook命令上使用-t指定进行调用
示例:
tasks:
-name: disable selinux
command: /sbin/setenforce 0
如果命令或脚本的退出码不为零,可以使用如下方式替代
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors来忽略错误信息
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
运行playbook的方式
Usage: ansible-playbook [options] playbook.yml [playbook2 ...]
常见选项
--check 只检测可能会发生的改变,但不真正执行操作
--list-hosts 列出运行任务的主机
--limit 主机列表 只针对主机列表中的主机执行
-v 显示过程 -vv -vvv更详细
示例:
ansible-playbook file.yml --check 只检测
ansible-playbook file.yml
ansible-playbook file.yml --limit test 还可以只针对某一台主机
shell脚本
#!/bin/bash
#安装Apache
yum install --quite -y httpd
#复制配置文件
cp /tmp/httpd.conf /etc/conf/httpd.conf
cp /tmp/vhosts.conf /etc/httpd.conf.d/
#启动Apache,并设置开机启动
service httpd start
chkconfig httpd on
playbook定义
---
- hosts: all
tasks:
- name "安装apache"
yum: name=httpd
- name: "复制配置文件"
copy: src=/tmp/httpd.conf dest=/conf/httpd.conf
- name:
copy: src=/tmp/vhosts.conf dest=/etc/httpd.conf.d/
- name: "启动apache,并设置开机启动"
service: name=httpd state=started enabled=yes
可见,playbook与shell脚本是类似的,我们的模块就相当于shell中的一条条命令;但是相比来说,playbook看起来比shell脚本更简洁明了,通俗易懂,层次感鲜明
Handlers是task列表,这些tasks与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作
Notify次action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性的执行所有指定操作
在notify中列出的操作成为handler,也即notify中调用handler中定义的操作
示例:httpd.yml
- hosts: ceshi
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=file/httpd.conf dest=/etc/httpd.conf/ backup=yes ####假如我们原来执行过一次这个剧本,然后修改了配置文件,再次执行的时候
- name: start service ####由于原来服务已经启动了,所以不会接着执行了,就相当于我们剧本并没有生效
service: name=httpd state=started enabled=yes
加入handlers后
示例:httpd.yml
- hosts: ceshi
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=file/httpd.conf dest=/etc/httpd.conf/ backup=yes
notify: restart service ###与下面你写的触发器的action的name一致,当然此处同样可以多个
# notify:
- restart service
- check nginx process
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restarted
# - name: check nignx process
shell: killall -0 nginx >/tmp/nginx.log ##向nginx服务发送0信号,如果返回值为0,则服务正常;如若返回值为1,则表明服务down了,我们就需要重新拉起服务(注:此项不适合多进程服务,因为所有nginx挂了后才返回值为0)
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
1、ansible setup facts远程主机的所有变量都可直接调用
2、在/etc/ansible/hosts中定义
普通变量:主机组中主机单独定义,优先级高于公共变量
公共(组)变量:针对主机组中所有的主机定义统一变量
示例:
[root@ceshi ~]# cat hosts
[ceshi]
10.0.194.81
10.0.194.80
[ceshi:vars]
ansible_ssh_user=root
ansible_ssh_pass="123456"
ansible_ssh_port=5433
3、通过命令行指定变量,优先级最高
ansible-playbook -e varname=value
4、在playbook中定义
vars:
- var1: value1
- var2: value2
5、在role中定义
示例1、:
---
- hosts: test
remote_user= root
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enabled=yes
ansible-playbook -e 'pkanme=vsftpd' test.yml
示例2、:
---
- hosts: test
remote_user= root
tasks:
- name: install package
yum: name={{ pkname1 }}
- name: install package
yum: name={{ pkname2 }}
当然也可以安装多个,ansible-playbook -e 'pkanme1=vsftpd pkname2=httpd' test.yml
示例3、:
---
- hosts: test
remote_user= root
vars:
- pkname1: httpd
- pkname2: vsftpd
tasks:
- name: install package
yum: name={{ pkname1 }}
- name: install package
yum: name={{ pkname2 }}
也可以这么写