[Ansible 2.12] Playbook to enable yum on EOL CentOS 6

Hello everyone.
I'm Naka from the Systems Solutions Department, and I'd like to improve business efficiency using Ansible.

previously"Making yum usable on EOL CentOS 6 [Repository Change]"wrote an article titled

The default repositories for CentOS 6, which has reached End of Life (EOL), are no longer available, and yum cannot be used with an error.
Therefore, this document describes how to change the repositories to ones that are still available.

However, the above article describes a "manual" change process

CentOS 6 serversan environment with multiple, manually managing all of them would be extremely difficult.
Furthermore, manually managing multiple servers increases the probability of errors, so I would like to handle it using code.

This time, we will introduce a "Playbook" for "Code" and "Ansible" that allows you to use yum on EOL'd CentOS 6, and explain how to run it

Introduction

  • We do not recommend using CentOS 6. This is merely a
    for situations where you are forced to use CentOS 6temporary workaround.
  • is an unsupported version.
    Thisintended as a temporary workaroundandis not recommended.

Prerequisites

Q. Why change it in a playbook?

A.

1. "With manual work, the work time increases in proportion to the number of machines being worked on."
→ With Ansible, even if the number of machines increases, it can be handled in a much shorter time compared to manual work.
Therefore, the more machines there are,the better the work efficiencybecomes.

This will prevent personnel from being tied up in the work all day

2. "Manual work on multiple machines is prone to accidents."
→ When performing tasks continuously, it tends to become an assembly line process, making it very easy for errors to occur.

By creating a playbook for this, you can make the same changes to all machines without making any mistakes

3. "Playbooks can be reused and inherited as procedure manuals."
→ There are cases where procedure manuals are not kept, or where modifications are necessary to reuse them.
However, with Playbooks, they can often be used as is simply by changing the target, making them "less likely to become obsolete."

Q. What if I still want to do it manually?

A. I have explained the manual procedure in a previous article.

Please refer to here

How to use yum on EOL CentOS 6 [Repository change]

Q. If you get the error "(libselinux-python) aren't installed!", it seems easier to install it manually

A. I believe this error occurs when SELinux is not completely disabled and the "libselinux-python" package is missing

, "It's easier to just do it the way I did it manually to fix the errors
.

Therefore,we introduced a solution Playbook that can be used in conjunction with this in our previous article, so please make use of it.

[Ansible] Solution for "(libselinux-python) aren't installed!" for CentOS 6 Playbook

Execution environment

■ Linux Environment
OS: AlmaLinux release 8.10 (WSL2 environment)
Shell: Bash
Docker version 26.1.3, build b72abbb

■ Ansible Environment (Docker container within WSL2)
OS: AlmaLinux release 8.9
Ansible: Ansible-core 2.12.10

■ Windows Environment
OS: Windows 11 Pro (Version: 23H2)
Language setting: Changed to Japanese

■ CentOS 6 environment (Vagrant + VirtualBox)
OS: CentOS 6.9 (bento / centos-6.9)
Vagrant: 2.4.1
VirtualBox: 7.0.18 r162988 (Qt5.15.2)
IP: 192.168.33.15

Ansible 2.12 environment construction procedure

Since the CentOS 6 environment generally uses an older version of Python, we will use the older compatible version (2.12) of Ansible

In a previous article, we explained how to set up Ansible 2.12, so please refer to that for more information.

[Ansible 2.12] Build an Ansible execution environment for CentOS 6 using Docker in WSL2

Playbook

The following tasks were performed manually
: "backing up the repository
," "specifying the version
," "rewriting the base repository,"
and "deleting the yum cache."

The above four steps have been compiled into a single Playbook

centos6_repo_change.yml

The main.yml file uses `import_tasks` to load this Playbook.
(This is because I prefer to separate Playbooks by role to improve reusability, readability, and maintainability.)

