Roles y Colecciones de Ansible en RHEL

AnsibleBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá a automatizar la configuración de un servidor web Red Hat Enterprise Linux (RHEL) aprovechando la potencia y reutilización de los Roles y Colecciones de Ansible. Construirá un flujo de trabajo de automatización integral creando un rol personalizado para desplegar configuraciones específicas, integrando un rol externo de un repositorio Git como dependencia y utilizando un RHEL System Role preconstruido de una Colección de Ansible para gestionar servicios del sistema como SELinux.

El proceso comienza creando una estructura de rol estandarizada utilizando ansible-galaxy init. Luego definirá e instalará una dependencia de rol de un repositorio Git utilizando un archivo requirements.yml. Después de integrar un RHEL System Role, ensamblará los tres tipos de roles (personalizado, basado en Git y basado en Colección) en un único playbook maestro. Finalmente, ejecutará el playbook y verificará que el servidor web Apache y la configuración de SELinux se hayan aplicado correctamente al servidor RHEL de destino, demostrando una solución de automatización completa y modular.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 82%. Ha recibido una tasa de reseñas positivas del 90% por parte de los estudiantes.

Crear un Rol de Ansible Personalizado con ansible-galaxy init

En este paso, comenzará creando una estructura de directorios estandarizada para un nuevo rol de Ansible utilizando el comando ansible-galaxy init. Los roles de Ansible son un concepto fundamental para construir contenido de automatización reutilizable y organizado. Permiten empaquetar tareas, manejadores (handlers), variables y otros componentes en una unidad autocontenida y portátil. Utilizar una estructura estándar es una buena práctica que hace que su automatización sea más fácil de entender, gestionar y compartir.

Primero, asegúrese de estar en el directorio de trabajo correcto. Todo el trabajo para este laboratorio se realizará dentro del directorio ~/project.

cd ~/project

Antes de crear un rol, necesita asegurarse de que las herramientas de línea de comandos de Ansible estén instaladas. El paquete ansible-core proporciona las herramientas esenciales, incluido ansible-galaxy.

Instale ansible-core utilizando el gestor de paquetes dnf. La bandera -y responde automáticamente "sí" a cualquier solicitud de confirmación.

sudo dnf install -y ansible-core

Debería ver una salida que indique que el paquete se está instalando y que las dependencias se están resolviendo.

...
Installed:
  ansible-core-2.16.x-1.el9.x86_64
  ...
Complete!

Es una práctica común organizar todos los roles del proyecto dentro de un directorio dedicado roles. Cree este directorio ahora.

mkdir roles

Ahora, navegue dentro del directorio roles recién creado. Aquí es donde inicializará su nuevo rol personalizado.

cd roles

Ahora utilizará el comando ansible-galaxy init para crear un esqueleto para un rol llamado apache.developer_configs. Este comando genera automáticamente un conjunto de directorios y archivos estándar, proporcionando un punto de partida limpio para el desarrollo de su rol.

ansible-galaxy init apache.developer_configs

Después de ejecutar el comando, verá un mensaje de confirmación.

- Role apache.developer_configs was created successfully

Para ver la estructura que se acaba de crear, puede usar el comando ls -R, que lista el contenido de un directorio y todos sus subdirectorios de forma recursiva.

ls -R apache.developer_configs

La salida muestra la estructura de directorios estándar para un rol de Ansible:

apache.developer_configs:
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars

apache.developer_configs/defaults:
main.yml

apache.developer_configs/files:

apache.developer_configs/handlers:
main.yml

apache.developer_configs/meta:
main.yml

apache.developer_configs/tasks:
main.yml

apache.developer_configs/templates:

apache.developer_configs/tests:
inventory  test.yml

apache.developer_configs/vars:
main.yml

Aquí hay una breve descripción general de los directorios más importantes:

  • tasks: Contiene la lista principal de tareas que serán ejecutadas por el rol.
  • handlers: Contiene manejadores (handlers), que son tareas que solo se ejecutan cuando son notificadas por otra tarea.
  • vars: Contiene variables para el rol.
  • templates: Contiene plantillas de archivos que utilizan el motor de plantillas Jinja2.
  • meta: Contiene metadatos para el rol, incluidas las dependencias de otros roles.

