Automatizar la configuración del servidor con materiales del kit de taller de Ansible

Este kit de taller está diseñado para ayudar al público técnico a familiarizarse con los conceptos vinculados a la gestión de configuración y con el uso de Ansible para automatizar la configuración de la infraestructura del servidor.

El objetivo es proporcionar un conjunto completo de recursos para que un ponente celebre un evento y de una charla introductoria sobre Ansible. Incluye lo siguiente:

  • Diapositivas y notas para el ponente; se incluyen vídeos demo cortos y comandos para ejecutar una demostración en vivo opcional. Esta charla dura aproximadamente 50 minutos.
  • Un repositorio de GitHub que contenga el código de la aplicación de demostración y las secuencias de comandos de Ansible necesarias para implementar esa aplicación en un servidor de Ubuntu.
  • Este tutorial, explica cómo implementar la demo Travellist de la aplicación Laravel en un servidor remoto.

Este tutorial está destinado a complementar la demo de charla con detalles y aclaraciones adicionales. También sirve como referencia para los lectores que buscan implementar una aplicación de Laravel en un servidor remoto de Ubuntu usando Ansible.

Introducción

Debido al carácter desechable de los entornos de aplicaciones modernos, la automatización de servidores ahora desempeña un papel fundamental en la administración de sistemas. Las herramientas de gestión de configuración como Ansible normalmente se utilizan para agilizar el proceso de automatización de la configuración del servidor estableciendo procedimientos estándares para los nuevos servidores. Esto tiene el beneficio de reducir los errores humanos asociados con las configuraciones manuales.

Ansible ofrece una arquitectura simplificada que no requiere la instalación de software especial en los nodos. También proporciona un conjunto sólido de características y módulos incorporados que facilitan la escritura de secuencias de comandos de automatización.

Este tutorial, diseñado para acompañar a las diapositivas y las notas del ponente para el kit del taller Automatizar la configuración del servidor con Ansible, le mostrará cómo configurar un archivo de inventario y ejecutar un conjunto de secuencias de comandos de aprovisionamiento para automatizar completamente el proceso de configurar un servidor LEMP remoto (Linux, (E)Nginx, MariaDB y PHP-FPM) en Ubuntu 18.04 e implementar una aplicación demo Laravel en este sistema.

Nota: Este material está destinado a demostrar cómo usar playbooks para automatizar la configuración del servidor con Ansible. Aunque nuestra demo consiste en una aplicación Laravel que se ejecuta en un servidor LEMP, se anima a los lectores que modifiquen y adapten la configuración incluida para que se adapte a sus propias necesidades.

Requisitos previos

Para este tutorial, necesitará lo siguiente:

Paso 1: Clonar el repositorio demo

Lo primero que debemos hacer es clonar el repositorio que contiene las secuencias de comando de aprovisionamiento de Ansible y la aplicación demo Laravel que implementaremos en los servidores remotos. Puede encontrar todos los archivos necesarios en el repositorio de Github do-community/ansible-laravel-demo.

Tras iniciar sesión en su nodo de control de Ansible como su usuario sudo, clone el repositorio y navegue al directorio creado por el comando git:

  • git clone https://github.com/do-community/ansible-laravel-demo.git
  • cd ansible-laravel-demo

Ahora, puede ejecutar un comando ls para inspeccionar los contenidos del repositorio clonado:

  • ls -l --group-directories-first

Verá resultados como este:

ansible-laravel-demo
drwxrwxr-x 3 sammy sammy 4096 Mar 24 15:24 application
drwxrwxr-x 2 sammy sammy 4096 Mar 24 15:24 group_vars
drwxrwxr-x 7 sammy sammy 4096 Mar 24 15:24 roles
-rw-rw-r-- 1 sammy sammy  102 Mar 24 15:24 inventory-example
-rw-rw-r-- 1 sammy sammy 1987 Mar 24 15:24 laravel-deploy.yml
-rw-rw-r-- 1 sammy sammy  794 Mar 24 15:24 laravel-env.j2
-rw-rw-r-- 1 sammy sammy  920 Mar 24 15:24 readme.md
-rw-rw-r-- 1 sammy sammy  318 Mar 24 15:24 server-setup.yml

