Introducción
Ansible es una potente herramienta de automatización que nos permite configurar, mantener y administrar entornos de manera escalable y eficiente, mediante una conexión a los nodos a través de SSH. Ansible hace uso de archivos con extensión. YML, donde se describen las tareas que se van a ejecutar en los nodos configurados.
Ventajas de usar Ansible:
- Simplicidad: Ansible utiliza un lenguaje basado en YAML (YAML Ain't Markup Language) para definir las tareas, lo que lo hace fácil de entender y utilizar.
- Escalabilidad: Ansible puede gestionar desde unos pocos hasta muchos servidores, dependiendo de los que se configuren en el archivo de inventario
- Idempotencia: Las tareas de Ansible son idempotentes, lo que significa que puedes ejecutar un playbook múltiples veces sin que eso cause cambios no deseados en el sistema si ya está en el estado deseado.
- Integración con otras herramientas: Ansible se integra fácilmente con otras herramientas y plataformas, como Docker, Kubernetes, y sistemas de CI/CD.
- Seguridad: La gestión de secretos y las variables en Ansible pueden manejarse de forma segura, y permite auditar y controlar el acceso a configuraciones sensibles.
Ejemplo práctico
Para este laboratorio, se hará uso de la herramienta Docker, para crear contenedores y simular la administración de servidores mediante script de ansible.
Para iniciar, se clonara del repositorio de github los Dockerfile, que se usaran como base para la creación de las imágenes del servidor administrador y de los que se van a controlar:
# Se clona el repositorio
git clone https://github.com/evergel/Welcome_to_Ansible.git
# Se accede al directorio
cd Welcome_to_Ansible/
Aqui veremos 3 archivos claves:
Dockerfile_controller: Este será el Dockerfile que se usara como base para la construcción de la imagen del nodo controlador
Dockerfile_slave: Este será el Dockerfile que se usara como base para la construcción de la imagen de los nodos que se van a controlar
.ansible.cfg: Archivo de configuración que se copiara en la construcción de la imagen del nodo controlador
Configuración
Crear la imagen del nodo controlador, el cual tendrá instalado ansible:
docker build -f Dockerfile_controller -t img_controller .
Puntos clave del Dockerfile_controller
# Aqui se instalan las herramientas necesarias(SSH, ansible, python3)
RUN apk update && \
apk add --no-cache iproute2 net-tools openssh ansible python3
# En este punto se copia el archivo de configuracion
COPY .ansible.cfg /home/ansible/.ansible.cfg
# define la ruta donde estara alojado
ENV ANSIBLE_CONFIG=/home/ansible/.ansible.cfg
# Creación y configuración del usuario ansible
RUN adduser -D ansible && \
mkdir -p /home/ansible/.ssh && \
chown -R ansible:ansible /home/ansible/.ssh && \
chmod 700 /home/ansible/.ssh
# Generación de clave SSH para ansible
USER ansible
WORKDIR /home/ansible/.ssh
RUN ssh-keygen -t rsa -b 4096 -f id_rsa -q -N "" && \
cp id_rsa.pub authorized_keys && \
chmod 600 id_rsa id_rsa.pub authorized_keys
Crear la imagen del nodo administrado
docker build -f Dockerfile_slave -t img_slave .
Puntos clave del Dockerfile_slave
# Aqui se instalan las herramientas necesarias(SSH, python3)
RUN apk update && \
apk add --no-cache sudo openssh bash python3
# Se crea el usuario ansible y se le asigna un password
RUN adduser -D -s /bin/bash ansible && \
echo "ansible:gG930" | chpasswd
# Aqui se asignan permisos sudo al usuario ansible, que sera el administrador
RUN echo "ansible ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
Una vez creadas las imagenes se pueden verificar ejecutando
docker image ls
Creamos el contenedor del nodo que va a controlar los servidores
docker run -d --name ansible_controller img_controller:latest
donde ansible_controller es el nombre que le pondremos al contenedor y img_controller la imagen de la cual se va a basar el contenedor, que fue previamente construida
Creamos los contenedores de los nodos que van a ser gestionados desde el nodo controlador
docker run -d --name ansible_slave img_slave:latest
docker run -d --name ansible_slave1 img_slave:latest
docker run -d --name ansible_slave2 img_slave:latest
Una vez creados los contenedores verificamos las IP's de los contenedores que actuaran como nodos administrados, de la siguiente manera:
docker container inspect ansible_slave| grep IPAddress
# Se vera una salida asi
"IPAddress": "172.17.0.3"
Ahora se accede al contenedor del nodo administrador
docker exec -it -u ansible ansible_controller sh
Luego se procede a copiar las llaves ssh desde el nodo controlador hacia los nodos controlados para establecer relación de confianza
# Ejemplo
# ansible_slave
ssh-copy-id ansible@<ip_ansible_slave>
# ansible_slave2
ssh-copy-id ansible@<ip_ansible_slave2>
# ansible_slave3
ssh-copy-id ansible@<ip_ansible_slave3>
pedirá el password que se definió al usuario ansible (gG930)
Por ultimo creamos el archivo de inventario, en el cual podemos especificar los nodos que se van a controlar, también dividirlos en grupos, etc.
Por ejemplo:
# nos dirigimos al home del usuario ansible
cd $HOME
# Creamos el archivo inventory con un editor de texto, como vim
vi inventory
# agregamos los nodos de la siguiente manera
[all]
172.17.0.3
172.17.0.4
172.17.0.5
[group1]
172.17.0.3
172.17.0.4
De esta forma ya tendremos nuestro nodo controlador configurado y podremos ejecutar tareas sobre los nodos administrados
Por ejemplo,
Ejecutaremos el siguiente playbook, el cual se encargara de actualizar paquetes e instalar unos nuevos:
# Creamos nuestro primer playbook, el cual llamaremos play1.yml
vi play1.yml
# Agregamos lo siguiente
- name: Configuracion inicial de servidores remotos
hosts: "{{ target_hosts | default('all') }}"
become: true
vars:
packages:
- vim
- git
- curl
tasks:
- name: Actualizar el índice de paquetes
apk:
update_cache: yes
- name: Actualizar todos los paquetes
apk:
upgrade: yes
register: upgrade_result
- name: Instalar paquetes necesarios
apk:
name: "{{ packages }}"
state: present
# por ultimo lo ejecutamos asi
ansible-playbook play1.yml -e "target_hosts=group1"
# Aqui estamos especificando que las tareas se ejecuten sobre los nodos del group1
172.17.0.3
172.17.0.4
Ejemplo 2
Crear un playbook que nos permita crear un usuario administrador
# creamos el playbook
vi create_user.yml
# Definimos las tareas en el playbook
---
- name: Crear usuario y asignar permisos
hosts: "{{ target_hosts }}"
become: yes
vars:
usuario: "{{ usuario }}"
tasks:
- name: Crear usuario
user:
name: "{{ usuario }}"
append: yes
- name: Asignar permisos de sudo
lineinfile:
dest: /etc/sudoers
line: "{{ usuario }} ALL=(ALL) NOPASSWD:ALL"
state: present
# Lo ejecutamos asi
ansible-playbook create_user.yml -e "usuario=usua_admin" -e "target_hosts=all"
# aqui especificamos que se ejecute para el grupo [all] y que el usuario a crear es usua_admin
Conclusiones
Usar Ansible para la administración de servidores nos aporta una gran ventaja, gracias a su simplicidad, flexibilidad y escalabilidad, nos permite optimizar el tiempo y asegurar consistencia en la configuración y despliegue de sistemas, mejorando la eficiencia operativa en los entornos que se deseen controlar