Ansible

Ansible es una potente herramienta de automatización de código abierto que simplifica la gestión de configuraciones, la implementación de aplicaciones y la orquestación de tareas en entornos informáticos. A diferencia de otras herramientas similares, Ansible opera sin necesidad de instalar agentes en los sistemas que administra, lo que reduce la complejidad y el mantenimiento.

Su funcionamiento se basa en la creación de "playbooks", archivos escritos en YAML que describen el estado deseado de los sistemas y las tareas a realizar. Ansible se conecta a los servidores a través de SSH (en sistemas Linux/Unix) o WinRM (en Windows) y ejecuta los módulos definidos en los playbooks para lograr la configuración deseada. Esta arquitectura sin agentes y su lenguaje declarativo hacen de Ansible una herramienta versátil y fácil de usar para automatizar una amplia gama de tareas de TI.

¿Para qué sirve?

Ansible se usa para automatizar:

  • 🎮 Configuración de servidores (como instalar paquetes o cambiar archivos de configuración).
  • 🎮 Despliegue de aplicaciones.
  • 🎮 Orquestación de tareas entre múltiples sistemas.
  • 🎮 Gestión de usuarios, servicios y actualizaciones.
  • 🎮 Integración con la nube (AWS, GCP, Azure, etc).

Todo esto a través de playbooks escritos en YAML, lo que lo hace muy legible y fácil de versionar.

Arquitectura

Ansible, una herramienta de automatización de código abierto, destaca por su modelo push sin agentes, donde un nodo de control se conecta vía SSH a los hosts definidos en un inventario para ejecutar tareas, lo que simplifica la gestión al eliminar la necesidad de instalar software en los nodos remotos. A pesar de su simplicidad, Ansible cuenta con una arquitectura robusta, compuesta por componentes esenciales que trabajan conjuntamente para permitir la automatización eficiente y segura de diversas tareas en entornos informáticos.

Nodo de Control (Control Node)

Este es el punto central desde donde se ejecutan todos los comandos y playbooks. Es la máquina que tiene Ansible instalado y desde la cual se orquesta todo. Puede ser una laptop, servidor o contenedor, siempre que tenga acceso SSH a los nodos gestionados.

  • ◈ No requiere instalar software en los destinos.
  • ◈ Es donde escribes y ejecutas tus playbooks.
  • ◈ Solo un nodo de control es necesario para manejar cientos o miles de hosts.
Inventario (Inventory)

El inventario es un archivo que define los hosts o grupos de hosts sobre los cuales Ansible va a ejecutar tareas. Puede ser estático (archivo INI o YAML) o dinámico (generado desde scripts o nubes como AWS, GCP, Azure).

⌭ Ejemplo:

[webservers] 192.168.1.10 192.168.1.11 [db] dbserver ansible_host=192.168.1.20

Ansible usa esta información para conectarse a los hosts usando SSH, y para aplicar tareas en grupos específicos.

Playbooks

Los playbooks son archivos escritos en YAML que definen qué tareas deben ejecutarse en qué hosts. Representan el corazón de la automatización en Ansible, y permiten definir flujos de trabajo complejos de manera ordenada y legible.

Cada playbook contiene:

  • ◈ Un grupo de hosts.
  • ◈ Privilegios (como become: true para sudo).
  • ◈ Una lista ordenada de tareas.
  • ◈ Variables y condicionales.
Módulos

Los módulos son unidades de trabajo reutilizables que ejecutan tareas específicas, como instalar paquetes, copiar archivos, crear usuarios, reiniciar servicios, etc. Ansible tiene cientos de módulos integrados, y puedes crear los tuyos propios.

Ejemplos de módulos comunes:

  • apt, yum, dnf → Instalación de paquetes.
  • copy, template → Archivos.
  • user, group → Gestión de usuarios.
  • service → Control de servicios.

Se ejecutan en los hosts remotos y son idempotentes: si algo ya está hecho, no se vuelve a aplicar.


La documentación oficial de Ansible, es la fuente principal para obtener información detallada sobre los módulos disponibles, incluyendo descripciones exhaustivas y ejemplos prácticos de uso.

También puedes utilizar el comando ansible-doc en tu línea de comandos para obtener información sobre los módulos disponibles.

Comando ansible-doc para listar todos los módulos disponibles:
Comando ansible-doc para obtener información de un módulo específico:
Roles