Aquí tiene una descripción de cada una de estas carpetas y archivos y de lo que son:

  • application/: este directorio contiene la aplicación demo Laravel que va a ser implementada en el servidor remoto al final del taller.
  • group_vars/: este directorio contiene los archivos variables que contienen opciones personalizadas para la configuración de la aplicación, como las credenciales de la base de datos y dónde guardar los archivos de la aplicación en el servidor remoto.
  • roles/: este directorio contiene los diferentes roles de Ansible que gestionan el aprovisionamiento de un servidor LEMP de Ubuntu.
  • inventory-example: este archivo puede usarse como una base para crear un inventario personalizado para su infraestructura.
  • laravel-deploy.yml: este playbook implementará la aplicación demo Laravel en el servidor remoto.
  • laravel-env.j2: el playbook laravel-deploy.yml utiliza esta plantilla para configurar el archivo de entorno de la aplicación.
  • readme.md: este archivo contiene información general sobre el aprovisionamiento contenido en este repositorio.
  • server-setup.yml: este playbook proporcionará un servidor LEMP usando los roles definidos en el diretorio roles/.

Paso 2: Configurar el archivo de inventario y probar la conexión con los nodos

Ahora, crearemos un archivo de inventario para listar los hosts que queremos administrar usando Ansible. Primero, copie el archivo inventory-example a un nuevo archivo llamado hosts:

  • cp inventory-example hosts

Ahora, utilice su editor de texto favorito para abrir el nuevo archivo de inventario y actualizarlo con sus propios servidores. En este caso, utilizaremos nano:

  • nano hosts

El inventario de ejemplo que viene con el kit de taller contiene dos grupos de Ansible: dev y production. Esto está destinado a demostrar la forma de usar variables de grupo para personalizar la implementación en varios entornos. Si desea probar esta configuración con un único nodo, puede usar dev o el grupo production y eliminar el otro del archivo de inventario.

ansible-laravel-demo/hosts
[dev]
203.0.113.0.101

[prod]
203.0.113.0.102

[all:vars]
ansible_python_interpreter=/usr/bin/python3

Nota: La variable ansible_python_interpreter define la ruta al ejecutable de Python en el host remoto. Aquí, indicamos a Ansible que establezca esta variable para todos los hosts en este archivo de inventario.

Guarde y cierre el archivo cuando termine. Si utiliza nano, puede hacerlo pulsando CTRL+X, luego Y y ENTER para confirmar.

Una vez que haya terminado de ajustar su archivo de inventario, puede ejecutar el módulo ping de Ansible para probar si el nodo de control puede conectar con los hosts:

  • ansible all -i hosts -m ping -u root

Vamos a desglosar este comando:

  • all: esta opción indica a Ansible que ejecute el siguiente comando en todos los hosts desde el archivo de inventario designado.
  • -i hosts: especifica qué inventario debería usarse. Cuando no se proporciona esta opción, Ansible intentará usar el inventario predeterminado, que normalmente se ubica en /etc/ansible/hosts.
  • -m ping: esto ejecutará el módulo ping de Ansible, que probará la conectividad con los nodos y si el ejecutable de Python puede encontarse o no en los sistemas remotos.
  • -u root: esta opción especifica el usuario remoto que debería usarse para establecer conexión con los nodos. Estamos usando la cuenta root como ejemplo porque normalmente es la única cuenta disponibles en los servidores nuevos. Es posible que sean necesarias otras opciones de conexión dependiendo del proveedor de su infraestructura y de la configuración SSH.

Si su conexión SSH a los nodos se configura correctamente, obtendrá el siguiente resultado:

Output
203.0.113.0.101 | SUCCESS => { "changed": false, "ping": "pong" } 203.0.113.0.102 | SUCCESS => { "changed": false, "ping": "pong" }

