Ansible学习笔记--roles

roles

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

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

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

角色(roles):角色集合

1
2
3
4
5
6
7
mkdir roles/{mysql,httpd,nginx,memcache} -pv 
tree roles
roles/
mysql/
httpd/
nginx/
memcached/

基于ansible roles 安装 nginx

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
# 环境准备,清除已安装的nginx和用户组
ansible internal -m shell -a 'yum -y remove nginx' -b
ansible internal -m shell -a 'rpm -q nginx'
ansible internal -m shell -a 'getent passwd nginx'
ansible internal -m shell -a 'getent group nginx'
ansible internal -m user -a 'name=nginx state=absent' -b

# 开始
cd ansible/ # 根目录
cd roles/nginx # 项目文件夹

[ec2-user@master ansible]$ tree
.
├── nginx_role.yml # 调用文件
└── roles
├── httpd
├── memcached
├── mysql
└── nginx
├── tasks # 在该文件下创建多个任务
│ ├── group.yml
│ ├── main.yml # 入口文件
│ ├── restart.yml
│ ├── start.yml
│ ├── template.yml
│ ├── user.yml
│ └── yum.yml
└── templates # 创建配置文件的j2模板
└── nginx.conf.j2

mkdir tasks templates # 创建两个常用文件夹
cd tasks
vi main.yml # 入口
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: start.yml

vi group.yml
- name: create group
group: name=nginx gid=80

vi user.yml
- name: create user
user: name=nginx uid=80 group=nginx system=yes shell=/sbin/nologin

vi yum.yml
- name: install package
yum: name=nginx

vi template.yml
- name: copy conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

vi start.yml
- name: start service
service: name=nginx state=started enabled=yes

cd ../../../
vi nginx_role.yml
---
- hosts: internal
remote_user: ec2-user
become: yes
roles:
- role: nginx

ansible-playbook -C nginx_role.yml # 检查再执行

rpm -qa nginx # 查看系统是否有这个安装包
ansible internal -m shell -a 'ss -ntlp' # 可查看到80端口
ansible internal -m shell -a 'ps aux|grep nginx' # 查看进程
```


## roles目录结构
可以互相调用,roles目录结构,每个角色,以特定的层级目录结构进行组织

playbook.yml 调用角色
roles/
project/ (角色名称)
tasks/
files/
vars/
templates/
handlers/
default/ 不常用
meta/ 不常用

1
## 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文件

1
roles/appname 目录结构
tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;
           此文件可以使用include包含其它的位于此目录中的task文件
files目录:存放由copy或script等模块调用的文件;
templates目录:template模块会自动在此目录中寻找Jinja2模板文件
handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;
              在handler中使用include包含的其它的handler文件也应该位于此目录中;
vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;
          ansible1.3及其以后的版本才支持;
default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件
1
2
3
4
5
6
7
```
roles/example_role/files/ 所有文件,都将可存放在这里
roles/example_role/templates/ 所有模板都存放在这里
roles/example_role/tasks/main.yml: 主函数,包括在其中的所有任务将被执行
roles/example_role/handlers/main.yml:所有包括其中的 handlers 将被执行
roles/example_role/vars/main.yml: 所有包括在其中的变量将在roles中生效
roles/example_role/meta/main.yml: roles所有依赖将被正常登入

创建role

创建role的步骤

  • 创建以roles命名的目录
  • 在roles目录中分别创建以各角色名称命名的目录,如webservers等
  • 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建
  • 在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
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
1> 创建roles目录
mkdir roles/{httpd,mysql,redis}/tasks -pv
mkdir roles/httpd/{handlers,files}

查看目录结构
tree roles/
roles/
├── httpd
│ ├── files
│ ├── handlers
│ └── tasks
├── mysql
│ └── tasks
└── redis
└── tasks

2> 创建目标文件
cd roles/httpd/tasks/
touch install.yml config.yml service.yml

3> vim install.yml
- name: install httpd package
yum: name=httpd

vim config.yml
- name: config file
copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes

vim service.yml
- name: start service
service: name=httpd state=started enabled=yes

4> 创建main.yml主控文件,调用以上单独的yml文件,
main.yml定义了谁先执行谁后执行的顺序
vim main.yml
- include: install.yml
- include: config.yml
- include: service.yml