Ahora ha creado con éxito la estructura básica para su rol personalizado de Ansible. En los siguientes pasos, poblará estos directorios con contenido para configurar un servidor web.

Instalar una Dependencia de Rol desde un Repositorio Git usando requirements.yml

En este paso, aprenderá a gestionar dependencias de roles desde fuentes externas, como un repositorio Git. Esta es una práctica común en proyectos Ansible más grandes donde se reutilizan roles desarrollados por la comunidad u otros equipos. Ansible utiliza un archivo, típicamente llamado requirements.yml, para definir una lista de roles a instalar.

Su rol personalizado, apache.developer_configs, dependerá de un rol base de Apache para asegurar que el servidor web esté instalado y funcionando. Definirá esta dependencia y la instalará.

Primero, asegúrese de estar en el directorio principal del proyecto. Si todavía está en el subdirectorio roles del paso anterior, navegue de regreso a ~/project.

cd ~/project

Ahora, creará el archivo requirements.yml dentro de su directorio roles. Este archivo listará todos los roles externos que su proyecto necesita. Utilice el editor nano para crear y editar el archivo.

nano roles/requirements.yml

Agregue el siguiente contenido al archivo. Esta entrada le indica a ansible-galaxy que descargue una versión específica de un rol de Apache de un repositorio Git público y lo nombre localmente como infra.apache.

- name: infra.apache
  src: https://github.com/geerlingguy/ansible-role-apache.git
  scm: git
  version: 3.2.0

Analicemos esta definición:

  • name: Este es el nombre local para el rol. Aunque el repositorio de origen tenga un nombre diferente, se instalará en un directorio llamado infra.apache.
  • src: La URL de origen del repositorio Git.
  • scm: Especifica la herramienta de gestión de control de origen, que en este caso es git.
  • version: La rama, etiqueta o hash de commit de Git específico a utilizar. Fijar una versión es crucial para asegurar que su automatización sea estable y predecible.

Guarde el archivo y salga de nano presionando Ctrl+X, seguido de Y, y luego Enter.

Con el archivo requirements.yml en su lugar, ahora puede usar el comando ansible-galaxy install para descargar e instalar el rol.

  • La bandera -r apunta a su archivo de requisitos.
  • La bandera -p especifica la ruta donde se deben instalar los roles.
ansible-galaxy install -r roles/requirements.yml -p roles

Verá una salida que confirma el proceso de descarga e instalación.

Starting galaxy role install process
- downloading role 'ansible-role-apache', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-apache/archive/3.2.0.tar.gz
- extracting infra.apache to /home/labex/project/roles/infra.apache
- infra.apache (3.2.0) was installed successfully

Para confirmar que el rol se instaló correctamente, liste el contenido del directorio roles.

ls -l roles

Ahora debería ver el directorio infra.apache junto con el rol apache.developer_configs que creó anteriormente.

total 12
drwxr-xr-x. 9 labex labex 4096 Nov 10 10:10 apache.developer_configs
drwxr-xr-x. 9 labex labex 4096 Nov 10 10:15 infra.apache
-rw-r--r--. 1 labex labex  118 Nov 10 10:12 requirements.yml

Ahora ha declarado con éxito un repositorio Git externo como dependencia y lo ha instalado en su proyecto. El siguiente paso es integrar esta dependencia en los metadatos de su rol personalizado.

Integrar un Rol de Sistema RHEL de una Colección de Ansible

En este paso, trabajará con Colecciones de Ansible, que son la forma estándar de distribuir contenido de Ansible, incluyendo roles, módulos y plugins. Instalará la colección community.general, que proporciona un conjunto de módulos útiles para automatizar tareas administrativas comunes, incluida la gestión de SELinux.

Para nuestro escenario de servidor web, necesitamos configurar correctamente SELinux para permitir que el servicio Apache escuche en puertos no estándar. La colección community.general incluye módulos SELinux que son perfectos para esta tarea.

Primero, asegúrese de estar en el directorio principal del proyecto.

cd ~/project

Es una buena práctica mantener las colecciones instaladas dentro del directorio del proyecto para que su proyecto sea autosuficiente. Cree un directorio llamado collections para almacenarlas.

mkdir collections