La respuesta pong significa que su nodo de control puede establecer conexión con sus nodos gestionados y que Ansible puede ejecutar los comandos de Python en los hosts remotos.

Paso 3: Configurar los archivos variables

Antes de ejecutar los playbooks que están incluidos en este kit de taller, primero deberá editar el archivo de variables que contiene ajustes como el nombre del usuario remoto que se creará y las credenciales de la base de datos que se configurarán con MariaDB.

Abra el archivo group_vars/all usando el editor de texto que prefiera:

  • nano group_vars/all.yml
ansible-laravel-demo/group_vars/all.yml
---
# Initial Server Setup
remote_user: sammy

# MySQL Setup
mysql_root_password: MYSQL_ROOT_PASSWORD
mysql_app_db: travellist
mysql_app_user: travellist_user
mysql_app_pass: DB_PASSWORD

# Web Server Setup
http_host: "{{ ansible_facts.eth0.ipv4.address }}"
remote_www_root: /var/www
app_root_dir: travellist-demo
document_root: "{{ remote_www_root }}/{{ app_root_dir }}/public"

# Laravel Env Variables
app_name: Travellist
app_env: dev
app_debug: true
app_url: "http://{{ http_host }}"
db_host: localhost
db_port: 3306
db_database: "{{ mysql_app_db }}"
db_user: "{{ mysql_app_user }}"
db_pass: "{{ mysql_app_pass }}"

Las variables que debe considerar son las siguientes:

  • remote_user: el usuario especificado se creará en el servidor remoto y se le concendrán privilegios sudo.
  • mysql_root_password: esta variable define la contraseña root de la base de datos para el servidor de MariaDB. Observe que esta debería ser una contraseña segura que usted elija.
  • mysql_app_db: el nombre de la base de datos que va a crear para la aplicación Laravel. No es necesario que cambie este valor, pero puede hacerlo si lo desea. Este valor se usará para establecer el archivo de configuración .env de Laravel.
  • mysql_app_user: el nombre del usuario de la base de datos para la aplicación Laravel. De nuevo, no es necesario que cambie este valor, pero puede hacerlo si lo desea.
  • mysql_app_pass: la contraseña de la base de datos para la aplicación Laravel. Esta debería ser una contraseña segura de su elección.
  • http_host: el nombre de dominio o dirección IP del host remoto. Aquí, recurriremos al hecho de que Ansible contiene la dirección ipv4 para la interfaz de red eth0. En el caso de que tenga nombres de dominios apuntando a sus hosts remotos, es posible que desee crear archivos de variables independientes para cada uno de ellos sobrescribiendo este valor de modo que la configuración de Nginx contenga el hostname correcto para cada servidor.

Una vez que termine de editar estos valores, guarde y cierre el archivo.

Crear archivos de variables adicionales para varios entornos

Si configuró su archivo de inventario con varios nodos, es posible que desee crear archivos de variables adicionales para configurar cada nodo de forma adecuada. En nuestro inventario de ejemplo, creamos dos grupos distintos: dev y production. Para evitar tener las mismas credenciales de la base de datos y otros ajustes en ambos entornos, debemos crear un archivo variable independiente que albergue nuestros valores de producción.

Es posible que desee copiar el archivo variable y usarlo como base para sus valores de producción:

  • cp group_vars/all.yml group_vars/production.yml
  • nano group_vars/production.yml

Debido a que el archivo all.yml contiene los valores predeterminados que deberían ser válidos para todos los entornos, puede eliminar del nuevo archivo production.yml todas las variables que no necesitarán modificaciones. Las variables que debería actualizar para cada entorno se resaltan aquí:

ansible-laravel-demo/group_vars/production
---
# Initial Server Setup
remote_user: prod_user

# MySQL Setup
mysql_root_password: MYSQL_PROD_ROOT_PASSWORD
mysql_app_pass: MYSQL_PROD_APP_PASSWORD

# Laravel Env Variables
app_env: prod
app_debug: false