En Ansible, los roles son una forma estructurada y reutilizable de organizar código. Permiten dividir una automatización compleja en piezas pequeñas, modulares y fáciles de mantener. Cada rol se encarga de una funcionalidad específica (como instalar Apache, configurar un firewall o gestionar usuarios).

Se usan principalmente para:

  • ◈ Modularizar proyectos grandes.
  • ◈ Reutilizar código entre diferentes playbooks.
  • ◈ Establecer una convención estándar de carpetas.

Cuando usas un rol, Ansible carga automáticamente sus tareas, archivos, variables, templates y handlers.

⌭ Estructura de un rol:

roles/ └── nombre_del_rol/ ├── defaults/ → Variables por defecto (más débiles) │ └── main.yml ├── vars/ → Variables fuertes (sobrescriben a defaults) │ └── main.yml ├── files/ → Archivos que se copian tal cual ├── templates/ → Archivos .j2 que usan variables ├── tasks/ → Lista principal de tareas │ └── main.yml ├── handlers/ → Acciones que se ejecutan tras cambios (ej: reiniciar) ├── meta/ → Dependencias con otros roles └── README.md → Documentación del rol

Los roles más comunes o recomendados al diseñar infraestructuras automatizadas son:

  • Roles de sistema operativo
    • os_hardening: seguridad del sistema.
    • common: ajustes básicos como timezone, idioma, hostname, usuarios.
  • Roles de red y conectividad
    • firewall: gestión de reglas iptables o firewalld.
    • dns_client: configurar DNS y resolv.conf.
    • ntp: sincronización horaria.
  • Roles de herramientas
    • docker: instalación y configuración del engine.
    • kubernetes: instalación del clúster.
    • monitoring: configuración de Prometheus, Grafana, etc.
  • Roles de aplicaciones
    • nginx, apache, haproxy: servidores web o balanceadores.
    • mysql, postgres, mongodb: bases de datos.
    • app_deploy: despliegue de aplicaciones personalizadas.
  • Roles de seguridad
    • fail2ban: protección contra fuerza bruta.
    • ssh_hardening: políticas de acceso remoto.
    • users: crear y gestionar usuarios seguros.

La arquitectura de Ansible, basada en roles, promueve una clara separación de responsabilidades, lo que resulta en un código más limpio y fácil de mantener. Esta modularidad facilita la reutilización de configuraciones entre distintos proyectos o entornos, optimizando el tiempo y el esfuerzo invertido en la automatización. Además, Ansible Galaxy permite compartir estos roles con otros equipos o incluso con la comunidad global, fomentando la colaboración y la adopción de mejores prácticas.

Plugins

Ansible tiene plugins para extender funcionalidades. Algunos tipos son:

  • Connection Plugins: controlan cómo Ansible se conecta a los hosts (ej. ssh, local, paramiko).
  • Callback Plugins: definen cómo se muestra la salida (por ejemplo, en JSON o en formato legible).
  • Lookup Plugins: permiten acceder a datos externos, como contraseñas o inventarios dinámicos.
Ansible Vault

Aunque no es obligatorio, ansible-vault permite encriptar archivos sensibles como contraseñas, claves o tokens. Se integra directamente con los playbooks y evita guardar secretos en texto plano.

Cifrar un archivo con Ansible Vault:
Ansible Galaxy

Ansible Galaxy es un repositorio en línea que sirve como una plataforma centralizada para compartir y descubrir contenido de Ansible. Principalmente, alberga "roles" y "colecciones", que son unidades preempaquetadas de código Ansible diseñadas para simplificar la automatización de tareas complejas. Los roles y colecciones permiten a los usuarios reutilizar configuraciones y mejores prácticas, acelerando así el desarrollo y la implementación de automatizaciones.

En resumen, Ansible Galaxy es el repositorio donde la comunidad comparte roles ya listos para usar. Algunos ejemplos populares:

Rol Descripción
geerlingguy.mysql Instala y configura MySQL/MariaDB.
geerlingguy.apache Configura servidores Apache.
nginxinc.nginx Rol oficial de NGINX para configurar y administrar.
dev-sec.os-hardening Aplica políticas de seguridad al sistema operativo.
elastic.elasticsearch Implementa un clúster de Elasticsearch.
ansible-role-docker Instala y configura Docker Engine.
Se instalan así:

Y luego los llamas desde tu playbook.

