Blog de Amazon Web Services (AWS)

Una mejor integración de Ansible con AWS Systems Manager

Andres Silva, Arquitecto Especialista Principal de Soluciones con el equipo de Herramientas de Administración en AWS

 

Introducción

Ansible es una herramienta poderosa porque es simple, pero permite manejar muchas tareas complicadas con un mínimo esfuerzo. Hace algún tiempo publiqué esta entrada de blog cuando lanzamos la primera versión del documento AWS System Manager (SSM) que habilita el soporte para Ansible. En ese entonces te conté de cómo la estrecha integración de SSM con otros servicios de AWS como IAM y Cloudtrail no solo simplifica la gestión, sino que también mejora la postura de seguridad de tu infraestructura. Recibimos buenos comentarios sobre esa primera iteración de la integración con Ansible. Pero los clientes querían más; integración de GitHub, “playbooks” complejos y más. También nos dieron buenos comentarios sobre cómo mejorar la integración.

Escuchamos los comentarios y recientemente presentamos un soporte más sólido para Ansible con AWS Systems Manager. La integración es proporcionada por un nuevo Documento de Systems Manager llamado AWS-ApplyansiblePlayBooks. Esta nueva versión incorpora muchas de las características que nuestros clientes han solicitado. Si desea obtener más información sobre todas las nuevas características, consulte la documentación que se encuentra aquí

 

Recorriendo cómo funciona Ansible

Vamos a recorrer un ejemplo de cómo utilizar esta nueva y poderosa funcionalidad. Este post no pretende enseñarte cómo funciona Ansible. Una de las grandes cosas de Ansible es su gran documentación a la que puedes acceder aquí

Digamos que desea configurar una instancia ec2 para ejecutar apache y servir una página personalizada. Con una instancia completamente nueva hay algunas cosas que debes hacer para que eso suceda. Vamos a analizar los pasos y también ver algunos comandos que usarías para hacer eso.

Si necesitas instalar el software de servidor web apache, puedes hacerlo en una instancia de Amazon Linux con el siguiente comando:

 

sudo yum install httpd

 

Pero si estás usando Ubuntu o en una distribución basada en Debian, el comando se ve así:

 

sudo apt-get install apache2

 

Como puedes ver necesitas saber qué sistema operativo estás ejecutando para decidir qué comando para instalar vas a usar. Ansible simplifica esto y te mostraré cómo después en el post.  Después de instalar el software es necesario asegurarse de que el servicio se está ejecutando. Lo puedes hacer con el siguiente comando:

 

systemctl start httpd  #for Amazon Linuxsystemctl start apache2 #for Ubuntu

 

El siguiente paso sería copiar la página web que deseas personalizar y servir como página principal de su servidor web. Normalmente harías esto con un editor de texto y algún código html. No entraremos en los detalles pero para el propósito de esta entrada de blog usaremos una página sencilla con algunas variables para la personalización y para mostrar el poder de la automatización de Ansible.

Como puede ver se necesitan varios pasos y si el proceso está automatizado para soportar múltiples sistemas operativos, entonces se necesita agregar algún manejo lógico para tener en cuenta las diferentes formas de instalar software (yum vs apt-get)

¿Cómo podemos hacer esto usando Ansible y el nuevo Documento SSM para ejecutar los playbooks de Ansible? Sin entrar en demasiados detalles sobre cómo funciona Ansible, puedes realizar las tareas necesarias creando un playbook con las siguientes tareas:

 

- name: Gather ec2 facts
  ec2_metadata_facts:
- name: install apache on redhat or centos instances
  yum: name=httpd state=present
  when: ansible_os_family == "RedHat"
- name: install apache on debian or ubuntu instances
  apt: name=apache2 state=present
  when: ansible_os_family == "Debian"
- name: template the index file for debian
  template: src=index.html.j2 dest=/var/www/html/index.html owner=www-data group=www-data mode=0644
  when: ansible_os_family == "Debian"
- name: template the index file for Redhat
  template: src=index.html.j2 dest=/var/www/html/index.html owner=apache group=apache mode=0644
  when: ansible_os_family == "RedHat"
- name: enable apache on startup and start service for redhat or centos
  service: name=httpd enabled=yes state=started
  when: ansible_os_family == "RedHat" 
- name: enable apache on startup and start service for debian or ubuntu
  service: name=apache2 enabled=yes state=started
  when: ansible_os_family == "Debian"

 

Las tareas definidas anteriormente hacen lo siguiente:

 

Reunir datos de ec2 y cargarlo en una variable de diccionario que se puede utilizar en cualquier lugar de la automatización. Más sobre el uso de eso después.

Hay dos tareas para instalar Apache, una para distribuciones basadas en yum y otra para distribuciones basadas en Debian. Esto se ejecuta condicionalmente. Ansible sólo ejecutará uno de ellos dependiendo del sistema operativo que esté ejecutando la instancia.

También observaras unas entradas para usar una plantilla de archivo para la página index.html. Nuevamente, dependiendo de la distribución de Linux solo se ejecutará una.

También hay dos tareas para iniciar el servicio. Esto asegura que se utilice el comando correcto para cada distribución.

Como puede ver, en términos muy simples hemos sido capaces de definir no sólo todos los comandos necesarios para configurar nuestra instancia como servidor web, sino que también hemos ampliado la automatización para ser lo suficientemente flexible como para soportar múltiples distribuciones Linux.

