ansible剧本playbook使用一览

playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的。

yaml

编程的配置文件,YAML是专门用来写配置文件的语言,比JSON格式更加方便

基本语法规则

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键,只允许使用空格。
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

字典: key: value

列表: [] -

后缀名 yaml yml

支持的数据格式

对象

键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)

1
2
3
4
5
bitmex:
online:
tick: ['XBTUSD']
test:
tick: ['XBTUSD']

转为 python 如下
{"bitmex":{"online": {"tick": ["XBTUSD"]}, "test": {"tick": ["XBTUSD"]}}}

数组

一组按次序排列的值,又称为序列(sequence) / 列表(list)
一组连词线开头的行,构成一个数组。

1
2
3
- BTC
- ETH
- EOS

转为python如下
["BTC", "ETH", "EOS"]

1
2
3
4
-
- BTC
- USD
- EOS

转为python如下
[["BTC", "USD", "EOS"]]

ansible-playbook命令格式

执行顺序: 从上往下

特性:幂等性 不管执行多少遍,结果都是一样的

1
2
3
4
5
ansible-playbook [options] playbook.yml [playbook2 ...] 
-C, --check # 检查,白跑,干跑
-f FORKS, --forks=FORKS #用来做并发
--list-hosts # 列出主机列表
--syntax-check # 语法检查

简单用法

1
2
3
4
5
6
- hosts: web
tasks:
- name: creategroup
group: name=tom10
- name: cretaeuser
user: name=wusir10
1
2
3
4
5
hosts: gb
tasks:
- name: 第san个姑娘
dong: 第san个姑娘

传参

1
2
3
4
- hosts: web
tasks:
- name: create{{ user }}
user: name={{ user}}

第一种方式

1
ansible-playbook -e 'user=tomsb10' p2.yml

第二种方式

1
2
3
[db]
172.17.0.3 user=tomsb11
172.17.0.4 user=tomsb12

第三种方式

1
2
[db:vars] #表示组的参数
user=tomsb13

第四种方式

1
2
3
4
5
6
- hosts: db
vars:
- user: tomsb14
tasks:
- name: create{{ user }}
user: name={{ user}}

第五种传参方式

1
2
3
4
5
6
7
- hosts: db
tasks:
- name: sum
shell: echo 7+8|bc
register: user
- name: createuser
user: name={{user.stdout}}

传参方式的优先级

1
-e > playbook vars > hosts文件

setup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ansible_all_ipv4_addresses # ipv4的所有地址
ansible_all_ipv6_addresses # ipv6的所有地址
ansible_date_time # 获取到控制节点时间
ansible_default_ipv4 # 默认的ipv4地址
ansible_distribution # 系统
ansible_distribution_major_version # 系统的大版本
ansible_distribution_version # 系统的版本号
ansible_domain #系统所在的域
ansible_env #系统的环境变量
ansible_hostname #系统的主机名
ansible_fqdn #系统的全名
ansible_machine #系统的架构
ansible_memory_mb #系统的内存信息
ansible_os_family # 系统的家族
ansible_pkg_mgr # 系统的包管理工具
ansible_processor_cores #系统的cpu的核数(每颗)
ansible_processor_count #系统cpu的颗数
ansible_processor_vcpus #系统cpu的总个数=cpu的颗数*CPU的核数
ansible_python # 系统上的python
ansible cache -m setup -a 'filter=*processor*' # 用来搜索

* 匹配数量,表示0或者多次

? 匹配数量,表示0或者1次

. 除换行符以外的所有字符

+ 至少一次

[123abc] 匹配内容,or

() 分组

{m} 次数,出现m次

{m,} 至少m次

{m,n}出现m-n次

a*.b

1
2
3
4
5
6
7
8
- hosts: db
tasks:
- name: zzgbgn
dong: zzdbgn
when: zhanzhe
- name: pzhegbgn
dong: pzhedbgn
when: pazhe

条件判断

  • 不同的系统

  • 不同的版本

  • 不同的环境

  • 不同的用户

1
2
3
4
5
6
7
8
9
10
11
[root@7474265a0267 tmp]# ansible-playbook -e 'a=2' test.yml 

- hosts: db
remote_user: root
tasks:
- name: createfile
copy: content="大弦嘈嘈如急雨" dest=/tmp/a.txt
when: a=="3"
- name: cratefile
copy: content="小弦切切如私语" dest=/tmp/a.txt
when: a=="4"

tags

只执行tag标识的任务

1
2
3
4
5
6
7
- hosts: db
tasks:
- name: wadong
tieqiao: wadong
- name: tk
dong: tk
tags: tk
1
2
3
4
5
6
7
8
9
10
- hosts: web
tasks:
- name: installnginx
yum: name=nginx
- name: copyfile
copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf
tags: copyfile
- name: start
service: name=nginx state=started

1
ansible-playbook -t copyfile p7.yml 

循环 with_item

一次性创建多个txt文件

1
2
3
4
5
6
7
8
- hosts: web
tasks:
- name: out
shell: touch /tmp/{{item}}.txt
with_items:
- tony
- tiny
- caty

运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@7474265a0267 tmp]# ansible-playbook addmysql.yml
PLAY [web] ****************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************
ok: [172.17.0.3]

