04.2 playbooks roles
本文参考:https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
1. 目录结构⚓
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
- tasks:包含主要的被执行的tasks列表
- handlers:包含可以被所有的roles使用的handlers
- defaults:对于这个role来说的默认变量
- vars:对于这个role来说的其它变量
- files:包含可以被这个role部署的文件
- templates:包含可以被这个role部署的模版文件(遵循Jinja2规范)
- meta:定义这个role的一些元数据
2. 使用 roles⚓
在 playbook 文件中编写:
---
- hosts: webservers
roles:
- common
- webservers
这为每个角色x
指定了以下行为:
- 若存在
roles/x/tasks/main.yml
,会将其中的 tasks 加入到 play 中 roles/x/handlers/main.yml
,加入roles/x/vars/main.yml
,加入roles/x/defaults/main.yml
,加入roles/x/meta/main.yml
,加入roles/x/{files,templates,tasks}/
中的文件可以被copy、script、template
或此role中导入的tasks都可以被引用。无需写相对或绝对路径。
playbook 的执行顺序:
- 在 play 中定义的任何
pre_tasks
。 - 运行迄今为止被触发的 handlers。
- 依次执行
roles
中的每个 role。在meta/main.yml
中依赖的 role 会先被运行,受标签过滤和条件限制。 - 任何在play中定义的
tasks
。 - 运行迄今为止被触发的 handlers。
- 在play中定义的任何
post_tasks
。 - 运行迄今为止被触发的 handlers。
从 2.4 开始,可以使用 import_role
or include_role
来与其他 tasks 一起工作:
---
- hosts: webservers
tasks:
- debug:
msg: "before we run our role"
- import_role:
name: example
- include_role:
name: example
- debug:
msg: "after we ran our role"
2.1 Role 的搜索路径⚓
- 相对于 playbook 文件的
roles/
文件夹; - 默认的
/etc/ansible/roles/
文件夹。
可以设置环境变量 ANSIBLE_ROLES_PATH
来指定 role 的路径,或者在配置文件/etc/ansible/ansible.cfg
中设置roles_path
变量。可以指定多个roles目录,使用冒号分隔即可。
[root@dev playbooks]# cat /etc/ansible/ansible.cfg | grep roles_path
roles_path = /usr/share/ansible/playbooks/roles:/etc/ansible/roles
2.2 导入 role⚓
role 的名字可以是一个简单的名字或者是完整的路径:
---
- hosts: webservers
roles:
- common
# or
- role: '/path/to/my/roles/common'
roles 也能接收其他的关键字:
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
或者使用最新的语法:
---
- hosts: webservers
tasks:
- include_role:
name: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
...
还可以有条件地导入 role 并执行其 tasks:
---
- hosts: webservers
tasks:
- include_role:
name: some_role
when: "ansible_facts['os_family'] == 'RedHat'"
2.3 为 role 中的 tasks 分配 tags⚓
tags 被分配给 tasks ,用途是可以只执行一部分 tasks。
---
- hosts: webservers
roles:
- role: foo
tags:
- bar
- baz
# using YAML shorthand, this is equivalent to the above:
- { role: foo, tags: ["bar", "baz"] }
最新语法:
---
- hosts: webservers
tasks:
- import_role:
name: foo
tags:
- bar
- baz
注意:没有在导入 roles 的时候就指定执行的 tags 的功能。
2.4 Role 的重复定义与执行⚓
在一个 play 中,即使多次定义一个 role,也只会执行一次。例如:
---
- hosts: webservers
roles:
- foo
- foo
有两种方式可以达成多次执行的目的:
- 在每个 role 定义时传递不同的参数;
- 在
meta/main.yml
文件中添加allow_duplicates: true
。
例1:
---
- hosts: webservers
roles:
- role: foo
vars:
message: "first"
- { role: foo, vars: { message: "second" } }
例2:
# playbook.yml
---
- hosts: webservers
roles:
- foo
- foo
# roles/foo/meta/main.yml
---
allow_duplicates: true
2.5 Role 默认变量⚓
默认变量允许你在导入(included)和依赖(dependent)时设置默认变量。这些变量拥有最低的权限,可以被任何其它类型的变量或 inventory 的变量覆盖。
编写defaults/main.yml
即可创建默认变量。
2.6 Role 依赖⚓
role 的依赖在 meta/main.yml
文件中定义,只能使用经典语法进行定义:
# roles/myapp/meta/main.yml
---
dependencies:
- role: common
vars:
some_parameter: 3
- role: apache
vars:
apache_port: 80
- role: postgres
vars:
dbname: blarg
other_parameter: 12
role 的依赖总是在导入地 role 之前被递归地执行。依赖也遵循上文中提到地重复定义规则。
Important
当你使用 allow_duplicates: true
时,它需要在被依赖的 role 中配置。
2.6.1 例子⚓
car依赖wheel:
# roles/car/meta/main.yml
---
dependencies:
- role: wheel
vars:
n: 1
- role: wheel
vars:
n: 2
wheel依赖tire与brake:
# roles/wheel/meta/main.yml
---
dependencies:
- role: tire
- role: brake
tire与brake配置可重复定义:
# roles/{tire,brake}/meta/main.yml
---
allow_duplicates: true
执行结果:
tire(n=1)
brake(n=1)
wheel(n=1)
tire(n=2)
brake(n=2)
wheel(n=2)
...
car
3. playbook 例子⚓
3.1 使用普通的 playbook 文件⚓
目录结构:
[root@linux files]# tree
.
├── rpms
│ ├── qemu-kvm-ev-2.3.0-31.x86_64.rpm
│ └── qemu-kvm-tools-ev-2.3.0-31.x86_64.rpm
└── upgrade-nodes.yml
playbook文件:
[root@linux playbooks]# cat upgrade-nodes.yml
---
- hosts: nodes
tasks:
- name: remove rpms firstly
file:
state: absent
path: /root/test/rpm/
- name: copy rpms to nodes
copy:
src: rpms/
dest: /root/test/rpm/
notify:
- list rpms
handlers:
- name: list rpms
command: ls -l /root/test/rpm/
3.2 使用 roles 结构⚓
inventory文件:
[root@linux playbooks]# cat /etc/ansible/hosts
[nodes]
192.168.216.41
192.168.216.42
目录结构:
[root@linux playbooks]# pwd
/usr/share/ansible/playbooks
[root@linux playbooks]# tree .
.
├── roles
│ └── upgrade-nodes
│ ├── files
│ │ └── rpms
│ │ ├── qemu-kvm-ev-2.3.0-31.x86_64.rpm
│ │ └── qemu-kvm-tools-ev-2.3.0-31.x86_64.rpm
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
└── upgrade-nodes.yml
playbook文件:
[root@linux playbooks]# cat upgrade-nodes.yml
---
- hosts: nodes
roles:
- upgrade-nodes
tasks文件:
[root@linux playbooks]# cat roles/upgrade-nodes/tasks/main.yml
---
- name: remove rpms firstly
file:
state: absent
path: /root/test/rpm/
- name: copy rpms to nodes
copy:
src: rpms/
dest: /root/test/rpm/
notify:
- list rpms
handlers文件:
[root@linux playbooks]# cat roles/upgrade-nodes/handlers/main.yml
- name: list rpms
command: ls -l /root/test/rpm/
使用-C
选项时,可能不会触发handlers。