Toda esa automatización podría contenerse en un solo archivo playbook de Ansible. No obstante porque estamos usando una plantilla para un archivo (index.html.j2) necesitaríamos incluir también ese archivo como parte de la automatización. Para hacer nuestra automatización más modular podríamos aprovechar el concepto de roles Ansible. Un “role” es un marco para proporcionar un conjunto independiente de archivos que se pueden utilizar para la automatización. Esto proporciona la flexibilidad de compartir y reutilizar archivos de automatización. En nuestro ejemplo podríamos romper la automatización simple que acabamos de diseñar y llamarlo apache. Este “role” ahora se puede compartir y distribuir para que otros no tengan que escribir todo el código necesario para configurar un servidor apache. Aquí hay información más interesante sobre cómo funcionan los “roles”

Juntando todo podemos tener una estructura de archivos sencilla que se vea así:

 

automation

├server.yml

├apache+

   ├tasks

├main.yml

    ├templates

        ├index.html.j2

 

El archivo main.yml tiene las tareas que delineamos antes. Como se puede ver ese archivo y la fuente de la plantilla ahora están agrupados en una estructura de archivos para un “role” llamado apache. Después en el nivel superior tenemos un archivo llamado server.yml que será el “playbook” principal. Ese archivo simplemente ejecutara al “role”. Se ve así


---

  - hosts: all

    become: true

    become_method: sudo

    roles:

      - apache

 

Para usar y mantener este conjunto de archivos de automatización podriamos usar un sistema de administración de código fuente y convertirlo en parte de una canalización de implementación. Para los propósitos de nuestro ejemplo, digamos que su sistema comprime los archivos de automatización y los almacena en s3. ¿Cómo podemos utlizar AWS Systems Manager para implementar la automatización?

 

Integración con AWS Systems Manager

Imagina que tienes una flota de servidores web que necesitan tener apache funcionando todo el tiempo y deben estar configurados para servir un archivo. Todos tienen una etiqueta llamada role con un valor de “websever” para identificarlos. Su objetivo es configurar un proceso que garantice que estas instancias estén configuradas correctamente todo el tiempo. Veamos un ejemplo de que puedes usar el nuevo documento Ansible SSM para simplificar las operaciones.

  • Inicie sesión en la consola de AWS y vaya a la página de Systems Manager
  • En el menu de la izquierda, Haga clic en el botón “Association”
  • Proporciona un nombre para la asociación. Se le puede llamar “webserver”
  • Selecciona AWS-AppliansiblePlayBooks de la lista de documentos de Systems Manager
  • En el campo de “Source Type”, seleccione S3
  • En el campo de “Source info”, ingrese la ruta a donde se encuentra el archivo zip en s3. Debe ingresar la ubicación del archivo usando notación JSON en el siguiente formato Por ejemplo: {“path”:” https://example-bucket.s3.amazonaws.com/automation.zip”}
  • En el campo Instalar dependencias, seleccione “True”. Esto instalará Ansible y todas sus dependencias.
  • En el archivo de playbook debemos especificar la ruta relativa completa de donde se encuentra la playbook principal. Ya que comprimimos los archivos en una carpeta llamada automatización, y el archivo principal se llama server.yml, especificamos “automation/server.yml” en este campo.
  • En el campo “Extra Vars” podemos especificar variables adicionales que nos gustaría pasar a la automatización durante la ejecución. La automatización de muestras proporcionada anteriormente espera una variable llamada myregion. Así que podemos escribir aquí “myregion=us-east-1”
  • En las secciones de “target” seleccionaremos la opción de “specify tags”. Después ingresa la definición de etiqueta para nuestro servidor web. En este caso el Key será role, y Value sera: webserver. Esto apuntará a la ejecución AWS Systems Manager a todas las instancias que tengan una etiqueta con esa combinancion de etiqueta
  • En el horario de especificar seleccione con qué frecuencia le gustaría ejecutar esta asociación.
  • Ahora haga clic en “Create Association”

También puede crear la asociación de Systems Manager utilizando el SDK o el AWS CLI. Si deseas crear la asociación usando el AWS CLI. puedes hacerlo con un comando como este:

aws ssm create-association --name "AWS-ApplyAnsiblePlaybooks" --parameters
 '{"SourceType":["S3"],"SourceInfo":["{\"path\": \"https://example-
bucket.s3.amazonaws.com/automation.zip\"}"],"InstallDependencies":["True"],"P
laybookFile":["automation/playbook.yml"],"ExtraVariables":["myregion=us-east-
1"],"Check":["False"],"Verbose":["-v"]}' --targets Key=resource-
groups:Name,Values=MyResourceGroup --max-concurrency "50" --max-errors "0" --
region us-east-1

 

Al ejecutar este comando, devolverá una estructura de “AssociationDescription” en formato JSON, que contiene todos los detalles de la nueva asociación.

Eso es todo. Ahora tienes el control total de tu automatización de Ansible usando AWS Systems Manager. Puede analizar los resultados de la ejecución de automatización desde la consola. Opcionalmente Tambien puede habilitar toda la salida de la ejecución a s3.

 

Conclusión

En esta entrada de blog hemos analizado algunas funcionalidades básicas de Ansible y hemos repasado la integración con AWS Systems Manager. Destacamos cómo estas características de AWS Systems Manager amplían la potencia de Ansible para proporcionarle un control más granular y una seguridad mejorada al implementar la automatización de la administración de la configuración.

 


Sobre el autor

Andres Silva es Arquitecto Especialista Principal de Soluciones del equipo de Herramientas de Administración de AWS y ha trabajado con la tecnología de AWS durante más de 9 años. Andrés trabaja en estrecha colaboración con los equipos de servicio para diseñar soluciones a escala que ayuden a los clientes a implementar y apoyar infraestructuras complejas en la nube. Cuando no está construyendo la automatización de la nube, le gusta andar en patineta con sus 2 hijos.