Desplegar y Gestionar Archivos en RHEL con Ansible

AnsibleBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá las habilidades fundamentales para desplegar y gestionar archivos en un sistema Red Hat Enterprise Linux (RHEL) utilizando Ansible. Obtendrá experiencia práctica con algunos de los módulos de Ansible más comunes y potentes diseñados para operaciones de archivos, pasando del despliegue básico de archivos a la manipulación de contenido y la gestión de estados más avanzadas.

Comenzará utilizando el módulo ansible.builtin.copy para transferir un archivo estático y establecer sus atributos. A continuación, modificará el contenido de los archivos con lineinfile y blockinfile, y generará un MOTD personalizado utilizando el módulo ansible.builtin.template. El laboratorio también cubre la creación de enlaces simbólicos, la verificación de estados de archivos con stat, la recuperación de logs con fetch y la limpieza de archivos gestionados, proporcionando una visión completa de las capacidades de gestión de archivos de Ansible.

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 83%. Ha recibido una tasa de reseñas positivas del 100% por parte de los estudiantes.

Copiar un Archivo Estático y Establecer Atributos con el Módulo ansible.builtin.copy

En este paso, aprenderá a utilizar uno de los módulos de Ansible más fundamentales: ansible.builtin.copy. Este módulo se utiliza para transferir archivos desde su nodo de control (la VM de LabEx) a una ubicación especificada en sus hosts gestionados. En nuestro caso, el host gestionado será localhost en sí mismo. Más allá de la simple copia, el módulo copy le permite controlar con precisión los atributos del archivo, como su propietario, grupo y modo de permisos, lo cual es esencial para una configuración correcta del sistema.

Primero, configuremos nuestro entorno de proyecto. Todo nuestro trabajo se realizará dentro del directorio ~/project.

  1. Navegue al directorio del proyecto y cree un subdirectorio para nuestros archivos de origen. Esta es una práctica común para mantener su proyecto organizado.

    Instale el paquete ansible-core.

    sudo dnf install -y ansible-core

    Luego, navegue al directorio del proyecto y cree un subdirectorio para nuestros archivos de origen.

    cd ~/project
    mkdir files
  2. A continuación, cree un archivo de texto simple que copiaremos. Utilizaremos un comando cat con un "documento aquí" para crear el archivo info.txt dentro del directorio files.

    cat << EOF > ~/project/files/info.txt
    This file was deployed by Ansible.
    It contains important system information.
    EOF
  3. Ahora, cree un archivo de inventario de Ansible. El inventario le dice a Ansible qué hosts gestionar. Para este laboratorio, gestionaremos la máquina local. Cree un archivo llamado inventory.ini.

    cat << EOF > ~/project/inventory.ini
    localhost ansible_connection=local
    EOF

    En este inventario, localhost es el host al que nos dirigimos. La variable ansible_connection=local instruye a Ansible a ejecutar las tareas directamente en el nodo de control, sin usar SSH.

  4. Cree su primer playbook de Ansible. Este playbook contendrá las instrucciones para copiar el archivo. Use nano o cat para crear un archivo llamado copy_file.yml.

    nano ~/project/copy_file.yml

    Agregue el siguiente contenido al archivo. Este playbook define una tarea: copiar info.txt al directorio /tmp/ y establecer sus atributos.

    ---
    - name: Deploy a static file to localhost
      hosts: localhost
      tasks:
        - name: Copy info.txt and set attributes
          ansible.builtin.copy:
            src: files/info.txt
            dest: /tmp/info.txt
            owner: labex
            group: labex
            mode: "0640"

    Analicemos los parámetros en la tarea copy:

    • src: files/info.txt: La ruta al archivo de origen en el nodo de control, relativa a la ubicación del playbook.
    • dest: /tmp/info.txt: La ruta absoluta donde se colocará el archivo en el host gestionado.
    • owner: labex: Establece el propietario del archivo en el usuario labex.
    • group: labex: Establece el grupo del archivo en el grupo labex.
    • mode: '0640': Establece los permisos del archivo. 0640 significa que el propietario puede leer/escribir, el grupo puede leer y los demás no tienen permisos.
  5. Ejecute el playbook usando el comando ansible-playbook. La bandera -i especifica nuestro archivo de inventario.

    ansible-playbook -i inventory.ini copy_file.yml

    Debería ver una salida que indica la ejecución exitosa del playbook, similar a esta:

    PLAY [Deploy a static file to localhost] ***************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Copy info.txt and set attributes] ****************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  6. Finalmente, verifique que el archivo se copió correctamente y tiene los atributos correctos. Use el comando ls -l para verificar los permisos, el propietario y el grupo.

    ls -l /tmp/info.txt

    La salida debería mostrar que labex es el propietario y el grupo, y los permisos son -rw-r-----.

    -rw-r----- 1 labex labex 72 Jul 10 14:30 /tmp/info.txt

    También puede ver el contenido del archivo para asegurarse de que se copió completamente.

    cat /tmp/info.txt
    This file was deployed by Ansible.
    It contains important system information.