Nodos Gestionados (Managed Nodes)

Son los servidores o dispositivos que Ansible administra. No requieren instalar ningún software adicional: basta con que tengan SSH y Python. Las tareas se ejecutan desde el nodo de control hacia ellos.

Pueden ser:

  • ◈ Servidores Linux
  • ◈ Equipos Windows (usando WinRM)
  • ◈ Equipos de red (switches, routers, firewalls)
  • ◈ Entornos cloud

El flujo de ejecución de Ansible comienza con la invocación de un ansible-playbook, que actúa como el punto de entrada para la automatización. El nodo de control, donde se ejecuta Ansible, procede a leer el inventario, un archivo que define los hosts gestionados y sus agrupaciones, esencial para determinar a qué sistemas se aplicarán las tareas. A continuación, Ansible carga los playbooks, archivos YAML que describen el estado deseado de los sistemas y las tareas a realizar, junto con las variables y roles necesarios para la configuración. La conexión con los nodos gestionados se establece mediante SSH, un protocolo seguro que permite la ejecución remota de comandos. Las tareas definidas en los playbooks se ejecutan secuencialmente, utilizando módulos de Ansible que realizan acciones específicas en los sistemas remotos. Una característica clave de Ansible es su idempotencia: los cambios se aplican solo si son necesarios, evitando modificaciones innecesarias y asegurando la consistencia del sistema. Finalmente, Ansible muestra el resultado de la ejecución, incluyendo cualquier error que haya ocurrido, proporcionando una visión clara del estado de la automatización.

Comandos básicos

Instala Ansible en el sistema Ubuntu:
Verifica la conectividad SSH a todos los hosts definidos en el inventario:
Ejecuta el comando "uptime" en los hosts del grupo "web":
Ejecuta el playbook "apache.yml" en los hosts definidos en el inventario:

Configuración

❏ Crear un archivo Dockerfile:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~nano ContainerFile
FROM ubuntu:latest # Instala OpenSSH y Ansible RUN apt-get update && apt-get install -y openssh-server openssh-client sudo ansible procps nano less net-tools iputils-ping # Configura el usuario ansible RUN useradd -ms /bin/bash ansible && echo "ansible:ansible" | chpasswd && echo 'ansible ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers # Permite login por contraseña RUN sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config && \ sed -i 's/#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]

❏ Construye la imagen.

Creación de una imagen de Fedora con la configuración básica:
Verificar que la imagen existe:
Crea una red Docker personalizada (modo bridge):
Verificar la red:

❏ Crear los contenedores.

Lanza 3 contenedores, cada uno con un puerto SSH distinto (nodo1 2221, nodo2 2222 y nodo3 2223):
Verificar las IPs:

Como estás usando Podman, todos los contenedores estarán en la red podman por defecto y ya tienen NAT a tu host, por lo tanto no necesitas una red personalizada.

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 14e57979967e registry.fedoraproject.org/fedora:latest sleep infinity 5 minutes ago Up 5 minutes 0.0.0.0:2221->22/tcp nodo1 7a8e438784a7 registry.fedoraproject.org/fedora:latest sleep infinity About a minute ago Up About a minute 0.0.0.0:2222->22/tcp nodo2 161965d9d0a5 registry.fedoraproject.org/fedora:latest sleep infinity 56 seconds ago Up 57 seconds 0.0.0.0:2223->22/tcp nodo3

❏ Verificar la conexión en los contenedores.

Entrar al contenedor:

Añadir al usuario ansible al grupo sudo:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~visudo
## The COMMANDS section may have other options added to it. ## ## Allow root to run any commands anywhere root ALL=(ALL) ALL ansible ALL=(ALL) ALL

La configuración que aplicada al usuario "ansible" le otorga privilegios de superusuario a través de sudo, lo que significa que puede ejecutar cualquier comando en el sistema sin restricciones, similar a lo que haría el usuario "root". Esto es crucial en entornos de automatización como Ansible, donde se requiere acceso completo al sistema para realizar tareas de configuración y administración. Sin embargo, esta configuración también conlleva riesgos de seguridad significativos si no se implementa y controla adecuadamente, ya que cualquier error o acceso no autorizado podría comprometer la integridad del sistema.

Arrancar el servicio sshd:

