Administrar paquetes y un servicio funcional

AnsibleBeginner
Practicar Ahora

Introducción

Que un paquete esté instalado, que exista un archivo de configuración y que un servicio responda son resultados distintos. Administrarás cada uno explícitamente: instalarás y eliminarás una utilidad, configurarás nginx, declararás su estado de ejecución y recargarás la configuración modificada mediante un handler. Las respuestas HTTP reales de ambos nodos administrados demostrarán que el servicio funciona.

Declarar estados de paquetes instalados y ausentes

En este paso, instalarás una pequeña utilidad, la inspeccionarás y la eliminarás mediante una declaración reutilizable de paquetes.

El módulo apt administra paquetes de Ubuntu en el host administrado. Su state: present solicita la instalación y state: absent solicita la eliminación. Este entorno incluye listas de paquetes preparadas y descargas en caché, así que mantén update_cache: false; actualizar las listas o solicitar las versiones más recientes añadiría dependencias de red innecesarias. Las políticas de actualización de producción pueden ser distintas.

Entra en el proyecto del controlador:

cd /home/labex/project

Crea un playbook cuya variable seleccione el estado deseado del paquete tree. Las operaciones de paquetes requieren become en los destinos. install_recommends: false evita los paquetes recomendados opcionales.

cat > packages.yml <<'YAML'
- name: Declare a utility package state
  hosts: all
  gather_facts: false
  become: true
  vars:
    utility_state: present
  tasks:
    - name: Converge the tree package
      ansible.builtin.apt:
        name: tree
        state: "{{ utility_state }}"
        update_cache: false
        install_recommends: false
YAML

Instala la utilidad:

ansible-playbook packages.yml

El comando tree muestra árboles de directorios; aquí su opción de versión demuestra que el ejecutable está realmente instalado en cada nodo administrado:

ansible all -m ansible.builtin.command -a 'tree --version'

Cada destino debería devolver una versión de tree. Repite el playbook; los paquetes presentes no deberían necesitar otra instalación:

ansible-playbook packages.yml

Ahora solicita la ausencia con una variable extra en lugar de editar la tarea reutilizable:

ansible-playbook packages.yml -e utility_state=absent

Repite el mismo estado deseado de ausencia. Ambas filas del resumen deberían mostrar ahora changed=0, failed=0 y unreachable=0:

ansible-playbook packages.yml -e utility_state=absent

El estado del paquete es una declaración sobre la instalación, no una prueba de que un servicio esté en ejecución o respondiendo. Deja tree ausente mientras el siguiente paso despliega nginx.

Configurar e iniciar un servicio web real

En este paso, instalarás nginx, desplegarás una configuración completa validada y mantendrás explícitamente su servicio en ejecución.

Los dos nodos administrados son contenedores con destinos SSH y sistemas de archivos separados. No ejecutan systemd. El módulo service usa su gestor de servicios disponible; no ejecutes systemctl en estos destinos. Administraremos el estado actual de ejecución en lugar de prometer una política de arranque de systemd.

Crea una página estática en el controlador. Termina con un salto de línea para que sus bytes administrados exactos sean predecibles:

printf 'Ansible service ready\n' > page.txt

Escribe una configuración completa de nginx. events y http son contextos de nivel superior de nginx, server define un sitio web, listen elige el puerto 8080, root selecciona su directorio de documentos e index selecciona la página para las solicitudes /. Son ajustes de nginx, no YAML de Ansible.

cat > nginx-course.conf <<'NGINX'
events {}
http {
    server {
        listen 8080;
        root /var/www/ansible-site;
        index index.html;
    }
}
NGINX

Crea el playbook de despliegue. La tarea apt usa policy_rc_d: 101 para impedir que el instalador de paquetes inicie nginx implícitamente; la tarea service posterior declara explícitamente el estado en ejecución. El validate de la tarea copy ejecuta la prueba de configuración de nginx sobre un candidato temporal (%s) antes de sustituir el destino.