Ha utilizado con éxito el módulo ansible.builtin.copy para desplegar un archivo y configurar sus atributos en su sistema local.

Modificar Contenido de Archivos con lineinfile y blockinfile

En este paso, aprenderá a modificar archivos existentes en un host gestionado sin reemplazar el archivo completo. Ansible proporciona módulos potentes para este propósito: ansible.builtin.lineinfile para gestionar líneas individuales y ansible.builtin.blockinfile para gestionar bloques de texto de varias líneas. Estos son extremadamente útiles para tareas como cambiar configuraciones o agregar entradas a archivos de registro.

Continuaremos trabajando con el archivo info.txt que creó en el paso anterior, el cual se encuentra en /tmp/info.txt.

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

    cd ~/project
  2. Cree un nuevo playbook llamado modify_file.yml. Este playbook contendrá dos tareas: una para agregar una línea individual y otra para agregar un bloque de texto a nuestro archivo existente.

    nano ~/project/modify_file.yml
  3. Agregue el siguiente contenido a su playbook modify_file.yml. Este playbook se dirige a localhost y utiliza tanto lineinfile como blockinfile para agregar contenido a /tmp/info.txt.

    ---
    - name: Modify an existing file
      hosts: localhost
      tasks:
        - name: Add a single line of text to a file
          ansible.builtin.lineinfile:
            path: /tmp/info.txt
            line: This line was added by the lineinfile module.
            state: present
    
        - name: Add a block of text to an existing file
          ansible.builtin.blockinfile:
            path: /tmp/info.txt
            block: |
              ## BEGIN ANSIBLE MANAGED BLOCK
              This block of text consists of two lines.
              They have been added by the blockinfile module.
              ## END ANSIBLE MANAGED BLOCK
            state: present

    Examinemos los módulos utilizados:

    • ansible.builtin.lineinfile: Este módulo asegura que una línea específica esté presente en un archivo. Si la línea ya existe, Ansible no hace nada, lo que hace que la tarea sea idempotente.
      • path: El archivo a modificar.
      • line: La línea de texto que se debe asegurar que esté en el archivo.
      • state: present: Esto asegura que la línea exista. Podría usar state: absent para eliminarla.
    • ansible.builtin.blockinfile: Este módulo gestiona un bloque de texto, rodeado por líneas marcadoras (por ejemplo, ## BEGIN ANSIBLE MANAGED BLOCK). Esto es ideal para gestionar secciones de configuración.
      • path: El archivo a modificar.
      • block: La cadena de varias líneas a insertar. El | es sintaxis de YAML para un bloque literal, preservando los saltos de línea.
      • state: present: Asegura que el bloque exista.
  4. Ejecute el playbook usando el comando ansible-playbook y su archivo inventory.ini.

    ansible-playbook -i inventory.ini modify_file.yml

    La salida mostrará que ambas tareas realizaron cambios en el archivo.

    PLAY [Modify an existing file] *************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Add a single line of text to a file] *************************************
    changed: [localhost]
    
    TASK [Add a block of text to an existing file] *********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. Finalmente, verifique los cambios viendo el contenido de /tmp/info.txt.

    cat /tmp/info.txt

    Debería ver el contenido original, seguido de la nueva línea y el nuevo bloque de texto.

    This file was deployed by Ansible.
    It contains important system information.
    This line was added by the lineinfile module.
    ## BEGIN ANSIBLE MANAGED BLOCK
    This block of text consists of two lines.
    They have been added by the blockinfile module.
    ## END ANSIBLE MANAGED BLOCK

    Si ejecuta el playbook nuevamente, Ansible informará ok=3 y changed=0 porque el contenido ya está presente, lo que demuestra la naturaleza idempotente de estos módulos.