Ahora, use el comando ansible-galaxy collection install para instalar las colecciones requeridas. El flag -p indica al comando que instale las colecciones en el directorio collections que acaba de crear.

ansible-galaxy collection install community.general:7.5.0 ansible.posix:1.5.4 -p collections

El comando descargará las colecciones y sus dependencias. Verá una salida similar a la siguiente:

Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'community.general:7.5.0' to '/home/labex/project/collections/ansible_collections/community/general'
Installing 'ansible.posix:1.5.4' to '/home/labex/project/collections/ansible_collections/ansible/posix'
...
community.general:7.5.0 was installed successfully
ansible.posix:1.5.4 was installed successfully

Para verificar que la colección ahora está disponible para su proyecto, puede listar todas las colecciones instaladas especificando la ruta de las colecciones.

ansible-galaxy collection list -p collections

La salida mostrará las colecciones instaladas y sus rutas de instalación dentro de su proyecto.

## /home/labex/project/collections/ansible_collections
Collection              Version
----------------------- -------
ansible.posix           1.5.4
community.general       7.5.0

Cuando utilice un módulo de una colección en un playbook, debe referirse a él por su Nombre de Colección Completamente Calificado (FQCN - Fully Qualified Collection Name). Para la gestión de SELinux, utilizará ansible.posix.selinux para la gestión del estado de SELinux y community.general.seport para la gestión de puertos de SELinux.

Ahora ha instalado con éxito colecciones potentes que incluyen módulos de gestión de SELinux. En el siguiente paso, ensamblará un playbook que utiliza su rol personalizado, el rol de Git y los módulos SELinux de estas colecciones para configurar completamente el servidor web de desarrollo.

Ensamblar y Ejecutar un Playbook con Roles Personalizados, de Git y del Sistema

En este paso, unirás todos los componentes que has preparado: tu rol personalizado, la dependencia de Git y el Rol del Sistema RHEL. Crearás un playbook principal que orquestará estos roles para configurar completamente el servidor web de desarrollo.

Piensa en este paso como el ensamblaje de una máquina compleja a partir de diferentes piezas: cada rol cumple un propósito específico y trabajan juntos para crear un entorno completo de servidor web. Vamos a desglosar esto en partes manejables:

Primero, asegúrate de estar en el directorio principal del proyecto.

cd ~/project

Antes de sumergirnos en la configuración, entendamos qué estamos creando:

  • Configuración de Ansible: Establece cómo se comporta Ansible y dónde encuentra los archivos.
  • Inventario: Define qué servidores gestionar (en nuestro caso, localhost).
  • Variables: Almacenan datos que nuestros roles utilizarán (información del desarrollador, configuraciones de SELinux).
  • Contenido del Rol Personalizado: Las tareas reales que configurarán los entornos de desarrollo.
  • Playbook Principal: El orquestador que ejecuta todo en el orden correcto.

1. Crear Configuración y Inventario de Ansible

El archivo ansible.cfg es como un archivo de configuración que le dice a Ansible cómo comportarse. Sin él, necesitarías especificar rutas y opciones en cada comando. Con él, Ansible sabe automáticamente dónde encontrar tus roles, colecciones e inventario.

Crea el archivo ansible.cfg usando nano. Este archivo le dice a Ansible dónde encontrar tus roles, colecciones e inventario.

nano ansible.cfg

Añade el siguiente contenido. Entendamos cada línea:

[defaults]
inventory = inventory
roles_path = roles
collections_paths = collections
host_key_checking = False

[privilege_escalation]
become = True

Qué hace cada configuración:

  • inventory = inventory: En lugar de escribir -i inventory cada vez, Ansible usará automáticamente este archivo.
  • roles_path = roles: Ansible buscará roles en el directorio roles.
  • collections_paths = collections: Ansible encontrará tus colecciones instaladas aquí.
  • host_key_checking = False: Evita errores de verificación de claves SSH en entornos de laboratorio.
  • become = True: Ejecuta automáticamente tareas con privilegios elevados cuando es necesario.

Guarda y sal de nano (Presiona Ctrl+X, luego Y, luego Enter).

El archivo de inventario le dice a Ansible qué máquinas gestionar. En nuestro caso, estamos configurando la máquina local.

nano inventory

