Fork me on GitHub

Ansible的高级用法之playbook和roles

playbook概念

playbook是由一个或多个“play” 组成的列表
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。 Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
Playbook采用YAML语言编写

YAML介绍

    YAML是一个可读性高的用来表达资料序列的格式。 YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。 Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者.

YAML Ain’t Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)

特性

  1. YAML的可读性好

  2. YAML和脚本语言的交互性好

  3. YAML使用实现语言的数据类型
  4. YAML有一个一致的信息模型
  5. YAML易于实现
  6. YAML可以基于流来处理
  7. YAML表达能力强,扩展性好

YAML语法简介

  • 在单一档案中,可用连续三个连字号(—)区分多个档案。另外,还有选择性的连续三个点号( … )用来表示档案结尾

  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能

  • 使用#号注释代码
  • 缩进必须是统一的,不能空格和tab混用
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
  • YAML文件内容是区别大小写的,k/v的值均需大小写敏感
  • k/v的值可同行写也可换行写。同行使用:分隔
  • v可是个字符串,也可是另一个列表
  • 一个完整的代码块功能需最少元素需包括 name: task
  • 一个name只能包括一个task
  • YAML文件扩展名通常为yml或yaml

List:列表,其所有元素均使用“-” 打头

示例:

1
2
3
4
5
6
# A list of tasty fruits  

- Apple
- Orange
- Strawberry
- Mango

Dictionary:字典,通常由多个key与value构成

示例:

1
2
3
4
5
---
# An employee record
name: Example Developer
job: Developer
skill: Elite

也可以将key:value放置于{}中进行表示,用,分隔多个key:value

示例:

1
2
3
---
# An employee record
{name: Example Developer, job: Developer, skill: Elite}

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用”-“来代表,Map里的键值对用”:”分隔
示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female

Playbook核心元素

  1. Hosts 执行的远程主机列表
  2. Tasks 任务集
  3. Varniables 内置变量或自定义变量在playbook中调用
  4. Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  5. Handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  6. tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。 ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
    1
    ansible-playbook –t tagsname useradd.yml

playbook基础组件

Hosts

    playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。 hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
可以是如下形式:

1
2
3
4
one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*

Websrvs:dbsrvs 或者,两个组的并集
Websrvs:&dbsrvs 与,两个组的交集
webservers:!phoenix 在websrvs组,但不在dbsrvs组
示例: - hosts: websrvs:dbsrvs

remote_user

    用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

1
2
3
4
5
6
7
8
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: magedu
sudo: yes 默认sudo为root
sudo_user:wang sudo为wang

task列表和action

    play的主体部分是task list。 task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出

tasks:任务列表

两种格式:

  • action: module arguments
  • module: arguments 建议使用
    注意:shell和command模块后面跟命令,而非key=value

任务可以通过”tags“打标签,可在ansible-playbook命令上使用-t指定进行调用
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的方式

ansible-playbook <filename.yml> … [options]

常见选项:
–check -C 只检测可能会发生的改变,但不真正执行操作
–list-hosts 列出运行任务的主机

1
2
3
4
5
6
7
8
9
[root@centos7 playbook]#ansible-playbook test.yml --list-hosts

playbook: test.yml

play #1 (appsrvs): appsrvs TAGS: []
pattern: [u'appsrvs']
hosts (2):
192.168.183.132
192.168.183.129

–list-tags 列出tag

1
2
3
4
5
6
[root@centos7 playbook]#ansible-playbook test.yml --list-tags  

playbook: test.yml

play #1 (appsrvs): appsrvs TAGS: []
TASK TAGS: []

–list-tasks 列出task

1
2
3
4
5
6
7
[root@centos7 playbook]#ansible-playbook test.yml --list-tasks
playbook: test.yml

play #1 (appsrvs): appsrvs TAGS: []
tasks:
first task TAGS: []
second task TAGS: []

–limit 主机列表 只针对主机列表中的主机执行

1
[root@centos7 playbook]#ansible-playbook test.yml --limit 192.168.183.129

-v -vv -vvv 显示过程

Playbook示例

安装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
30
31
32
33
34
35
36
37
38
[root@cetos7 ~]#vim /etc/ansible/hosts 

##[dbservers]

##db01.intranet.mydomain.net
##db02.intranet.mydomain.net
##10.25.1.56
##10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com

[appsrvs] #添加分组
192.168.183.132
192.168.183.129
~
"/etc/ansible/hosts" 50L, 1100C 47,0-1 Bot