Generar un MOTD Personalizado con el Módulo ansible.builtin.template

En este paso, pasará de copiar archivos estáticos a generar archivos dinámicos utilizando el módulo ansible.builtin.template. Este módulo aprovecha el motor de plantillas Jinja2 para crear archivos personalizados con variables e información del sistema, conocidas como "facts" (hechos), que Ansible recopila de sus hosts gestionados. Crearemos un Mensaje del Día (MOTD) dinámico que muestre información específica del sistema.

  1. Primero, asegúrese de estar en el directorio ~/project y cree un subdirectorio dedicado para sus plantillas. Es una buena práctica estándar de Ansible almacenar las plantillas Jinja2 en un directorio templates.

    cd ~/project
    mkdir templates
  2. A continuación, cree el archivo de plantilla Jinja2. Este archivo, motd.j2, contendrá la estructura de nuestro MOTD, con marcadores de posición para datos dinámicos. La extensión .j2 es una convención común para las plantillas Jinja2.

    nano ~/project/templates/motd.j2

    Agregue el siguiente contenido al archivo. Observe la sintaxis {{ ... }}, que denota un marcador de posición para una variable o un fact.

    #################################################################
    ##          Welcome to {{ ansible_facts['fqdn'] }}
    #
    ## This is a {{ ansible_facts['distribution'] }} system.
    ## System managed by Ansible.
    #
    ## For support, contact: {{ admin_email }}
    #################################################################

    En esta plantilla:

    • {{ ansible_facts['fqdn'] }} será reemplazado por el Nombre de Dominio Completamente Cualificado (Fully Qualified Domain Name) del host.
    • {{ ansible_facts['distribution'] }} será reemplazado por el nombre de la distribución de Linux (por ejemplo, RedHat).
    • {{ admin_email }} es una variable personalizada que definiremos en nuestro playbook.
  3. Ahora, cree un nuevo playbook llamado template_motd.yml. Este playbook utilizará la plantilla para generar /etc/motd.

    nano ~/project/template_motd.yml

    Agregue el siguiente contenido. Este playbook requiere privilegios elevados (become: true) para escribir en el directorio /etc. También define la variable personalizada admin_email.

    ---
    - name: Deploy a custom MOTD from a template
      hosts: localhost
      become: true
      vars:
        admin_email: admin@labex.io
      tasks:
        - name: Generate /etc/motd from template
          ansible.builtin.template:
            src: templates/motd.j2
            dest: /etc/motd
            owner: root
            group: root
            mode: "0644"

    Parámetros clave en este playbook:

    • become: true: Esto le indica a Ansible que use sudo para ejecutar la tarea, lo cual es necesario para escribir en /etc/motd.
    • vars: Esta sección es donde definimos variables personalizadas, como admin_email.
    • ansible.builtin.template: El módulo que procesa la plantilla Jinja2. src apunta a nuestro archivo .j2, y dest es el archivo de destino en el host gestionado.
  4. Ejecute el playbook.

    ansible-playbook -i inventory.ini template_motd.yml

    La salida debería confirmar que la tarea fue exitosa.

    PLAY [Deploy a custom MOTD from a template] ************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Generate /etc/motd from template] ****************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. Verifique el resultado. Compruebe el contenido del archivo /etc/motd recién generado.

    cat /etc/motd

    Verá la salida renderizada, con los marcadores de posición de Jinja2 reemplazados por los facts reales del sistema y la variable personalizada que definió. El fqdn coincidirá con el nombre de host de su entorno de laboratorio.

    #################################################################
    ##          Welcome to host.labex.io
    #
    ## This is a RedHat system.
    ## System managed by Ansible.
    #
    ## For support, contact: admin@labex.io
    #################################################################

Ahora ha utilizado con éxito una plantilla para crear un archivo personalizado, una habilidad fundamental en la automatización de la infraestructura.