--- ## Variable default # repo_source | default('/etc/yum.repos.d/CentOS-Base.repo') # repo_dest | default(default_repo_path) # repo_url | default('http://ftp.iij.ad.jp/pub/linux/centos-vault/$releasever')" # Base.repo backup # If a backup for the day already exists, it will not be retrieved - name: Check backup for base.repo ansible.builtin.stat: path: "{{ repo_dest | default('/etc/yum.repos.d/CentOS-Base.repo_' + lookup('pipe', 'date +\"%Y%m%d\"')) }}" register: backup_base_repo_result< - name: Backup base.repo ansible.builtin.copy: src: "{{ repo_source | default('/etc/yum.repos.d/CentOS-Base.repo') }}" dest: "{{ repo_dest | default('/etc/yum.repos.d/CentOS-Base.repo_' + lookup('pipe', 'date +\"%Y%m%d\"')) }}" mode: "0644" remote_src: yes when: not backup_base_repo_result.stat.exists # If releasever does not exist, create it with the current version number - name: Set releasever ansible.builtin.shell: cmd: echo "{{ ansible_distribution_version }}" > /etc/yum/vars/releasever args: creates: /etc/yum/vars/releasever - ansible.builtin.debug: var: ansible_distribution_version # Comment out mirrorlist in repo & change baseurl to an available repository to enable it - name: Replace mirrorlist ansible.builtin.replace: path: "{{ repo_source | default('/etc/yum.repos.d/CentOS-Base.repo') }}" regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" loop: - regexp: '^mirrorlist=http://mirrorlist.centos.org' replace: '#mirrorlist=http://mirrorlist.centos.org' - regexp: '^#baseurl=http://mirror.centos.org/centos/\$releasever' replace: "baseurl={{ repo_url | default('http://ftp.iij.ad.jp/pub/linux/centos-vault/$releasever') }}" register: replace_result # When changing the repository, delete the yum cache - name: Clean yum cache ansible.builtin.command: cmd: yum clean all when: replace_result is changed
The intention is mostly written in the comments, but I will also explain it below

## Variable default

Specify the default value of the variable

It is also provided as a guide to make it easier to understand when specifying vars separately

# Base.repo backup

Check for its existence with the stat module and store it in a variable with register

This is determined by when, and if there is no backup of the repository for that day, it will be obtained

From now on, path destinations, repositories, etc. will be made into variables and default values ​​for the variables will be specified using the default filter

In addition, for backups using the lookup plugin, we've added the year, month, and day to the end of the filename to make them easier to identify.

# If releasever does not exist, create it with the current version number

Create a variable file to fix the version when using yum

The `ansible.builtin.shell` module is used for the checks and processing.
Because this module uses OS-level functionality, idempotency checks are not performed.

However, the `args -> creates` parameter because it allows me to specify a condition that the command should not be executed if the specified file does not exist, thus enabling me to control the situation as intended.

ansible_distribution_version

the Ansiblefact variable "ansible_distribution_version", you can obtain the current OS version of the execution environment (6.9 in this case).

The above is used to create a file via the echo command

Just to be sure, use the ansible.builtin.debug module to display the contents of the variables on the console

# Comment out the repo mirrorlist and change the baseurl to an available repository to enable it

The ansible.builtin.replace module rewrites two places as shown in the title

to the part that is rewritten using the sed command during the manual procedureThis corresponds

We use loop to specify two locations, but it can also be done with with_items

The execution result is saved using register and used in the next process using when

 # When changing repositories, delete the yum cache
when: replace_result is changed

clears the yum cache The yum module does not have a function equivalent to `yum clean all`, which

For this reason, we use the ansible.builtin.command module, which executes OS commands in the same way as a shell

The results of using the replace module to rewrite the repository mentioned earlier are saved using register, and are executed only when "changed" is confirmed

Aside: Difference between shell module and Command module

the Shell moduleBecauseit can utilize OS environment variables and pipes.
It's convenient because it allows you to execute one-liners and other commands you normally use within your environment.

The Command moduledoes not use the Shell, soit cannot utilize environment variables.
This is an advantage, asit eliminates the possibility of unintended behavior caused by environment-specific variables.

However, since these methods utilize commands specific to the target OS rather than Ansible,idempotency cannot be guaranteed.
only be used as a last resort when modules are insufficientThey should

Example

Inventory file for verification environment