Observe que cambiamos el valor de app_env a prod y fijamos el valor app_debug en false. Estos son los ajustes de Laravel recomendados para los entornos de producción.

Cuando termine de personalizar sus variables de producción, guarde y cierre el archivo.

Cifrar archivos variables con Ansible Vault

Si planea compartir su configuración Ansible con otros usuarios, es importante mantener las credenciales y otros datos sensibles de sus archivos variables protegidos. Esto es posible con Ansible Vault, una función que se incluye con Ansible por defecto. Ansible Vault le permite cifrar archivos de variables de modo que solo los usuarios con acceso a la contraseña de almacén puedan ver, editar o descifrar estos archivos. La contraseña de almacén es también necesaria para ejecutar un playbook o un comando que utilice archivos cifrados.

Para cifrar su archivo de variables de producción, ejecute lo siguiente:

  • ansible-vault encrypt group_vars/production.yml

Se le solicitará proporcionar una contraseña de almacén y confirmarla. Una vez que termine, si comprueba el contenido del archivo, verá que los datos estarán cifrados.

Si desea ver el archivo variable sin cambiar su contenido, puede usar el comando view.

  • ansible-vault view group_vars/production.yml

Se le pedirá que proporcione la misma contraseña que definió cuando cifró ese archivo con asnible-vault. Tras proporcionar la contraseña, el contenido del archivo aparecerá en su terminal. Para salir de la vista de archivo, escriba q.

Para editar un archivo previamente cifrado con Ansible Vault, utilice el comando de almacén edit:

  • ansible-vault edit group_vars/production.yml

Este comando lo solicitará proporcionar la contraseña de almacén para el archivo. Su editor de terminal predeterminado se utilizará para abrir el archivo para su edición. Tras realizar los cambios deseados, guarde y cierre el archivo. Ansible Vault lo cifrará de nuevo automáticamente.

Ahora ha terminado de configurar sus archivos variables. En el siguiente paso, ejecutaremos el playbook para configurar Nginx, PHP-FPM y MariaDB (que junto con un sistema operativo basado en Linux como Ubuntu forman la pila LEMP) en sus servidores remotos.

Paso 4: Ejecutar el playbook de LEMP

Antes de implementar la aplicación demo Laravel en los servidores remotos, debemos configurar un entorno LEMP que presentará la aplicación. El playbook server-setup.yml incluye los roles de Ansible necesarios para configurar esto. Para inspeccionar sus contenidos, ejecute:

  • cat server-setup.yml
ansible-laravel-demo/server-setup.yml
---
- hosts: all
  become: true
  roles:
    - { role: setup, tags: ['setup'] }

    - { role: mariadb, tags: ['mysql', 'mariadb', 'db', 'lemp'] }

    - { role: php, tags: ['php', 'web', 'php-fpm', 'lemp'] }

    - { role: nginx, tags: ['nginx', 'web', 'http', 'lemp'] }

    - { role: composer, tags: ['composer'] }

Aquí tiene una descripción de los roles incluidos en este playbook:

  • setup: contiene las tareas necesarias para crear un nuevo usuario del sistema y concederle privilegios sudo, y para habilitar el firewall ufw.
  • mariadb: instala la el servidor de la base de datos MariaDB y crea la base de datos y el usuario de la aplicación.
  • php: instala php-fpm y los módulos PHP que son necesarios para ejecutar una aplicación Laravel.
  • nginx: instala el servidor web Nginx y permite el acceso en el puerto 80.
  • composer: instala Composer globalmente.

Observe que hemos configurado algunas etiquetas en cada rol. Esto es para que resulte sencillo volver ejecutar solo partes de este playbook, si es necesario. Si realiza cambios en su archivo de plantilla de Nginx, por ejemplo, es posible que desee ejecutar solo el rol de Nginx.