[root@centos7 playbook]#vim httpd.yml
---
- hosts: appsrvs
remote_user: root
tasks:
- name: creat group
group: name=apache system=yes gid=80
- name: creat user
user: name=apache group=apache uid=80 shell=/sbin/nologin home=/usr/share/httpd system=yes password='$1$MrKn.0gj$CvMvkger.03UzBwQIrya.0'
- name: install package
yum: name=httpd
- name: config file
copy: src=/root/playbook/httpd.conf dest=/etc/httpd/conf/ backup=yes
- name: service
service: name=httpd state=started enabled=yes
~

[root@centos7 playbook]#ansible-playbook httod.yml

handlers和notify结合使用触发条件

Handlers
是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作
Notify
此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操 作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称handler,也即notify中调用handler中定义的操作

    如果httpd.conf文件内容修改了再运行一遍httpd.yml,只有config file发生改变,其他任务不会继续做了,所以把上述的playbook改写一下,加上notify和handlers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@centos7 playbook]#vim httpd.yml                
---
- hosts: appsrvs
remote_user: root
tasks:
- name: creat group
group: name=apache system=yes gid=80
- name: creat user
user: name=apache group=apache uid=80 shell=/sbin/nologin home=/usr/share/httpd system=yes password='$1$MrKn.0gj$CvMvkger.03UzBwQIrya.0'
- name: install package
yum: name=httpd
- name: config file
copy: src=/root/playbook/httpd.conf dest=/etc/httpd
notify: restart service
/conf/ backup=yes
- name: service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restart
[root@centos7 playbook]#ansible-playbook httod.yml
如果我们httpd端口80 改成8080,再运行一遍`ansible-playbook`时,这时就只会触发重启httpd服务

Playbook中tags使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@centos7 playbook]#vim httpd.yml                
---
- hosts: appsrvs
remote_user: root
tasks:
- name: creat group
group: name=apache system=yes gid=80
- name: creat user
user: name=apache group=apache uid=80 shell=/sbin/nologin home=/usr/share/httpd system=yes password='$1$MrKn.0gj$CvMvkger.03UzBwQIrya.0'
- name: install package
yum: name=httpd
tags: install
- name: config file
copy: src=/root/playbook/httpd.conf dest=/etc/httpd
tags: config
notify: restart service
/conf/ backup=yes
- name: service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restart

给playbook打上tags我们就可以单独的执行tags的那部分tasks

[root@centos7 playbook]#ansible-playbook -t install httpd.yml 仅仅执行了安装httpd

Playbook中变量使用

变量来源:

  1. ansible setup facts 远程主机的所有变量都可直接调用
  2. 在/etc/ansible/hosts中定义

    普通变量:主机组中主机单独定义,优先级高于公共变量
    公共(组)变量:针对主机组中所有主机定义统一变量

  3. 通过命令行指定变量,优先级最高

    ansible-playbook –e varname=value

  4. 在playbook中定义

    1
    2
    3
    vars:
    - var1: value1
    - var2: value2
  5. 在独立的变量YAML文件中定义

  6. 在role中定义

变量命名

变量名仅能由字母、数字和下划线组成,且只能以字母开头

变量定义:key=value

示例:http_port=80

变量调用方式

通过 调用变量,且变量名前后必须有空格,有时用“”才生效

ansible-playbook –e 选项指定

1
ansible-playbook test.yml -e “hosts=www user=magedu”

示例

使用setup变量

示例:var.yml

1
2
3
4
5
6
7
- hosts: websrvs
remote_user: root

tasks:
- name: create log file
file: name=/var/log/ {{ ansible_fqdn }} state=touch
ansible-playbook var.yml

变量

示例:var.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: websrvs
remote_user: root
vars:
- username: user1
- groupname: group1

tasks:
- name: create group
group: name={{ groupname }} state=present
- name: create user
user: name={{ username }} state=present
ansible-playbook var.yml
ansible-playbook -e "username=user2 groupname=group2” var2.yml

  1. 主机变量

可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用
示例:

1
2
3
[websrvs]
www1.magedu.com http_port=80 maxRequestsPerChild=808
www2.magedu.com http_port=8080 maxRequestsPerChild=909

  1. 组变量

组变量是指赋予给指定组内所有主机上的在playbook中可用的变量
示例:

1
2
3
4
5
6
[websrvs]
www1.magedu.com
www2.magedu.com
[websrvs:vars]
ntp_server=ntp.magedu.com
nfs_server=nfs.magedu.com

  1. 普通变量

    1
    2
    3
    [websrvs]
    192.168.99.101 http_port=8080 hname=www1
    192.168.99.102 http_port=80 hname=www2
  2. 公共(组)变量

    1
    2
    3
    4
    5
    6
    7
    [websvrs:vars]
    http_port=808
    mark=“_”
    [websrvs]
    192.168.99.101 http_port=8080 hname=www1
    192.168.99.102 http_port=80 hname=www2
    ansible websvrs –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'
  3. 命令行指定变量:

    1
    ansible websvrs –e http_port=8000 –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'

模板templates

  1. 文本文件,嵌套有脚本(使用模板编程语言编写)
  2. Jinja2语言,使用字面量,有下面形式

    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1, item2, …]
    元组:(item1, item2, …)
    字典:{key1:value1, key2:value2, …}
    布尔型:true/false
    算术运算:+, -, *, /, //, %, **
    比较操作:==, !=, >, >=, <, <=
    逻辑运算:and, or, not
    流表达式:For If When

  3. templates功能:根据模块文件动态生成对应的配置文件

  4. templates文件必须存放于templates目录下,且命名为 .j2 结尾
  5. yaml/yml 文件需和templates目录平级,目录结构如下:

    1
    2
    3
    4
    ./
    ├── temnginx.yml
    └── templates
    └── nginx.conf.j2
  6. Playbook中template变更替换

  7. Playbook中template算术运算

Templates示例

利用templates 同步nginx配置文件,并修改配置文件nginx.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
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
[root@centos7 playbook]#mkdir templates
[root@centos7 playbook]#mv nginx.conf templates/nginx.conf.j2
[root@centos7 playbook]#tree
.
├── test_templ.yml
├── templates
└── nginx.conf.j2
[root@centos7 playbook]#vim test_templ.yml
---
- hosts: appsrvs
remote_user: root

tasks:
- name: install
yum: name=nginx
- name: template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart
- name: service
service: name=nginx state=started enabled=yes
handlers:
- name: restart
service: name=nginx state=restarted

[root@centos7 playbook]#ansible-playbook test_templ.yml
.........省略结果
[root@centos7 playbook]#ansible appsrvs -a 'ss -ntlp' #查看80端口是否开启
[root@centos7 playbook]#ansible appsrvs -m shell -a 'ps axu | grep nginx'
192.168.183.137 | CHANGED | rc=0 >>
root 16688 0.0 0.1 120812 2228 ? Ss 21:15 0:00 nginx: master process /usr/sbin/nginx
nginx 16689 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
nginx 16690 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
root 16755 0.0 0.0 113172 1196 pts/1 S+ 21:15 0:00 /bin/sh -c ps axu | grep nginx
root 16757 0.0 0.0 112704 940 pts/1 S+ 21:15 0:00 grep nginx
192.168.183.136 | CHANGED | rc=0 >>
root 18759 0.0 0.1 122924 2100 ? Ss 20:46 0:00 nginx: master process /usr/sbin/nginx
nginx 18760 0.0 0.1 125472 3540 ? S 20:46 0:00 nginx: worker process
root 36053 0.0 0.0 113128 1196 pts/1 S+ 21:15 0:00 /bin/sh -c ps axu | grep nginx
root 36055 0.0 0.0 112664 948 pts/1 S+ 21:15 0:00 grep nginx
[root@centos7 playbook]#ansible appsrvs -m shell -a 'ps axu | grep nginx'
192.168.183.137 | CHANGED | rc=0 >>
root 16688 0.0 0.1 120812 2228 ? Ss 21:15 0:00 nginx: master process /usr/sbin/nginx
nginx 16689 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
nginx 16690 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
root 16755 0.0 0.0 113172 1196 pts/1 S+ 21:15 0:00 /bin/sh -c ps axu | grep nginx
root 16757 0.0 0.0 112704 940 pts/1 S+ 21:15 0:00 grep nginx

192.168.183.136 | CHANGED | rc=0 >>
root 18759 0.0 0.1 122924 2100 ? Ss 20:46 0:00 nginx: master process /usr/sbin/nginx
nginx 18760 0.0 0.1 125472 3540 ? S 20:46 0:00 nginx: worker process
root 36053 0.0 0.0 113128 1196 pts/1 S+ 21:15 0:00 /bin/sh -c ps axu | grep nginx
root 36055 0.0 0.0 112664 948 pts/1 S+ 21:15 0:00 grep nginx