Un handler es una acción con nombre que figura bajo handlers. Una tarea de configuración con cambios notifica a Reload nginx, que se ejecuta una vez al final del play. Si no hay cambio de configuración, no hay notificación. La tarea service normal usa started, que mantiene en ejecución un servicio ya iniciado sin un reinicio incondicional.

cat > web.yml <<'YAML'
- name: Deploy a working web service
  hosts: all
  gather_facts: false
  become: true
  tasks:
    - name: Install nginx without refreshing the prepared package lists
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: false
        install_recommends: false
        policy_rc_d: 101

    - name: Prepare the site directory
      ansible.builtin.file:
        path: /var/www/ansible-site
        state: directory
        owner: root
        group: root
        mode: "0755"

    - name: Deploy the static page
      ansible.builtin.copy:
        src: /home/labex/project/page.txt
        dest: /var/www/ansible-site/index.html
        owner: root
        group: root
        mode: "0644"

    - name: Validate and deploy nginx configuration
      ansible.builtin.copy:
        src: /home/labex/project/nginx-course.conf
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: "0644"
        validate: /usr/sbin/nginx -t -c %s
      notify: Reload nginx

    - name: Keep nginx running
      ansible.builtin.service:
        name: nginx
        state: started

  handlers:
    - name: Reload nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded
YAML

Comprueba la sintaxis y después aplica el despliegue:

ansible-playbook web.yml --syntax-check
ansible-playbook web.yml

Ambos nodos deberían instalar nginx, recibir los archivos e iniciarse correctamente. Un primer cambio de configuración también programa el handler de recarga. Comprobar únicamente la versión de un paquete no demostraría nada de ese comportamiento del servicio.

curl es un cliente HTTP. Su opción --fail trata un estado HTTP no satisfactorio como un fallo del comando; --silent elimina la salida de progreso y --show-error conserva los detalles del fallo. Ejecútalo en cada host administrado contra la propia interfaz de bucle local de ese host:

ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error http://127.0.0.1:8080/'

Cada resultado debería contener Ansible service ready. El controlador y cada destino tienen interfaces de bucle local separadas; este comando comprueba ambos servicios de destino en lugar del controlador.

Aplicar un cambio de configuración mediante un handler

En este paso, cambiarás un ajuste activo de nginx, observarás el handler y confirmarás el ajuste mediante una respuesta HTTP.

La directiva server_tokens de nginx controla si las cabeceras de respuesta muestran la versión de nginx. Añade server_tokens off dentro de http sustituyendo la configuración del controlador por esta versión completa:

cat > nginx-course.conf <<'NGINX'
events {}
http {
    server_tokens off;
    server {
        listen 8080;
        root /var/www/ansible-site;
        index index.html;
    }
}
NGINX

Aplica el mismo playbook:

ansible-playbook web.yml

La copia de configuración debería informar changed y notificar a Reload nginx en ambos hosts. El handler recarga el servicio en ejecución después de que la nueva configuración supere la validación. Su ejecución hace efectiva la configuración; limitarse a copiar un archivo no demuestra qué ha cargado el proceso.

-I de curl solicita cabeceras HTTP. Inspecciona la respuesta real del servicio en ambos hosts:

ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error -I http://127.0.0.1:8080/'

Ambas respuestas deberían tener un estado HTTP satisfactorio y una cabecera Server con nginx sin un sufijo de versión. Otros campos de las cabeceras, como las fechas, varían.

Repite el playbook completo:

ansible-playbook web.yml

Ambos hosts deberían informar changed=0 sin tareas fallidas ni inaccesibles, y no debería programarse ningún handler de recarga. La página estática sigue disponible, tree sigue ausente y nginx sigue instalado y en ejecución.

Resumen

Has declarado la presencia y ausencia de paquetes, separado la instalación del estado de ejecución del servicio y desplegado una configuración completa de nginx con validación del candidato. Una configuración modificada notificó a un handler de recarga, las respuestas HTTP reales demostraron el comportamiento activo y una repetición sin cambios evitó cambios o recargas adicionales.