5> 准备httpd.conf文件,放到httpd单独的文件目录下
cp /app/ansible/flies/httpd.conf ../files/

6> 创建一个网页
vim flies/index.html
<h1> welcome to weixiaodong home <\h1>

7> 创建网页的yml文件
vim tasks/index.yml
- name: index.html
copy: src=index.html dest=/var/www/html

8> 将网页的yml文件写进mian.yml文件中
vim mian.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml

9> 在handlers目录下创建handler文件mian.yml
vim handlers/main.yml
- name: restart service httpd
service: name=httpd state=restarted

10> 创建文件调用httpd角色
cd /app/ansidle/roles
vim role_httpd.yml
---
# httpd role
- hosts: appsrvs
remote_user: root

roles: #调用角色
- role: httpd

11> 查看目录结构
tree
.
httpd
├── files
│ ├── httpd.conf
│ └── index.html
├── handlers
│ └── main.yml
└── tasks
├── config.yml
├── index.yml
├── install.yml
├── main.yml
└── service.yml

12> ansible-playbook role_httpd.yml
针对大型项目使用Roles进行编排
roles目录结构:
playbook.yml
roles/
project/
tasks/
files/
vars/
templates/
handlers/
default/ # 不经常用
meta/ # 不经常用

示例:
nginx-role.yml
roles/
└── nginx
├── files
│ └── main.yml
├── tasks
│ ├── groupadd.yml
│ ├── install.yml
│ ├── main.yml
│ ├── restart.yml
│ └── useradd.yml
└── vars
└── main.yml
示例
roles的示例如下所示:
site.yml
webservers.yml
dbservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
meta/
实验: 创建一个nginx角色
建立nginx角色在多台主机上来部署nginx需要安装 创建账号
1> 创建nginx角色目录
cd /app/ansible/role
mkdir nginx{tesks,templates,hanslers} -pv

2> 创建任务目录
cd tasks/
touch insatll.yml config.yml service.yml file.yml user.yml
创建main.yml文件定义任务执行顺序
vim main.yml
- include: user.yml
- include: insatll.yml
- include: config.yml
- include: file.yml
- include: service.yml


3> 准备配置文件(centos7、8)
ll /app/ansible/role/nginx/templates/
nginx7.conf.j2
nginx8.conf.j2


4> 定义任务
vim tasks/install.yml
- name: install
yum: name=nginx

vim tasks/config.yml
- name: config file
template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version=="7"
notify: restrat

- name: config file
template: src=nginx8.conf.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version=="8"
notify: restrat

vim tasks/file.yml 跨角色调用file.yum文件,实现文件复用
- name: index.html
copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/

vim tasks/service.yml
- nmae: start service
service: name=nginx state=started enabled=yes

vim handlers/main.yml
- name: restrat
service: name=nginx state=restarted

vim roles/role_nginix.yml
---
#test rcle
- hosts: appsrvs

roles:
- role: nginx

5> 测试安装
ansible-playbook role_nginx.yml

playbook调用角色

调用角色方法1:

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

roles:
- mysql
- memcached
- nginx

调用角色方法2:传递变量给角色

1
2
3
4
5
6
7
- hosts:
remote_user:
roles:
- mysql
- { role: nginx, username: nginx } #不同的角色调用不同的变量
键role用于指定角色名称
后续的k/v用于传递变量给角色

调用角色方法3:还可基于条件测试实现角色调用

1
2
roles:
- { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }

通过roles传递变量

当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量

示例:

1
2
3
4
- hosts: webservers
roles:
- common
- { role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080 }

向roles传递参数

而在playbook中,可以这样使用roles:

1
2
3
4
5
---
- hosts: webservers
roles:
- common
- webservers

也可以向roles传递参数,示例:

1
2
3
4
5
6
---
- hosts: webservers
roles:
- common
- { role: foo_app_instance, dir: '/opt/a', port: 5000 }
- { role: foo_app_instance, dir: '/opt/b', port: 5001 }

条件式地使用roles

示例:

1
2
3
4
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'" }

Roles条件及变量等案例

