跳至内容

Ansible Galaxy:集合和角色

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


目标:在本节中,您将学习如何

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

🏁 ansibleansible-galaxyrolescollections

知识⭐ ⭐
复杂度⭐ ⭐ ⭐

阅读时间: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.ymlfilestemplates中。

剩下的就是定义角色任务的代码在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

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