Añade la siguiente línea:

localhost ansible_connection=local

Qué significa esto:

  • localhost: El nombre de nuestro host de destino.
  • ansible_connection=local: En lugar de SSH, usa conexiones locales (ya que estamos gestionando la misma máquina en la que ejecutamos Ansible).

Guarda y sal de nano.

2. Definir Variables de Rol

Las variables en Ansible son como configuraciones que tus roles pueden usar. En lugar de codificar valores como nombres de usuario o números de puerto en tus tareas, los defines en archivos de variables. Esto hace que tu automatización sea flexible y reutilizable.

El directorio group_vars/all es una ubicación especial donde Ansible carga automáticamente variables para todos los hosts. Cualquier archivo YAML en este directorio se vuelve disponible para tus playbooks y roles.

Crea la estructura de directorios para variables que se aplican a todos los hosts:

mkdir -p group_vars/all

Ahora, crea un archivo para definir la información del desarrollador. Estos datos serán utilizados por tu rol personalizado para crear cuentas de usuario y configuraciones web.

nano group_vars/all/developers.yml

Añade el siguiente contenido:

---
web_developers:
  - username: jdoe ## Primer desarrollador
    port: 9081 ## Puerto personalizado para el sitio web de este desarrollador
  - username: jdoe2 ## Segundo desarrollador
    port: 9082 ## Puerto personalizado para el sitio web de este desarrollador

Qué significa esta estructura de datos:

  • web_developers: Una lista que contiene información del desarrollador.
  • Cada desarrollador tiene un username y un port.
  • Tu rol personalizado recorrerá esta lista para crear configuraciones para cada desarrollador.

Guarda y sal.

A continuación, crea un archivo de variables para la configuración de SELinux. SELinux (Security-Enhanced Linux) es un módulo de seguridad que controla lo que las aplicaciones pueden hacer.

nano group_vars/all/selinux.yml

Añade el siguiente contenido:

---
selinux_state: enforcing ## Establece SELinux en modo enforcing (máxima seguridad)
selinux_ports: ## Lista de puertos que se permitirán usar a Apache
  - ports: "9081" ## Permitir el puerto 9081
    proto: "tcp" ## Protocolo: TCP
    setype: "http_port_t" ## Tipo SELinux: puerto HTTP
    state: "present" ## Añadir esta regla
  - ports: "9082" ## Permitir el puerto 9082
    proto: "tcp" ## Protocolo: TCP
    setype: "http_port_t" ## Tipo SELinux: puerto HTTP
    state: "present" ## Añadir esta regla

Entendiendo la configuración de SELinux:

  • selinux_state: enforcing: SELinux bloqueará activamente las acciones no autorizadas.
  • selinux_ports: Una lista de configuraciones de puertos.
  • http_port_t: El tipo SELinux que permite a Apache enlazarse a puertos.
  • Por defecto, Apache solo puede usar los puertos 80 y 443; necesitamos permitir explícitamente 9081 y 9082.

Guarda y sal.

3. Poblar el Rol Personalizado

Tu rol apache.developer_configs actualmente tiene la estructura de directorios pero sin contenido real. Necesitamos añadir:

  • Plantillas (Templates): Archivos que pueden incluir variables (usando sintaxis Jinja2).
  • Tareas (Tasks): El trabajo real que realizará Ansible.
  • Manejadores (Handlers): Tareas especiales que solo se ejecutan cuando se les notifica (como reiniciar servicios).
  • Metadatos (Metadata): Información sobre las dependencias del rol.

Las plantillas te permiten crear archivos de configuración que se adaptan según tus variables. La extensión .j2 indica que es una plantilla Jinja2.

nano roles/apache.developer_configs/templates/developer.conf.j2

Añade el siguiente contenido:

{% for dev in web_developers %}
Listen {{ dev.port }}
<VirtualHost *:{{ dev.port }}>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/{{ dev.username }}

    <Directory /var/www/{{ dev.username }}>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>
{% endfor %}

Entendiendo la sintaxis de la plantilla:

  • {% for dev in web_developers %}: Inicia un bucle a través de la lista de desarrolladores.
  • {{ dev.port }}: Inserta el número de puerto para este desarrollador.
  • {{ dev.username }}: Inserta el nombre de usuario para este desarrollador.
  • {% endfor %}: Finaliza el bucle.
  • El resultado serán configuraciones de host virtual separadas para cada desarrollador.