El siguiente comando ejecutará este playbook en todos los servidores desde su archivo de inventario. El --ask-vault-pass solo es necesario en caso de que haya usado ansible-vault para cifrar archivos variables en el paso anterior:

  • ansible-playbook -i hosts server-setup.yml -u root --ask-vault-pass

Verá un resultado similar a este:

Output
PLAY [all] ********************************************************************************************** TASK [Gathering Facts] ********************************************************************************** ok: [203.0.113.0.101] ok: [203.0.113.0.102] TASK [setup : Install Prerequisites] ******************************************************************** changed: [203.0.113.0.101] changed: [203.0.113.0.102] ... RUNNING HANDLER [nginx : Reload Nginx] ****************************************************************** changed: [203.0.113.0.101] changed: [203.0.113.0.102] PLAY RECAP ********************************************************************************************** 203.0.113.0.101 : ok=31 changed=27 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 203.0.113.0.102 : ok=31 changed=27 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1

Sus nodos ahora están listos para presentar aplicaciones PHP usando Nginx+PHP-FPM, con MariaDB como el servidor de la base de datos. En el siguiente paso, implementaremos la aplicación demo Laravel incluida con el playbook de Ansible laravel-deploy.yml.

Paso 5: Implementar la aplicación de Laravel

Ahora que tiene un entorno LEMP en funcionamiento en su servidor remoto, puede ejecutar el playbook laravel-deploy.yml. Este playbook ejecutará las siguientes tareas:

  1. Crear la raíz del documento de la aplicación en el servidor remoto, si esto aún no se hizo.
  2. Sincronizar la carpeta de la aplicación local con el servidor remoto usando el módulo sync.
  3. Usar el módulo acl para establecer permisos para el usuario www-data en la carpeta de almacenamiento.
  4. Configurar el archivo de aplicación .env en base a la plantilla laravel-env.j2.
  5. Instalar las dependencias de la aplicación con Composer.
  6. Generar la clave de seguridad de la aplicación.
  7. Configurar un enlace público para la carpeta de almacenamiento.
  8. Ejecutar migraciones y seeders de la base de datos.

Este playbook debería ejecutarse a través de un usuario no root con permisos sudo. Este usuario se creó cuando ejecutó el playbook server-setup.yml en el paso anterior, usando el nombre definido por la variable remote_user.

Cuano esté listo, ejecute el playbook laravel-deploy.yml con:

  • ansible-playbook -i hosts laravel-deploy.yml -u sammy --ask-vault-pass

El --ask-vault-pass solo es necesario en caso de que haya usado ansible-vault para cifrar archivos variables en el paso anterior.

Verá un resultado similar a este:

Output
PLAY [all] ********************************************************************************************** TASK [Gathering Facts] ********************************************************************************** ok: [203.0.113.0.101] ok: [203.0.113.0.102] TASK [Make sure the remote app root exists and has the right permissions] ******************************* ok: [203.0.113.0.101] ok: [203.0.113.0.102] TASK [Rsync application files to the remote server] ***************************************************** ok: [203.0.113.0.101] ok: [203.0.113.0.102] ... TASK [Run Migrations + Seeders] ************************************************************************* ok: [203.0.113.0.101] ok: [203.0.113.0.102] PLAY RECAP ********************************************************************************************** 203.0.113.0.101 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 203.0.113.0.102 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Cuando finalice la ejecución, podrá acceder a la aplicación demo apuntando su navegador al nombre de dominio o dirección IP de su nodo:

http://node_domain_or_IP

Verá una página como la siguiente:

Demo Travellist de Laravel

Conclusión

En este tutorial, se muestra la manera de configurar un archivo de inventario de Ansible, establecer conexión con nodos remotos y ejecutar playbooks de Ansible para configurar un servidor LEMP e implementar una aplicación de demostración de Laravel en él. Esta guía complementa las diapositivas y notas del ponente de Automatizar la configuración del servidor con el Kit del taller Ansible; además, viene acompañada de un repositorio de GitHub de demostración que contiene todos los archivos necesarios para seguir con el componente de demostración de este taller.

0 Comments

Creative Commons License