跳至内容

Ansible Galaxy:集合和角色

在本章中,您将学习如何使用、安装和管理 Ansible 角色和集合。


目标:在本章中,您将学会如何

✔ 安装和管理集合。
✔ 安装和管理角色。

🏁 ansible, ansible-galaxy, 角色, 集合

知识⭐ ⭐
复杂性: ⭐ ⭐ ⭐

阅读时间:40 分钟


Ansible Galaxy 提供来自 Ansible 社区的角色和集合。

提供的元素可以在 Playbook 中引用,并可直接使用

ansible-galaxy 命令

ansible-galaxy 命令使用 galaxy.ansible.com 来管理角色和集合。

  • 管理角色
ansible-galaxy role [import|init|install|login|remove|...]
子命令 功能
install 安装一个角色。
删除 移除一个或多个角色。
list 显示已安装角色的名称和版本。
信息 显示有关角色的信息。
init 生成一个新角色的骨架。
import 从 galaxy 网站导入一个角色。需要登录。
  • 管理集合
ansible-galaxy collection [import|init|install|login|remove|...]
子命令 功能
init 生成一个新集合的骨架。
install 安装一个集合。
list 显示已安装集合的名称和版本。

Ansible 角色

Ansible 角色是促进 Playbook 重用的单元。

注意

更多信息可以在 此处 找到。

安装有用的角色

为了突出使用角色的好处,我建议您使用 alemorvan/patchmanagement 角色,它允许您在更新过程中执行许多任务(例如,预更新或后更新),只需几行代码。

您可以在角色的 github 仓库 此处 查看代码。

  • 安装角色。这只需要一个命令
ansible-galaxy role install alemorvan.patchmanagement
  • 创建一个 Playbook 来包含该角色
- 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

角色允许您不必包含文件。无需在 Playbook 中指定文件路径或 include 指令。您只需指定一个任务,Ansible 会负责包含。

角色的结构很容易理解。

变量简单地存储在 vars/main.yml 中(如果变量不希望被覆盖),或者存储在 default/main.yml 中(如果您希望可以从角色外部覆盖变量内容)。

代码所需的 handlers、files 和 templates 分别存储在 handlers/main.ymlfilestemplates 中。

剩下的就是定义 tasks/main.yml 中角色任务的代码。

一旦所有这些工作正常,您就可以在 Playbook 中使用此角色。您可以无需担心其任务的技术方面而使用您的角色,同时通过变量自定义其操作。

实践:创建第一个简单角色

让我们通过一个 "go anywhere" 角色来实现这一点,该角色将创建默认用户并安装软件包。此角色可以系统地应用于所有服务器。

变量 (Variables)

我们将在所有服务器上创建一个 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 Playbook。

---
- 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   

恭喜!您现在可以使用只有几行的 Playbook 创建出色的东西。

让我们看看默认变量的使用。

创建一个默认安装在服务器上的软件包列表和一个空的待卸载软件包列表。编辑 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

借助之前创建的 Playbook 来测试您的角色。

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   

您现在可以在 Playbook 中覆盖 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 集合 (Collections)

集合是 Ansible 内容的分发格式,可以包含 Playbook、角色、模块和插件。

注意

更多信息可以在 此处 找到。

安装或升级集合

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

然后,您可以将自己的插件或角色存储在此新集合中。