Qué crea esto: Para nuestros dos desarrolladores, esta plantilla generará una configuración de Apache que:

  1. Hace que Apache escuche en los puertos 9081 y 9082.
  2. Crea hosts virtuales que sirven contenido desde /var/www/jdoe y /var/www/jdoe2.
  3. Establece los permisos apropiados para cada directorio.

Guarda y sal.

Las tareas son el trabajo real que realiza Ansible. Cada tarea utiliza un módulo de Ansible para lograr algo específico.

nano roles/apache.developer_configs/tasks/main.yml

Añade el siguiente contenido y entendamos cada tarea:

---
## Tarea 1: Crear cuentas de usuario para cada desarrollador
- name: Create developer user accounts
  ansible.builtin.user: ## Usa el módulo 'user'
    name: "{{ item.username }}" ## Crea el usuario con este nombre
    state: present ## Asegura que el usuario exista
  loop: "{{ web_developers }}" ## Haz esto para cada desarrollador en la lista

## Tarea 2: Crear directorios web para cada desarrollador
- name: Create developer web root directories
  ansible.builtin.file: ## Usa el módulo 'file'
    path: "/var/www/{{ item.username }}" ## Crea este directorio
    state: directory ## Asegura que sea un directorio
    owner: "{{ item.username }}" ## Establece el propietario
    group: "{{ item.username }}" ## Establece el grupo
    mode: "0755" ## Establece permisos (rwxr-xr-x)
  loop: "{{ web_developers }}"

## Tarea 3: Crear una página web de ejemplo para cada desarrollador
- name: Create a sample index.html for each developer
  ansible.builtin.copy: ## Usa el módulo 'copy'
    content: "Welcome to {{ item.username }}'s dev space\n" ## Contenido del archivo
    dest: "/var/www/{{ item.username }}/index.html" ## Dónde colocar el archivo
    owner: "{{ item.username }}" ## Propietario del archivo
    group: "{{ item.username }}" ## Grupo del archivo
    mode: "0644" ## Permisos del archivo (rw-r--r--)
  loop: "{{ web_developers }}"

## Tarea 4: Desplegar el archivo de configuración de Apache
- name: Deploy developer apache configs
  ansible.builtin.template: ## Usa el módulo 'template'
    src: developer.conf.j2 ## Archivo de plantilla de origen
    dest: /etc/httpd/conf.d/developer.conf ## Destino en el servidor
    mode: "0644" ## Permisos del archivo
  notify: restart apache ## Dispara el manejador de reinicio cuando esto cambie

Entendiendo conceptos clave:

  • loop: Repite la tarea para cada elemento de la lista.
  • {{ item.username }}: Se refiere al nombre de usuario del elemento actual en el bucle.
  • notify: restart apache: Cuando esta tarea realiza cambios, activará un manejador llamado "restart apache".
  • Permisos de archivo: 0755 significa que el propietario puede leer/escribir/ejecutar, los demás pueden leer/ejecutar; 0644 significa que el propietario puede leer/escribir, los demás solo pueden leer.

Guarda y sal.

Los manejadores (handlers) son tareas especiales que solo se ejecutan cuando son notificadas por otras tareas. Típicamente se usan para acciones como reiniciar servicios.

nano roles/apache.developer_configs/handlers/main.yml

Añade el siguiente contenido:

---
- name: restart apache ## Este nombre debe coincidir con la declaración notify:
  ansible.builtin.service: ## Usa el módulo 'service'
    name: httpd ## El nombre del servicio (Apache se llama 'httpd' en RHEL)
    state: restarted ## Reinicia el servicio

¿Por qué usar manejadores?

  • Eficiencia: El servicio solo se reinicia si la configuración realmente cambió.
  • Orden: Todas las tareas se ejecutan primero, luego todos los manejadores se ejecutan al final.
  • Idempotencia: Múltiples tareas pueden notificar al mismo manejador, pero solo se ejecuta una vez.

Guarda y sal.

Finalmente, necesitamos decirle a Ansible que nuestro rol personalizado depende del rol infra.apache que instalamos anteriormente.