[root@centos7 playbook]#ansible appsrvs -m setup -a 'filter=ansible_processor_count'
192.168.183.136 | SUCCESS => {
"ansible_facts": {
"ansible_processor_count": 1
},
"changed": false
}
192.168.183.137 | SUCCESS => {
"ansible_facts": {
"ansible_processor_count": 2
},
"changed": false
}

worker process 与 CPU数量一致

[root@centos7 playbook]#vim templates/nginx.conf.j2
.....省略.....
worker_processes {{ ansible_processor_count*2 }}; #Playbook中template算术运算
.....省略.....
[root@centos7 playbook]#ansible appsrvs -m shell -a 'ps axu | grep nginx'
192.168.183.136 | CHANGED | rc=0 >>
root 18759 0.0 0.1 122924 2100 ? Ss 20:46 0:00 nginx: master process /usr/sbin/nginx
nginx 18760 0.0 0.1 125472 3540 ? S 20:46 0:00 nginx: worker process
nginx 18761 0.0 0.1 125472 3540 ? S 20:46 0:00 nginx: worker process
root 36485 0.0 0.0 113128 1196 pts/1 S+ 21:36 0:00 /bin/sh -c ps axu | grep nginx
root 36487 0.0 0.0 112664 944 pts/1 S+ 21:36 0:00 grep nginx

192.168.183.137 | CHANGED | rc=0 >>
root 16688 0.0 0.1 120812 2228 ? Ss 21:15 0:00 nginx: master process /usr/sbin/nginx
nginx 16689 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
nginx 16690 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
nginx 16691 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
nginx 16692 0.0 0.1 123360 3524 ? S 21:15 0:00 nginx: worker process
root 17220 0.0 0.0 113172 1200 pts/1 S+ 21:36 0:00 /bin/sh -c ps axu | grep nginx
root 17222 0.0 0.0 112704 940 pts/1 S+ 21:36 0:00 grep nginx

when

    条件测试:如果需要根据变量、 facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法
格式

when语句
在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法
示例:

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
[root@centos7 playbook]#tree templates/
templates/
├── httpd6.conf.j2
└── httpd7.conf.j2

[root@centos7 playbook]#vim httpd.yml
---
- hosts: appsrvs
remote_user: root
tasks:
- name: install
yum: name=httpd
- name: template1
template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version=="6"
notify: restart
- name: template2
template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version=="7"
notify: restart
- name: service
service: name=httpd state=started enabled=yes
handlers:
- name: restart
service: name=httpd state=restart

迭代:with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制

对迭代项的引用,固定变量名为”item”
要在task中使用with_items给定要迭代的元素列表
列表格式:

字符串
字典

示例:

1
2
3
4
5
- name: add several users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2

迭代嵌套子变量
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- hosts:websrvs
remote_user: root
tasks:
- name: add groups
group: name={{ item }}
with_items:
- group1
- group2
- group3
- name: add users
user: name={{ item.name }} group={{ item.group }}
with_items:
- { name: 'user1', group: 'group1' }
- { name: 'user2', group: 'group2' }
- { name: 'user3', group: 'group3' }

roles

    ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

复杂场景:建议使用roles,代码复用度高

变更指定主机或主机组
如命名不规范维护和传承成本大
某些功能需多个Playbook,通过includes即可实现

角色(roles):角色集合

roles/
mysql/
httpd/
nginx/
memcached/

roles目录结构

每个角色,以特定的层级目录结构进行组织
roles目录结构:

playbook.yml
roles/
project/
tasks/
files/
vars/
templates/
handlers/
default/ 不常用
meta/ 不常用

Roles各目录作用

/roles/project/ :项目名称,有以下子目录
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文件

创建role

创建role的步骤

  1. 创建以roles命名的目录
  2. 在roles目录中分别创建以各角色名称命名的目录,如webservers等
  3. 在每个角色命名的目录中分别创建files、 handlers、 meta、 tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建
  4. 在playbook文件中,调用各角色

针对大型项目使用Roles进行编排

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
[root@centos7 playbook]#mkdir roles
[root@centos7 playbook]#mkdir roles/httpd
[root@centos7 playbook]#tree roles/
roles/
└── httpd

1 directories, 0 files
[root@centos7 playbook]#mkdir roles/httpd/{files,tasks,templates,handlers,vars}
[root@centos7 playbook]#tree roles/
roles/
└── httpd
├── files
├── handlers
├── tasks
├── templates
└── vars