Es importante recordar que el servicio SSH (sshd) debe estar en ejecución dentro de cada contenedor para permitir conexiones remotas. Por lo tanto, se debe asegurar que el servicio SSH se inicie correctamente en todos los contenedores que requieran acceso remoto a través de SSH.

Cambiar la contraseña del usuario root:

En la configuración proporcionada, tanto el usuario "root" como el usuario "ansible" poseen privilegios y contraseñas equivalentes para operar el servicio de Ansible. Esto se debe a que se ha configurado al usuario "ansible" con la capacidad de ejecutar cualquier comando mediante sudo sin necesidad de contraseña, y se ha establecido la misma contraseña ("ansible") para ambos usuarios. Por lo tanto, cualquier operación o tarea que pueda realizarse con el usuario "root" también puede llevarse a cabo con el usuario "ansible", lo que facilita la automatización y administración del sistema a través de Ansible.

Conectarse por SSH:

❏ Preparar la conexión entre nodos.

ansible-doc es una herramienta de Ansible que se utiliza para mostrar la documentación de módulos, plugins y otros componentes de Ansible.

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible-doc -l
amazon.aws.autoscaling_group amazon.aws.autoscaling_group_info amazon.aws.aws_az_info amazon.aws.aws_caller_info amazon.aws.aws_region_info amazon.aws.backup_plan amazon.aws.backup_plan_info amazon.aws.backup_restore_job_info amazon.aws.backup_selection amazon.aws.backup_selection_info amazon.aws.backup_tag amazon.aws.backup_tag_info amazon.aws.backup_vault amazon.aws.backup_vault_info amazon.aws.cloudformation amazon.aws.cloudformation_info amazon.aws.cloudtrail amazon.aws.cloudtrail_info amazon.aws.cloudwatch_metric_alarm amazon.aws.cloudwatch_metric_alarm_info amazon.aws.cloudwatchevent_rule amazon.aws.cloudwatchlogs_log_group amazon.aws.cloudwatchlogs_log_group_info . . . [ snip ] . . .
Generar claves SSH:
Copiar clave SSH pública al servidor remoto:

Para poder enviar la clave SSH a los otros nodos (nodo2 y nodo3) y permitir la autenticación sin contraseña, es fundamental que la contraseña del usuario "root" haya sido modificada en todos los contenedores. Esto se debe a que ssh-copy-id requiere autenticarse inicialmente con la contraseña para copiar la clave pública SSH al archivo authorized_keys de los nodos remotos (nodo2: <ip_nodo2>, nodo3: <ip_nodo3>). Una vez que la clave pública se ha copiado correctamente, se podrán establecer conexiones SSH sin necesidad de ingresar la contraseña.

❏ Editar el archivo que asigna nombres de host a direcciones IP (nano /etc/hosts) en el nodo de control (nodo1):

192.168.1.68 host.containers.internal host.docker.internal 10.89.0.13 e27ceca2da38 nodo1 10.89.0.14 7d96d7e0d90b nodo2 10.89.0.15 6132a20cf403 nodo3

❏ Verificar la conexión:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ping nodo2
PING 7d96d7e0d90b (10.89.0.14) 56(84) bytes of data. 64 bytes from 7d96d7e0d90b (10.89.0.14): icmp_seq=1 ttl=64 time=0.037 ms 64 bytes from 7d96d7e0d90b (10.89.0.14): icmp_seq=2 ttl=64 time=0.042 ms 64 bytes from 7d96d7e0d90b (10.89.0.14): icmp_seq=3 ttl=64 time=0.044 ms 64 bytes from 7d96d7e0d90b (10.89.0.14): icmp_seq=4 ttl=64 time=0.046 ms 64 bytes from 7d96d7e0d90b (10.89.0.14): icmp_seq=5 ttl=64 time=0.044 ms 64 bytes from 7d96d7e0d90b (10.89.0.14): icmp_seq=6 ttl=64 time=0.045 ms ^C --- 7d96d7e0d90b ping statistics --- 6 packets transmitted, 6 received, 0% packet loss, time 5111ms rtt min/avg/max/mdev = 0.037/0.043/0.046/0.003 ms

❏ Crear el archivo que contiene los hosts a gestionar (nano maquinas):

nodo2 nodo3

❏ Verificar la conexión:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas all -m ping
nodo3 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" } nodo2 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }

Para confirmar la autenticidad de cada host y asegurar una conexión segura, se recomienda realizar un ping individual a cada nodo (ansible -i maquinas nodo2 -m ping). Esto ayuda a verificar que te estás conectando al host correcto.

❏ Usar shell commands para crear un archivo en el nodo3:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas nodo3 -m command -a "touch /home/ansible/test.txt"
nodo3 | CHANGED | rc=0 >>

❏ Usar shell commands para listar enlaces simbólicos en el nodo3:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas nodo3 -m shell -a "ls -la / | grep lrwxrwxrwx"
nodo3 | CHANGED | rc=0 >> lrwxrwxrwx 1 root root 7 Apr 22 2024 bin -> usr/bin lrwxrwxrwx 1 root root 7 Apr 22 2024 lib -> usr/lib lrwxrwxrwx 1 root root 9 Apr 22 2024 lib64 -> usr/lib64 lrwxrwxrwx 1 root root 8 Apr 22 2024 sbin -> usr/sbin

El modulo -m command se cambio a -m shell para que el comando pueda usar pipes y redireccionadores.

Crear un archivo de prueba:

❏ Copiar un archivo a todos los nodos:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas nodo* -m copy -a "src=test.txt dest=/home/ansible"
nodo3 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/home/ansible/test2.txt", "gid": 0, "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "size": 0, "src": "/root/.ansible/tmp/ansible-tmp-1743974511.523381-438-188031703668177/source", "state": "file", "uid": 0 } nodo2 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/home/ansible/test2.txt", "gid": 0, "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "size": 0, "src": "/root/.ansible/tmp/ansible-tmp-1743974511.5220792-437-209822629953954/source", "state": "file", "uid": 0 }

❏ Instalar o actualizar curl en el nodo2:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas nodo2 -m apt -a "name=curl state=latest"
nodo2 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "cache_update_time": 1743974872, "cache_updated": false, "changed": true, "stderr": "debconf: delaying package configuration, since apt-utils is not installed\n", "stderr_lines": [ "debconf: delaying package configuration, since apt-utils is not installed" ], . . . [ snip ] . . .

Cuando se utilizan los parámetros -b y -K en un comando Ansible, se indica que se desea ejecutar el comando con privilegios elevados (como sudo) y se solicita la contraseña de elevación de privilegios. Esto es necesario cuando el usuario "ansible" no tiene permisos suficientes para realizar ciertas tareas, como instalar paquetes o modificar archivos de configuración del sistema. Al usar -b, Ansible intentará ejecutar el comando con sudo o un método similar para obtener privilegios de superusuario. El parámetro -K le indica a Ansible que solicite la contraseña necesaria para la elevación de privilegios.

❏ Instalar o actualizar Apache2 en el nodo2 con privilegios elevados:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas nodo2 -b -K -m apt -a "name=apache2 state=latest"
BECOME password: nodo2 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "cache_update_time": 1743974872, "cache_updated": false, "changed": true, "stderr": "debconf: delaying package configuration, since apt-utils is not installed\n", "stderr_lines": [ "debconf: delaying package configuration, since apt-utils is not installed" ], . . . [ snip ] . . .

❏ Iniciar y habilitar Apache2 en el nodo2 con privilegios elevados:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible -i maquinas nodo2 -b -K -m service -a "name=apache2 state=started enabled=yes"
BECOME password: nodo2 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "enabled": true, "name": "apache2", "state": "started" }
Verificar el estado de Apache2 en el nodo2:
Crear un archivo de configuración de Ansible deshabilitado por defecto:

Al generar este archivo con todas las opciones inicialmente deshabilitadas, se ofrece un lienzo en blanco para configurar Ansible de acuerdo con las necesidades específicas del proyecto. Esto facilita la activación selectiva de las opciones requeridas, optimizando así el comportamiento de Ansible para cada caso de uso particular.

El archivo ansible.cfg actúa como el centro de control para ajustar el comportamiento de Ansible. A través de este archivo, se pueden definir parámetros cruciales como la ubicación de los inventarios, los ajustes de conexión y las opciones de los módulos. La flexibilidad que ofrece este archivo permite adaptar Ansible a una amplia gama de entornos y flujos de trabajo. Para editar el archivo ansible.cfg y personalizar su contenido, se pueden utilizar editores de texto como nano o vi, herramientas que brindan la capacidad de modificar las opciones de configuración de manera precisa y eficiente.