1
2
3
4
5
6
7
8
9
10
# When条件
roles:
- {role: nginx, when: "ansible_distribution_major_version == '7' " ,username: nginx }
# 变量调用

- hosts: zabbix-proxy
sudo: yes
roles:
- { role: geerlingguy.php-mysql }
- { role: dj-wasabi.zabbix-proxy, zabbix_server_host: 192.168.37.167 }

完整的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
# nginx-role.yml 顶层任务调用yml文件
---
- hosts: testweb
remote_user: root
roles:
- role: nginx
- role: httpd 可执行多个role

cat roles/nginx/tasks/main.yml
---
- include: groupadd.yml
- include: useradd.yml
- include: install.yml
- include: restart.yml
- include: filecp.yml

# roles/nginx/tasks/groupadd.yml
---
- name: add group nginx
user: name=nginx state=present

cat roles/nginx/tasks/filecp.yml
---
- name: file copy
copy: src=tom.conf dest=/tmp/tom.conf

#以下文件格式类似:
useradd.yml,install.yml,restart.yml

ls roles/nginx/files/
tom.conf

roles playbook tags使用

1
2
3
4
5
6
7
8
9
10
11
12
ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml #对标签进行挑选执行

# nginx-role.yml
---
- hosts: testweb
remote_user: root
roles:
- { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6“ }
- { role: httpd ,tags: [ 'httpd', 'web' ] }
- { role: mysql ,tags: [ 'mysql', 'db' ] }
- { role: marridb ,tags: [ 'mysql', 'db' ] }
- { role: php }

实验: 创建角色memcached

memcacched 当做缓存用,会在内存中开启一块空间充当缓存

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
cat /etc/sysconfig/memcached 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64" # 缓存空间默认64M
OPTIONS=""


1> 创建对用目录
cd /app/ansible
mkdir roles/memcached/{tasks,templates} -pv

2> 拷贝memcached配置文件模板
cp /etc/sysconfig/memcached templates/memcached.j2
vim templates/memcached.j2
CACHESIZE="{{ansible_memtotal_mb//4}}" #物理内存的1/4用做缓存

3> 创建对应yml文件,并做相应配置
cd tasks/
touch install.yml config.yml service.yml
创建main.yml文件定义任务执行顺序
vim main.yml
- include: install.yml
- include: config.yml
- include: service.yml

vim install.yml
- name: install
yum: name=memcached

vim config.yml
- name: config file
template: src=memcached.j2 dets=/etc/sysconfig/memcached

vim service.yml
- name: service
service: name=memcached state=started enabled=yes

4> 创建调用角色文件
cd /app/ansible/roles/
vim role_memcached.yml
---
- hosts: appsrvs

roles:
- role: memcached

5> 安装
ansible-playbook role_memcached.yml
memcached端口号11211

其它功能

  • 委任(指定某一台机器做某一个task)
    • delegate_to
    • local_action (专指针对ansible命令执行的机器做的变更操作)
  • 交互提示
    • prompt
  • *暂停(java)
    • wait_for
  • Debug
    • debug: msg=”This always executes.”
  • Include
  • Template 多值合并
  • Template 动态变量配置

Ansible Roles

  • 委任
    • delegate_to
  • 交互提示
    • prompt
  • 暂停
    • wait_for
  • Debug
    • debug: msg=”This always executes.”
  • Include
  • Template 多值合并
  • Template 动态变量配置

推荐资料

1
2
3
4
5
6
http://galaxy.ansible.com
https://galaxy.ansible.com/explore#/
http://github.com/
http://ansible.com.cn/
https://github.com/ansible/ansible
https://github.com/ansible/ansible-examples

实验: 实现二进制安装mysql的卸载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat remove_mysql.yml 
---
# install mariadb server
- hosts: appsrvs:!192.168.38.108
remote_user: root

tasks:
- name: stop service
shell: /etc/init.d/mysqld stop
- name: delete user
user: name=mysql state=absent remove=yes
- name: delete
file: path={{item}} state=absent
with_items:
- /usr/local/mysql
- /usr/local/mariadb-10.2.27-linux-x86_64
- /etc/init.d/mysqld
- /etc/profile.d/mysql.sh
- /etc/my.cnf
- /data/mysql

ansible-playbook remove_mysql.yml