Desplegar Archivos de Soporte y Crear un Enlace Simbólico con copy y file

En este paso, combinará su conocimiento del módulo copy con un nuevo y versátil módulo: ansible.builtin.file. Mientras que copy se utiliza para transferir contenido, file se usa para gestionar el estado de archivos, directorios y enlaces simbólicos en el host gestionado. Lo utilizará para crear directorios, establecer permisos y, lo más importante para este ejercicio, crear enlaces simbólicos.

Nuestro escenario es configurar los mensajes previos al inicio de sesión que muestra el sistema. En muchos sistemas Linux, /etc/issue se muestra a los usuarios de terminal local, y /etc/issue.net se muestra a los usuarios remotos (como a través de SSH). Desplegaremos un único archivo issue y luego crearemos un enlace simbólico para que /etc/issue.net apunte a /etc/issue, asegurando que siempre muestren el mismo mensaje.

  1. Primero, asegúrese de estar en el directorio ~/project y cree el archivo de origen para nuestro mensaje de issue. Colocaremos este archivo en el subdirectorio files que creó anteriormente.

    cd ~/project
    cat << EOF > ~/project/files/issue
    Authorized access only.
    All connections are logged and monitored.
    EOF
  2. Cree un nuevo playbook llamado deploy_issue.yml. Este playbook contendrá dos tareas: una para copiar el archivo issue y otra para crear el enlace simbólico.

    nano ~/project/deploy_issue.yml
  3. Agregue el siguiente contenido a su playbook deploy_issue.yml. Este playbook requiere privilegios elevados (become: true) para gestionar archivos en el directorio /etc/.

    ---
    - name: Configure system issue files
      hosts: localhost
      become: true
      tasks:
        - name: Copy custom /etc/issue file
          ansible.builtin.copy:
            src: files/issue
            dest: /etc/issue
            owner: root
            group: root
            mode: "0644"
    
        - name: Ensure /etc/issue.net is a symlink to /etc/issue
          ansible.builtin.file:
            src: /etc/issue
            dest: /etc/issue.net
            state: link
            force: yes

    Analicemos la nueva tarea ansible.builtin.file:

    • src: /etc/issue: Cuando state es link, src especifica el archivo al que debe apuntar el enlace simbólico.
    • dest: /etc/issue.net: Esta es la ruta donde se creará el enlace simbólico en sí.
    • state: link: Este parámetro crucial le indica al módulo file que cree un enlace simbólico, no un archivo o directorio regular.
    • force: yes: Esta es una opción útil que garantiza la idempotencia. Si /etc/issue.net ya existe como un archivo regular, Ansible lo eliminará y creará el enlace. Sin force: yes, el playbook fallaría en esa situación.
  4. Ejecute el playbook.

    ansible-playbook -i inventory.ini deploy_issue.yml

    La salida mostrará que ambas tareas realizaron cambios exitosamente.

    PLAY [Configure system issue files] ********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Copy custom /etc/issue file] *********************************************
    changed: [localhost]
    
    TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. Verifique el resultado usando el comando ls -l. Este comando proporciona una lista detallada que muestra claramente los enlaces simbólicos.

    ls -l /etc/issue /etc/issue.net

    La salida debería mostrar que /etc/issue es un archivo regular y /etc/issue.net es un enlace simbólico que apunta a él. La l al principio de los permisos para /etc/issue.net indica que es un enlace.

    -rw-r--r--. 1 root root 65 Jul 10 15:00 /etc/issue
    lrwxrwxrwx. 1 root root 10 Jul 10 15:00 /etc/issue.net -> /etc/issue

Ahora ha desplegado con éxito un archivo de configuración y ha utilizado el módulo ansible.builtin.file para crear un enlace simbólico, un patrón común y potente para gestionar configuraciones del sistema.

Verificar Estado de Archivos con stat y Obtener Logs con fetch

En este paso, aprenderá sobre dos módulos importantes de recopilación de datos: ansible.builtin.stat y ansible.builtin.fetch. El módulo stat se utiliza para comprobar el estado de un archivo o directorio en un host gestionado; por ejemplo, para ver si existe, cuáles son sus permisos o cuándo fue modificado por última vez. No cambia nada, lo que lo hace perfecto para comprobaciones y lógica condicional. El módulo fetch hace lo contrario de copy: recupera archivos desde el host gestionado y los guarda en su nodo de control, lo que es ideal para hacer copias de seguridad de configuraciones o recopilar archivos de log para su análisis.