nano roles/apache.developer_configs/meta/main.yml

Reemplaza el contenido del archivo con:

---
dependencies:
  - role: infra.apache ## Este rol debe ejecutarse antes que nuestro rol personalizado

Qué hace esto:

  • Cuando Ansible ejecuta apache.developer_configs, ejecutará automáticamente infra.apache primero.
  • Esto asegura que Apache esté instalado y configurado antes de que agreguemos nuestras configuraciones personalizadas.
  • Las dependencias se ejecutan en el orden en que están listadas.

Guarda y sal.

4. Ensamblar y Ejecutar el Playbook Principal

Un playbook es como una receta que le dice a Ansible qué hacer y en qué orden. Nuestro playbook hará lo siguiente:

  1. Configurar los ajustes de SELinux (pre_tasks).
  2. Ejecutar nuestros roles (que incluye la cadena de dependencias).

Crea el archivo del playbook principal:

nano web_dev_server.yml

Añade el siguiente contenido con explicaciones detalladas:

---
- name: Configure Dev Web Server ## Nombre del playbook
  hosts: localhost ## Ejecutar en localhost
  pre_tasks: ## Tareas que se ejecutan antes de los roles
    ## Tarea 1: Configurar el modo SELinux
    - name: Set SELinux to enforcing mode
      ansible.posix.selinux: ## Módulo de la colección ansible.posix
        policy: targeted ## Usar la política SELinux 'targeted'
        state: "{{ selinux_state }}" ## Usar la variable que definimos
      when: selinux_state is defined ## Ejecutar solo si la variable existe

    ## Tarea 2: Configurar puertos SELinux
    - name: Configure SELinux ports for Apache
      community.general.seport: ## Módulo de la colección community.general
        ports: "{{ item.ports }}" ## Número de puerto
        proto: "{{ item.proto }}" ## Protocolo (tcp)
        setype: "{{ item.setype }}" ## Tipo SELinux (http_port_t)
        state: "{{ item.state }}" ## present o absent
      loop: "{{ selinux_ports }}" ## Iterar sobre nuestra lista de puertos
      when: selinux_ports is defined ## Ejecutar solo si la variable existe

  roles: ## Roles a ejecutar
    - apache.developer_configs ## Nuestro rol personalizado (que activará infra.apache)

Entendiendo el orden de ejecución:

  1. pre_tasks: La configuración de SELinux se ejecuta primero.
  2. roles: Las dependencias de roles se ejecutan (infra.apache), luego nuestro rol personalizado.
  3. handlers: Cualquier manejador notificado se ejecuta al final.

Por qué este orden es importante:

  • SELinux debe configurarse antes de que Apache intente enlazarse a puertos personalizados.
  • Apache debe estar instalado antes de que podamos configurar hosts virtuales.
  • Los reinicios de servicio ocurren después de que toda la configuración se completa.

Guarda y sal.

Ahora estás listo para ejecutar tu automatización completa:

ansible-playbook web_dev_server.yml

El playbook se ejecutará y verás una salida detallada. Aquí tienes lo que puedes esperar (por ejemplo):

PLAY [Configure Dev Web Server] *************************************************

TASK [Gathering Facts] **********************************************************
ok: [localhost]                     ## Ansible recopila información del sistema

TASK [Set SELinux to enforcing mode] *******************************************
changed: [localhost]                ## El modo SELinux fue cambiado

TASK [Configure SELinux ports for Apache] **************************************
changed: [localhost] => (item={'ports': '9081', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})
changed: [localhost] => (item={'ports': '9082', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})

TASK [infra.apache : Ensure Apache is installed.] *******************************
changed: [localhost]                ## El paquete Apache fue instalado

TASK [apache.developer_configs : Create developer user accounts] ****************
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Create developer web root directories] *********
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Create a sample index.html for each developer] *
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Deploy developer apache configs] ***************
changed: [localhost]                ## El archivo de configuración fue creado

RUNNING HANDLER [apache.developer_configs : restart apache] *********************
changed: [localhost]                ## Apache fue reiniciado

PLAY RECAP **********************************************************************
localhost                  : ok=17   changed=12   unreachable=0    failed=0    skipped=3    rescued=0    ignored=0

¡Has ensamblado y ejecutado con éxito un playbook complejo que combina múltiples roles de diferentes fuentes para crear un entorno completo de desarrollo web!

Verificar la Configuración de SELinux y Apache en el Servidor RHEL

En este paso final, verificará que su automatización de Ansible ha configurado correctamente el sistema. Es crucial confirmar que los servicios se están ejecutando según lo esperado y que las políticas de seguridad (SELinux) se han aplicado correctamente. Utilizará herramientas estándar de línea de comandos de RHEL para inspeccionar el estado del sistema.

Primero, asegúrese de estar en el directorio principal del proyecto.

cd ~/project

1. Verificar la Configuración de SELinux

Los módulos SELinux de las colecciones tuvieron la tarea de establecer el modo SELinux en enforcing y permitir nuevos puertos para el tipo http_port_t.

Compruebe el estado actual de SELinux utilizando el comando sestatus.

sestatus

La salida debería mostrar que SELinux está habilitado y en modo enforcing.

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

A continuación, utilice el comando semanage port para verificar que los puertos 9081 y 9082 se han agregado al contexto http_port_t. Puede canalizar la salida a grep para encontrar las líneas relevantes.

sudo semanage port -l | grep http_port_t

Debería ver sus puertos personalizados listados entre los puertos HTTP predeterminados. La salida exacta puede variar, pero incluirá los puertos que definió.

http_port_t                    tcp      9082, 9081, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

Esto confirma que los módulos SELinux han actualizado correctamente la política.

2. Verificar el Servicio y la Configuración de Apache

El rol infra.apache instaló e inició el servicio httpd. Dado que systemctl no está disponible en este entorno de contenedor, puede verificar el proceso en ejecución usando ps.

ps aux | grep httpd

Debería ver varios procesos httpd en ejecución, lo que indica que el servicio está activo.

root        8851  0.2  0.4  25652 16228 ?        Ss   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8852  0.0  0.1  25308  6044 ?        S    09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8853  0.0  0.3 1443348 11364 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8854  0.0  0.3 1443348 11480 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8855  0.0  0.4 1574484 15848 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
labex       9298  0.0  0.0   6408  2176 pts/3    S+   09:31   0:00 grep --color=auto httpd

3. Verificar la Accesibilidad del Contenido Web

Finalmente, la prueba más importante es ver si los sitios web de los desarrolladores son accesibles. Su rol apache.developer_configs configuró hosts virtuales en los puertos 9081 y 9082. Utilice el comando curl para solicitar el contenido de cada punto final.

Primero, pruebe el sitio para el usuario jdoe en el puerto 9081.

curl http://localhost:9081

La salida esperada es el contenido del archivo index.html que creó para este usuario.

Welcome to jdoe's dev space

A continuación, pruebe el sitio para el usuario jdoe2 en el puerto 9082.

curl http://localhost:9082

Debería ver el mensaje de bienvenida correspondiente.

Welcome to jdoe2's dev space

Estos comandos curl exitosos confirman que Apache está configurado correctamente, los hosts virtuales están funcionando y la política SELinux está permitiendo el tráfico en los puertos personalizados.

¡Felicitaciones! Ha creado con éxito un proyecto de automatización de Ansible completo que combina un rol personalizado, un rol de un repositorio Git y módulos SELinux de colecciones de Ansible para configurar un servidor web de desarrollo seguro y multiusuario.

Resumen

En este laboratorio, aprenderá a automatizar la configuración de un servidor web RHEL aprovechando el poder y la estructura de los Roles y Colecciones de Ansible. Comenzará creando un rol personalizado desde cero utilizando el comando ansible-galaxy init, que establece una estructura de directorios estandarizada para contenido de automatización reutilizable. Este paso fundamental prepara el escenario para tareas de automatización más complejas.

Basándose en el rol personalizado, integrará dependencias externas, incluido un rol de un repositorio Git a través de un archivo requirements.yml y un Rol de Sistema RHEL oficial de una Colección de Ansible. Finalmente, ensamblará estos diferentes tipos de roles —personalizado, basado en Git y de sistema— en un único playbook, lo ejecutará para configurar el servidor y verificará la configuración resultante de Apache y SELinux para confirmar que la automatización fue exitosa.