Cuando Ansible busca archivos de configuración, sigue un orden de prioridad específico para determinar qué archivo utilizar. Este orden de prioridad es el siguiente:

  • ANSIBLE_CONFIG (variable de entorno): Si se define la variable de entorno ANSIBLE_CONFIG, Ansible utilizará el archivo especificado en esta variable.
  • ansible.cfg (directorio de trabajo actual): Si no se define la variable de entorno, Ansible buscará un archivo ansible.cfg en el directorio de trabajo actual.
  • ~/.ansible.cfg (directorio de inicio del usuario): Si no se encuentra en el directorio de trabajo actual, Ansible buscará un archivo ansible.cfg en el directorio de inicio del usuario.
  • /etc/ansible/ansible.cfg (directorio de configuración del sistema): Si no se encuentra en el directorio de inicio del usuario, Ansible buscará un archivo ansible.cfg en el directorio de configuración del sistema.

Este orden de prioridad permite una gran flexibilidad en la configuración de Ansible, permitiendo configuraciones a nivel de proyecto, usuario o sistema.

Ansible Playbooks

❏ Crear el archivo de inventario (nano inventario):

[servidores_web] nodo2 ansible_user=ansible [bases_de_datos] nodo3 ansible_user=ansible
Verificar la conectividad:

❏ Playbook para instalar Apache en servidores_web (nano nginx.yml):

--- - name: Instalar y configurar NGINX en servidores web hosts: servidores_web become: yes tasks: - name: Instalar NGINX apt: name: nginx state: present update_cache: yes - name: Asegurar que NGINX esté iniciado y habilitado service: name: nginx state: started enabled: yes

En YAML, la indentación es crucial para definir la estructura del archivo. En tu playbook, cada línea debe estar indentada correctamente.

❏ Ejecutar un playbook de Ansible para configurar Nginx:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible-playbook -i inventario nginx.yml -K
BECOME password: PLAY [Instalar y configurar NGINX en servidores web] *********************************** TASK [Gathering Facts] ***************************************************************** ok: [nodo2] TASK [Instalar NGINX] ****************************************************************** changed: [nodo2] TASK [Asegurar que NGINX esté iniciado y habilitado] *********************************** fatal: [nodo2]: FAILED! => {"changed": false, "msg": " * Starting nginx nginx\n ...fail!\n"} PLAY RECAP ***************************************************************************** nodo2 : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

❏ Playbook para instalar MySQL en bases_de_datos (nano mysql.yml):

--- - name: Instalar MySQL en bases de datos hosts: bases_de_datos become: yes vars: db_user: ansible db_pass: ansible db_name: testdb tasks: - name: Instalar apt-utils apt: name: apt-utils state: present - name: Instalar MySQL y dependencias package: name: "{{item}}" state: present update_cache: yes loop: - mysql-server - mysql-client - python3-mysqldb - libmysqlclient-dev - name: Iniciar y habilitar el servicio MySQL service: name: mysql state: started enabled: yes - name: Crear usuario de MySQL mysql_user: name: "{{db_user}}" password: "{{db_pass}}" priv: '*.*:ALL' host: '%' state: present - name: Crear base de datos mysql_db: name: "{{db_name}}" state: present - name: Permitir conexiones remotas a MySQL lineinfile: path: /etc/mysql/mysql.conf.d/mysqld.cnf # Ajusta la ruta si es necesario regexp: '^bind-address' line: 'bind-address = 0.0.0.0' backup: yes notify: - Reiniciar MySQL handlers: - name: Reiniciar MySQL service: name: mysql state: restarted

❏ Ejecutar un playbook de Ansible para configurar MySQL:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~ansible-playbook -i inventario mysql.yml -K
BECOME password: PLAY [Instalar MySQL en bases de datos] ************************************************ TASK [Gathering Facts] ***************************************************************** ok: [nodo3] TASK [Instalar apt-utils] ************************************************************** ok: [nodo3] . . . [ snip ] . . .

El paquete mysql-server-8.0 está parcialmente instalado y fallando en la post-instalación. Esto es común en contenedores, especialmente porque muchos scripts postinstalación intentan iniciar servicios... y los contenedores no suelen tener un sistema de init o systemd completo.

❏ Borrar los recursos de Docker.

Detener los contenedores:
Eliminar los contenedores:
Eliminar la red con Docker:
Eliminar la imagen fedora-ansible: