Ansible Galaxy:集合和角色¶
在本章中,您将学习如何使用、安装和管理 Ansible 角色和集合。
目标:在本节中,您将学习如何
安装和管理集合。
安装和管理角色。
ansible、ansible-galaxy、roles、collections
知识:
复杂度:
阅读时间:40 分钟
Ansible Galaxy 提供来自 Ansible 社区的 Ansible 角色和集合。
提供的元素可以在剧本中引用,并开箱即用。
ansible-galaxy
命令¶
ansible-galaxy
命令使用 galaxy.ansible.com 管理角色和集合。
- 要管理角色
ansible-galaxy role [import|init|install|login|remove|...]
子命令 | 功能 |
---|---|
安装 | 安装角色。 |
删除 | 删除一个或多个角色。 |
列表 | 显示已安装角色的名称和版本。 |
信息 | 显示有关角色的信息。 |
初始化 | 生成新角色的骨架。 |
导入 | 从 Galaxy 网站导入角色。需要登录。 |
- 要管理集合
ansible-galaxy collection [import|init|install|login|remove|...]
子命令 | 功能 |
---|---|
初始化 | 生成新集合的骨架。 |
安装 | 安装集合。 |
列表 | 显示已安装集合的名称和版本。 |
Ansible 角色¶
Ansible 角色是一个促进剧本可重用性的单元。
注意
更多信息可以 在这里找到
安装有用的角色¶
为了突出使用角色的意义,我建议您使用 alemorvan/patchmanagement
角色,该角色允许您在更新过程中仅用几行代码执行许多任务(例如,更新前或更新后)。
您可以在该角色的 Github 仓库中查看代码 这里.
- 安装角色。这只需要一条命令
ansible-galaxy role install alemorvan.patchmanagement
- 创建一个剧本以包含该角色
- name: Start a Patch Management
hosts: ansible_clients
vars:
pm_before_update_tasks_file: custom_tasks/pm_before_update_tasks_file.yml
pm_after_update_tasks_file: custom_tasks/pm_after_update_tasks_file.yml
tasks:
- name: "Include patchmanagement"
include_role:
name: "alemorvan.patchmanagement"
使用此角色,您可以为所有清单添加自己的任务,也可以仅为目标节点添加任务。
让我们创建将在更新过程之前和之后运行的任务
- 创建
custom_tasks
文件夹
mkdir custom_tasks
- 创建
custom_tasks/pm_before_update_tasks_file.yml
(您可以随意更改此文件的文件名和内容)
---
- name: sample task before the update process
debug:
msg: "This is a sample tasks, feel free to add your own test task"
- 创建
custom_tasks/pm_after_update_tasks_file.yml
(您可以随意更改此文件的文件名和内容)
---
- name: sample task after the update process
debug:
msg: "This is a sample tasks, feel free to add your own test task"
并启动您的第一个补丁管理
ansible-playbook patchmanagement.yml
PLAY [Start a Patch Management] *************************************************************************
TASK [Gathering Facts] **********************************************************************************
ok: [192.168.1.11]
TASK [Include patchmanagement] **************************************************************************
TASK [alemorvan.patchmanagement : MAIN | Linux Patch Management Job] ************************************
ok: [192.168.1.11] => {
"msg": "Start 192 patch management"
}
...
TASK [alemorvan.patchmanagement : sample task before the update process] ********************************
ok: [192.168.1.11] => {
"msg": "This is a sample tasks, feel free to add your own test task"
}
...
TASK [alemorvan.patchmanagement : MAIN | We can now patch] **********************************************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/patch.yml for 192.168.1.11
TASK [alemorvan.patchmanagement : PATCH | Tasks depends on distribution] ********************************
ok: [192.168.1.11] => {
"ansible_distribution": "Rocky"
}
TASK [alemorvan.patchmanagement : PATCH | Include tasks for CentOS & RedHat tasks] **********************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/linux_tasks/redhat_centos.yml for 192.168.1.11
TASK [alemorvan.patchmanagement : RHEL CENTOS | yum clean all] ******************************************
changed: [192.168.1.11]
TASK [alemorvan.patchmanagement : RHEL CENTOS | Ensure yum-utils is installed] **************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : RHEL CENTOS | Remove old kernels] *************************************
skipping: [192.168.1.11]
TASK [alemorvan.patchmanagement : RHEL CENTOS | Update rpm package with yum] ****************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : PATCH | Inlude tasks for Debian & Ubuntu tasks] ***********************
skipping: [192.168.1.11]
TASK [alemorvan.patchmanagement : MAIN | We can now reboot] *********************************************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/reboot.yml for 192.168.1.11
TASK [alemorvan.patchmanagement : REBOOT | Reboot triggered] ********************************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : REBOOT | Ensure we are not in rescue mode] ****************************
ok: [192.168.1.11]
...
TASK [alemorvan.patchmanagement : FACTS | Insert fact file] *********************************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : FACTS | Save date of last PM] *****************************************
ok: [192.168.1.11]
...
TASK [alemorvan.patchmanagement : sample task after the update process] *********************************
ok: [192.168.1.11] => {
"msg": "This is a sample tasks, feel free to add your own test task"
}
PLAY RECAP **********************************************************************************************
192.168.1.11 : ok=31 changed=1 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
对于如此复杂的过程来说,非常简单,不是吗?
这只是社区提供的角色可以做的事情的一个例子。看看 galaxy.ansible.com,发现对您有用的角色!
您也可以根据自己的需要创建自己的角色,如果您愿意,也可以将它们发布到互联网上。这就是我们将在下一章中简要介绍的内容。
角色开发简介¶
ansible-galaxy
命令可以生成角色骨架,作为自定义角色开发的起点
$ ansible-galaxy role init rocky8
- Role rocky8 was created successfully
该命令将生成以下树结构来包含rocky8
角色
tree rocky8/
rocky8/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
8 directories, 8 files
角色允许您不再需要包含文件。在剧本中不需要指定文件路径或include
指令。您只需要指定一个任务,Ansible 会负责包含。
角色的结构相当容易理解。
变量简单地存储在vars/main.yml
中(如果变量不需要被覆盖),或者存储在default/main.yml
中(如果您想保留从角色外部覆盖变量内容的可能性)。
代码所需的处理程序、文件和模板分别存储在handlers/main.yml
、files
和templates
中。
剩下的就是定义角色任务的代码在tasks/main.yml
中。
一旦所有这些都运行良好,您就可以在剧本中使用此角色。您将能够使用您的角色而无需担心其任务的技术方面,同时使用变量自定义其操作。
实践操作:创建一个第一个简单的角色¶
让我们用一个“无所不能”的角色来实现它,该角色将创建一个默认用户并安装软件包。此角色可以系统地应用于所有服务器。
变量¶
我们将在所有服务器上创建一个rockstar
用户。由于我们不希望覆盖此用户,因此让我们在vars/main.yml
中定义它
---
rocky8_default_group:
name: rockstar
gid: 1100
rocky8_default_user:
name: rockstar
uid: 1100
group: rockstar
现在,我们可以在tasks/main.yml
中使用这些变量,而无需任何包含。
---
- name: Create default group
group:
name: "{{ rocky8_default_group.name }}"
gid: "{{ rocky8_default_group.gid }}"
- name: Create default user
user:
name: "{{ rocky8_default_user.name }}"
uid: "{{ rocky8_default_user.uid }}"
group: "{{ rocky8_default_user.group }}"
要测试您的新角色,让我们在与您的角色相同的目录中创建一个test-role.yml
剧本
---
- name: Test my role
hosts: localhost
roles:
- role: rocky8
become: true
become_user: root
并启动它
ansible-playbook test-role.yml
PLAY [Test my role] ************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [localhost]
TASK [rocky8 : Create default group] *******************************************************************
changed: [localhost]
TASK [rocky8 : Create default user] ********************************************************************
changed: [localhost]
PLAY RECAP *********************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
恭喜!现在您能够用只有几行的剧本创建很棒的东西。
让我们看看默认变量的使用。
创建一个要在服务器上默认安装的软件包列表和一个要卸载的空软件包列表。编辑defaults/main.yml
文件并添加这两个列表
rocky8_default_packages:
- tree
- vim
rocky8_remove_packages: []
并在tasks/main.yml
中使用它们
- name: Install default packages (can be overridden)
package:
name: "{{ rocky8_default_packages }}"
state: present
- name: "Uninstall default packages (can be overridden) {{ rocky8_remove_packages }}"
package:
name: "{{ rocky8_remove_packages }}"
state: absent
借助之前创建的剧本测试您的角色
ansible-playbook test-role.yml
PLAY [Test my role] ************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [localhost]
TASK [rocky8 : Create default group] *******************************************************************
ok: [localhost]
TASK [rocky8 : Create default user] ********************************************************************
ok: [localhost]
TASK [rocky8 : Install default packages (can be overridden)] ********************************************
ok: [localhost]
TASK [rocky8 : Uninstall default packages (can be overridden) []] ***************************************
ok: [localhost]
PLAY RECAP *********************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
现在您可以在剧本中覆盖rocky8_remove_packages
并卸载例如cockpit
---
- name: Test my role
hosts: localhost
vars:
rocky8_remove_packages:
- cockpit
roles:
- role: rocky8
become: true
become_user: root
ansible-playbook test-role.yml
PLAY [Test my role] ************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [localhost]
TASK [rocky8 : Create default group] *******************************************************************
ok: [localhost]
TASK [rocky8 : Create default user] ********************************************************************
ok: [localhost]
TASK [rocky8 : Install default packages (can be overridden)] ********************************************
ok: [localhost]
TASK [rocky8 : Uninstall default packages (can be overridden) ['cockpit']] ******************************
changed: [localhost]
PLAY RECAP *********************************************************************************************
localhost : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
显然,您可以无限地改进您的角色。想象一下,对于您的其中一台服务器,您需要一个在要卸载的列表中的软件包。然后,您可以例如创建一个可以被覆盖的新列表,然后使用 Jinja 的difference()
过滤器从要卸载的软件包列表中删除要安装的特定软件包列表中的软件包。
- name: "Uninstall default packages (can be overridden) {{ rocky8_remove_packages }}"
package:
name: "{{ rocky8_remove_packages | difference(rocky8_specifics_packages) }}"
state: absent
Ansible 集合¶
集合是 Ansible 内容的发布格式,可以包含剧本、角色、模块和插件。
注意
更多信息可以 在这里找到
要安装或升级集合
ansible-galaxy collection install namespace.collection [--upgrade]
然后,您可以使用新安装的集合,在其名称空间和名称之前使用模块的名称或角色的名称
- import_role:
name: namespace.collection.rolename
- namespace.collection.modulename:
option1: value
您可以在 这里找到集合索引。
让我们安装community.general
集合
ansible-galaxy collection install community.general
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/download/community-general-3.3.2.tar.gz to /home/ansible/.ansible/tmp/ansible-local-51384hsuhf3t5/tmpr_c9qrt1/community-general-3.3.2-f4q9u4dg
Installing 'community.general:3.3.2' to '/home/ansible/.ansible/collections/ansible_collections/community/general'
community.general:3.3.2 was installed successfully
现在我们可以使用新提供的模块yum_versionlock
- name: Start a Patch Management
hosts: ansible_clients
become: true
become_user: root
tasks:
- name: Ensure yum-versionlock is installed
package:
name: python3-dnf-plugin-versionlock
state: present
- name: Prevent kernel from being updated
community.general.yum_versionlock:
state: present
name: kernel
register: locks
- name: Display locks
debug:
var: locks.meta.packages
ansible-playbook versionlock.yml
PLAY [Start a Patch Management] *************************************************************************
TASK [Gathering Facts] **********************************************************************************
ok: [192.168.1.11]
TASK [Ensure yum-versionlock is installed] **************************************************************
changed: [192.168.1.11]
TASK [Prevent kernel from being updated] ****************************************************************
changed: [192.168.1.11]
TASK [Display locks] ************************************************************************************
ok: [192.168.1.11] => {
"locks.meta.packages": [
"kernel"
]
}
PLAY RECAP **********************************************************************************************
192.168.1.11 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
创建您自己的集合¶
与角色一样,您能够借助ansible-galaxy
命令创建您自己的集合
ansible-galaxy collection init rocky8.rockstarcollection
- Collection rocky8.rockstarcollection was created successfully
tree rocky8/rockstarcollection/
rocky8/rockstarcollection/
├── docs
├── galaxy.yml
├── plugins
│ └── README.md
├── README.md
└── roles
然后,您可以将自己的插件或角色存储在这个新集合中。