Crearemos un playbook que primero comprueba la existencia del archivo /etc/motd que creó anteriormente, y luego recupera el archivo de log del gestor de paquetes DNF (/var/log/dnf.log) a un directorio local en su VM de LabEx.

  1. Primero, asegúrese de estar en el directorio ~/project y cree un nuevo subdirectorio para almacenar los archivos que recuperará.

    cd ~/project
    mkdir fetched_logs
  2. Cree un nuevo playbook llamado check_and_fetch.yml. Este playbook contendrá las tareas para comprobar el archivo y recuperar el log.

    nano ~/project/check_and_fetch.yml
  3. Agregue el siguiente contenido a su playbook check_and_fetch.yml. Este playbook utiliza stat para obtener detalles del archivo, register para almacenar esos detalles en una variable, debug para mostrar la variable y fetch para recuperar el archivo de log.

    ---
    - name: Check file status and fetch logs
      hosts: localhost
      become: true
      tasks:
        - name: Check if /etc/motd exists
          ansible.builtin.stat:
            path: /etc/motd
          register: motd_status
    
        - name: Display stat results
          ansible.builtin.debug:
            var: motd_status.stat
    
        - name: Fetch the dnf log file from managed host
          ansible.builtin.fetch:
            src: /var/log/dnf.log
            dest: fetched_logs/
            flat: yes

    Analicemos los conceptos clave:

    • register: motd_status: Esta es una característica crucial de Ansible. Toma toda la salida de una tarea y la guarda en una nueva variable llamada motd_status.
    • ansible.builtin.debug: Este módulo se utiliza para imprimir valores durante la ejecución de un playbook. Aquí, imprimimos el objeto stat dentro de nuestra variable registrada (motd_status.stat) para ver las propiedades del archivo.
    • ansible.builtin.fetch: Este módulo recupera un archivo del host gestionado.
      • src: La ruta del archivo a recuperar del host gestionado.
      • dest: El directorio en el nodo de control (su VM de LabEx) donde se guardará el archivo.
      • flat: yes: Por defecto, fetch crea una estructura de subdirectorios que coincide con el host y la ruta de origen. flat: yes simplifica esto copiando el archivo directamente en el directorio dest sin subdirectorios adicionales.
  4. Ejecute el playbook. Dado que estamos leyendo un archivo de log del sistema, se utiliza become: true para obtener los permisos necesarios.

    ansible-playbook -i inventory.ini check_and_fetch.yml

    La salida mostrará los resultados de la comprobación stat en la tarea de depuración, seguida de la tarea fetch.

    PLAY [Check file status and fetch logs] ****************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Check if /etc/motd exists] ***********************************************
    ok: [localhost]
    
    TASK [Display stat results] ****************************************************
    ok: [localhost] => {
        "motd_status.stat": {
            "exists": true,
            "gid": 0,
            "isreg": true,
            "mode": "0644",
            "path": "/etc/motd",
            ...
        }
    }
    
    TASK [Fetch the dnf log file from managed host] ********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. Verifique que el archivo de log se recuperó correctamente. Liste el contenido del directorio fetched_logs.

    ls -l ~/project/fetched_logs/

    Debería ver el archivo dnf.log, ahora almacenado localmente en su nodo de control.

    total 4
    -rw-r--r--. 1 labex labex 1234 Jul 10 15:30 dnf.log

Ahora ha aprendido a inspeccionar las propiedades de los archivos sin realizar cambios y a recuperar archivos importantes de sus sistemas gestionados a su nodo de control.

Limpiar Archivos del Host Gestionado con el Módulo file

En este último paso, aprenderá a utilizar el módulo ansible.builtin.file para asegurarse de que los archivos y directorios no estén presentes en un sistema. Una parte fundamental de la gestión de la configuración no es solo crear y modificar recursos, sino también limpiarlos. Al establecer el parámetro state en absent, puede indicar a Ansible que elimine archivos, enlaces simbólicos o incluso directorios completos.

Para concluir este laboratorio, escribiremos un único playbook de "limpieza" que eliminará todos los artefactos que creamos en los pasos anteriores: /tmp/info.txt, /etc/motd, /etc/issue y el enlace simbólico /etc/issue.net.

  1. Primero, asegúrese de estar en el directorio ~/project.

    cd ~/project
  2. Cree un nuevo playbook llamado cleanup.yml. Este playbook contendrá todas las tareas necesarias para revertir nuestros cambios.

    nano ~/project/cleanup.yml
  3. Agregue el siguiente contenido a su playbook cleanup.yml. Este playbook utiliza una lista de tareas, cada una dirigida a uno de los archivos que creamos. Tenga en cuenta que become: true se establece en el nivel del play, por lo que todas las tareas se ejecutarán con privilegios elevados.

    ---
    - name: Clean up managed files from the system
      hosts: localhost
      become: true
      tasks:
        - name: Remove the temporary info file
          ansible.builtin.file:
            path: /tmp/info.txt
            state: absent
    
        - name: Remove the custom MOTD file
          ansible.builtin.file:
            path: /etc/motd
            state: absent
    
        - name: Remove the custom issue file
          ansible.builtin.file:
            path: /etc/issue
            state: absent
    
        - name: Remove the issue.net symbolic link
          ansible.builtin.file:
            path: /etc/issue.net
            state: absent

    La clave de este playbook es el parámetro state: absent en cada tarea. Esto le indica al módulo file que se asegure de que el elemento en la path especificada no exista. Si encuentra el archivo, lo eliminará. Si el archivo ya no está, no hará nada, manteniendo la idempotencia.

  4. Ejecute el playbook de limpieza.

    ansible-playbook -i inventory.ini cleanup.yml

    La salida mostrará que cada tarea realizó con éxito un cambio al eliminar un archivo.

    PLAY [Clean up managed files from the system] **********************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Remove the temporary info file] ******************************************
    changed: [localhost]
    
    TASK [Remove the custom MOTD file] *********************************************
    changed: [localhost]
    
    TASK [Remove the custom issue file] ********************************************
    changed: [localhost]
    
    TASK [Remove the issue.net symbolic link] **************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. Verifique que los archivos han sido eliminados. Puede usar el comando ls para comprobar su existencia. El comando informará que no puede acceder a ellos porque ya no están.

    ls /tmp/info.txt /etc/motd /etc/issue /etc/issue.net

    La salida esperada es una serie de errores, lo que confirma que la limpieza fue exitosa.

    ls: cannot access '/tmp/info.txt': No such file or directory
    ls: cannot access '/etc/motd': No such file or directory
    ls: cannot access '/etc/issue': No such file or directory
    ls: cannot access '/etc/issue.net': No such file or directory

Ahora ha utilizado con éxito Ansible para eliminar archivos y limpiar un sistema, completando el ciclo de vida completo de la gestión de archivos desde la creación hasta la eliminación.

Resumen

En este laboratorio, aprendió los fundamentos de la gestión de archivos en sistemas RHEL utilizando Ansible. Comenzó utilizando el módulo ansible.builtin.copy para transferir un archivo estático a un host gestionado mientras establecía la propiedad y los permisos específicos. Luego exploró cómo modificar archivos existentes asegurando que una línea específica esté presente con lineinfile y gestionando bloques de texto de varias líneas con blockinfile. Una habilidad clave cubierta fue la generación de contenido de archivos dinámico utilizando el módulo ansible.builtin.template y la sintaxis Jinja2 para crear un Mensaje del Día (MOTD) personalizado poblado con hechos del sistema.

Además, practicó el despliegue de archivos de soporte y la creación de enlaces simbólicos utilizando el módulo ansible.builtin.file. Para garantizar el éxito de sus despliegues, utilizó el módulo stat para verificar el estado y los atributos de los archivos y el módulo fetch para recuperar archivos, como logs, del host gestionado al nodo de control. Finalmente, aprendió a realizar operaciones de limpieza utilizando el módulo file con state: absent para eliminar los archivos y directorios creados durante el laboratorio, asegurando un estado limpio en el host gestionado.