6 directories, 0 files
[root@centos7 playbook]#cd roles/httpd/
[root@centos7 httpd]#tree
.
├── files
├── handlers
├── tasks
├── templates
└── vars

5 directories, 0 files
[root@centos7 httpd]#cd tasks/
[root@centos7 tasks]#touch user.yml group.yml config.yml install.yml service.yml
[root@centos7 tasks]#vim group.yml
- name: useradd group
group: name=apache system=yes gid=80

[root@centos7 tasks]#vim user.yml
- name: useradd user
user: name=apache group=apache shell=/sbin/nologin home=/usr/share/httpd system=yes

[root@centos7 tasks]#vim install.yml
- name: install package
yum: name=httpd

[root@centos7 tasks]#vim config.yml
- name: config file
copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes notify: restart

[root@centos7 tasks]#vim service.yml
- name: service
service: name=httpd state=started enabled=yes

[root@centos7 tasks]#ll
total 20
-rw-r--r-- 1 root root 76 Nov 24 00:41 config.yml
-rw-r--r-- 1 root root 61 Nov 24 00:30 group.yml
-rw-r--r-- 1 root root 42 Nov 24 00:39 install.yml
-rw-r--r-- 1 root root 62 Nov 24 00:42 service.yml
-rw-r--r-- 1 root root 107 Nov 24 00:34 user.yml

[root@centos7 tasks]#vim main.yml
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: service.yml

[root@centos7 tasks]#cd ..

[root@centos7 httpd]#vim handlers/main.yml
- name: restart
service: name=httpd state=restarted

[root@centos7 httpd]#cp /etc/httpd/conf/httpd.conf files/
[root@centos7 httpd]#tree
.
├── files
│ └── httpd.conf
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── group.yml
│ ├── install.yml
│ ├── main.yml
│ ├── service.yml
│ └── user.yml
├── templates
└── vars

5 directories, 8 files


[root@centos7 httpd]#cd ../../
[root@centos7 playbook]#vim httpd_roles.yml
---
- hosts: appsrvs
remote_user: root

roles:
- role: httpd
[root@centos7 playbook]#ansible-playbook httpd_roles.yml

把httpd的文件复制一份到nginx里,然后改改

[root@centos7 roles]#cp -r httpd/ nginx/
[root@centos7 roles]#tree
.
├── httpd
│ ├── files
│ │ └── httpd.conf
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── config.yml
│ │ ├── group.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── service.yml
│ │ └── user.yml
│ ├── templates
│ └── vars
└── nginx
├── files
│ └── httpd.conf
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── group.yml
│ ├── install.yml
│ ├── main.yml
│ ├── service.yml
│ └── user.yml
├── templates
└── vars

12 directories, 16 files
[root@centos7 roles]#cd nginx/
[root@centos7 nginx]#tree
.
├── files
│ └── httpd.conf
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── group.yml
│ ├── install.yml
│ ├── main.yml
│ ├── service.yml
│ └── user.yml
├── templates
└── vars

5 directories, 8 files
[root@centos7 nginx]#rm -f tasks/{group,user}.yml
[root@centos7 nginx]#tree
.
├── files
│ └── httpd.conf
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── install.yml
│ ├── main.yml
│ └── service.yml
├── templates
└── vars

5 directories, 6 files
[root@centos7 nginx]#cp /etc/nginx/nginx.conf templates/nginx.conf.j2
[root@centos7 nginx]#tree
.
├── files
│ └── httpd.conf
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── install.yml
│ ├── main.yml
│ └── service.yml
├── templates
│ └── nginx.conf.j2
└── vars

5 directories, 7 files
[root@centos7 nginx]#cd tasks/
[root@centos7 tasks]#tree
.
├── config.yml
├── install.yml
├── main.yml
└── service.yml

0 directories, 4 files
[root@centos7 tasks]#vim config.yml
- name: config file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart

[root@centos7 tasks]#vim install.yml
- name: install package
yum: name=nginx

[root@centos7 tasks]#vim main.yml
- include: install.yml
- include: config.yml
- include: service.yml

[root@centos7 tasks]#vim service.yml
- name: service
service: name=nginx state=started enabled=yes

[root@centos7 tasks]#cd ../../../
[root@centos7 playbook]#vim nginx_roles.yml
- hosts: appsrvs
remote_user: root

roles:
- role: nginx

[root@centos7 playbook]#ansible-playbook nginx_roles.yml
---------------- The End ----------------
坚持原创技术分享,您的支持将鼓励我继续创作!