In a CentOS 6 (bento / centos-6.9) environment, password authentication(which is deprecated)can exist, so we conducted the test in this state as well.

--- all: vars: ansible_user: vagrant hosts: targetnode: ansible_host: 192.168.33.15 ansible_ssh_pass: vagrant

main.yml

Instead of writing tasks in main.yml, I've adopted a style where I import Playbooks using import_tasks.
(This is because I prefer to separate Playbooks by role to improve reusability, readability, and maintainability.)

Regarding variables,the values ​​specified in `default` within the Playbook are used, so execution is possible even if they are not specified.

However, we have listed the items and content that can be changed with variables because we believe it is easy to understand intuitively

- name: main.yml hosts: targetnode become: yes vars: wget_repo: "http://ftp.iij.ad.jp/pub/linux/centos-vault" repo_source: "/etc/yum.repos.d/CentOS-Base.repo" repo_dest: "/etc/yum.repos.d/CentOS-Base.repo_{{ lookup('pipe', 'date +\"%Y%m%d\"') }}" repo_url: '{{ wget_repo }}/$releasever' tasks: #Install if SELinux is not disabled and libselinux-python does not exist - name: Include libeselinux-python(wget) ansible.builtin.import_tasks: libselinux-python_wget.yml #Change the initial repository of Centos6 Base - name: Include centos6_repo_change ansible.builtin.import_tasks: centos6_repo_change.yml

libselinux-python_wget.yml , as mentioned inthe previous articleis the Playbook for troubleshooting SELinux-related errors

The centos6_repo_change.yml file is the Playbook I've introduced here.

Playbook execution

mentioned abovethe other articlewe will execute the code from a container running an older version of Ansible, as

Before executing, check that yum cannot be used on the verification machine

■Preliminary check [vagrant@targetnode ~]$ yum info php Loaded plugins: fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os&infra=stock error was 14: PYCURL ERROR 6 - "Couldn't resolve host 'mirrorlist.centos.org'" Error: Cannot find a valid baseurl for repo: base *The repository is no longer available, so an error will appear and it cannot be used
■ Execute Playbook [root@author's container environment work]# ansible-playbook -i hosts main.yml ~Omitted~ PLAY RECAP ****************************************************************************************************************************** targetnode : ok=17 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2 *The results of the two Playbooks are output
■Post-confirmation [vagrant@targetnode ~]$ yum info php Loaded plugins: fastestmirror Determining fastest mirrors base | 3.7 kB 00:00 base/primary_db | 4.7 MB 00:00 extras | 3.4 kB 00:00 extras/primary_db | 30 kB 00:00 updates | 3.4 kB 00:00 updates/primary_db | 8.1 MB 00:00 Available Packages Name : php Arch : x86_64 Version : 5.3.3 ~Omitted~

After the Playbook execution, the repository errors have been resolved and metadata has been retrieved.
The output of `yum info php` is then displayed, confirming that yum is now working correctly.

lastly

This post is based on my previous experience using Ansible to solve a problem.
The playbook I created back then was hastily made and therefore rougher and less reusable than it is now, but I'm glad I was able to improve it for this blog post.

Preparing for anything only when a situation arises can be stressful, and the materials tend to be only useful in that specific moment. It
might be a good idea to prepare a general-purpose playbook when you have the time.

I hope this article has given readers a little inspiration to try Ansible, or provided some useful knowledge/information.
Thank you for reading this far!

Reference materials

ansible.builtin.yum module – Manages packages with the yum package manager
https://docs.ansible.com/ansible/9/collections/ansible/builtin/yum_module.html

ansible.builtin.replace module – Replace all instances of a particular string in a file using a back-referenced regular expression
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/replace_module.html

How do I change the CentOS 6 repository address? | Alibaba Cloud
https://www.alibabacloud.com/help/en/ecs/user-guide/change-the-centos-6-source-address

If you found this article helpful,please give it a "Like"!
3
Loading...
3 votes, average: 1.00 / 13
849
X Facebook Hatena Bookmark pocket

The person who wrote this article

About the author

inside

Beyond as a mid-career hire and
am currently in the Systems Solutions Department.
I hold LPIC-3 304 and AWS SAA certifications.