TASK [out] ****************************************************************************************************************************************
changed: [172.17.0.3] => (item=tony)
changed: [172.17.0.3] => (item=tiny)
changed: [172.17.0.3] => (item=caty)
[WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient
you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.


PLAY RECAP ****************************************************************************************************************************************
172.17.0.3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

测试查看:

1
2
3
4
5
6
[root@7225c5bf1567 tmp]# ls -l
total 4
-rw-r--r-- 1 root root 0 Oct 25 06:05 caty.txt
drwx------ 3 root root 4096 Oct 25 02:49 systemd-private-48a15306f1fa4d5b99624bd74a722301-nginx.service-GNMuXG
-rw-r--r-- 1 root root 0 Oct 25 06:05 tiny.txt
-rw-r--r-- 1 root root 0 Oct 25 06:05 tony.txt

创建多个用户且创建多个用户组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- hosts: web
tasks:
- name: crateuser
user: name={{item}}
with_items:
- alex30
- alex31
- alex32
- name: crategroup
group: name={{item}}
with_items:
- wulaoshi20
- wulaoshi21
- wulaoshi22
~

嵌套循环

创建多个用户和用户组,并将用户依次加入到对应用户组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- hosts: web
tasks:
- name: addgroup
group: name={{item}}
with_items:
- vs01
- vs02
- vs03
- name: adduser
user: name={{item.name}} group={{item.group}}
with_items:
- {'name':tony1, 'group':vs01}
- {'name':tony2, 'group':vs02}
- {'name':tony3, 'group':vs03}

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@7474265a0267 tmp]# ansible-playbook test.yml 

PLAY [web] ****************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************
ok: [172.17.0.3]

TASK [addgroup] ***********************************************************************************************************************************
changed: [172.17.0.3] => (item=vs01)
changed: [172.17.0.3] => (item=vs02)
changed: [172.17.0.3] => (item=vs03)

TASK [adduser] ************************************************************************************************************************************
changed: [172.17.0.3] => (item={u'group': u'vs01', u'name': u'tony1'})
changed: [172.17.0.3] => (item={u'group': u'vs02', u'name': u'tony2'})
changed: [172.17.0.3] => (item={u'group': u'vs03', u'name': u'tony3'})

PLAY RECAP ****************************************************************************************************************************************
172.17.0.3 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

测试

1
2
3
4
5
6
[root@7225c5bf1567 tmp]# id tony1
uid=1000(tony1) gid=1000(vs01) groups=1000(vs01)
[root@7225c5bf1567 tmp]# id tony2
uid=1001(tony2) gid=1001(vs02) groups=1001(vs02)
[root@7225c5bf1567 tmp]# id tony3
uid=1002(tony3) gid=1002(vs03) groups=1002(vs03)

template

应用场景:多用于批量复制配置文件到从机

创建模板文件

test.conf,就一句话显示当前主机名

1
MyHostName:{{ansible_hostname}}

修改yml文件

test.yml,将test.conf复制到目标主机中的dest.conf(模板复制)

1
2
3
4
- hosts: all
tasks:
- name: copytemp
template: src=/tmp/test.conf dest=/tmp/dest.conf

执行yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@7474265a0267 tmp]# ansible-playbook addmysql.yml 

PLAY [all] ****************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************
ok: [172.17.0.4]
ok: [172.17.0.3]

TASK [copytemp] ***********************************************************************************************************************************
changed: [172.17.0.3]
changed: [172.17.0.4]

PLAY RECAP ****************************************************************************************************************************************
172.17.0.3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
172.17.0.4 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

测试查看

172.17.0.3测试

1
2
[root@7225c5bf1567 tmp]# cat dest.conf
MyHostName:7225c5bf1567

172.17.0.4测试

1
2
[root@c5c6db1e6ac4 tmp]# cat dest.conf
MyHostName:c5c6db1e6ac4

copytamplate的区别

  • copy模块不替代参数

  • template模块替代参数

    yml文件中我们template项中的src我们使用了绝对路径,我们在当前目录创建一个templates文件夹,将test.conf放入其中,文件可改为以下,省略了绝对路径

1
2
3
4
- hosts: all
tasks:
- name: copytemp
template: src=test.conf dest=/tmp/dest.conf

handlers

我们以redis为例,我们需要将主机上的redis配置复制到从机上,从机redis配置文件修改后不会重启,需要我们来手动重启,这时候就用到了handlers,当前yml文件含义为如果执行到copyfle任务,notify代表着会触发restart任务,即:复制完配置文件要执行重启redis操作

1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: web
tasks:
- name: installredis
yum: name=redis
- name: copyfile
template: src=redis.conf dest=/etc/redis.conf
tags: copyfile
notify: restart
- name: start
service: name=redis state=started
handlers:
- name: restart
service: name=redis state=restarted

命令执行

该命令只执行copyfile任务

1
ansible-playbook -t copyfile test.yml

roles

  • 目录清晰
  • 可以互相调用

roles文件夹

文件夹里面是要创建的每一个角色,每一个角色一个文件夹

每一个角色里面都有tasks(必须的),templates,files,handlers,vars目录

每个目录都要有main.yml文件,通过import_tasks来调用

其中templates文件夹中的文件可以通过相对路径来调用

其中files文件夹中的文件是否可以通过相对路径来调用?