Playbook de Ansible para instalar automáticamente una instancia de RHEL7 en EC2 de AWS como LEMP

Inicio explicándoles que LEMP es Linux, Nginx, MySQL y PHP.

Luego deben crear una instancia en EC2 de AWS y deben tener un usuario registrado en RedHat con la licencia de RHEL7 (o si es para fines no productivos, pueden registrarse en la Developers Network de RedHat y optar a licencias de desarrollo).

Luego de que tengan la instancia creada, les recomiendo usar la imagen ami-036affea69a1101c9 con una instancia T2.micro que brinda una opción barata y buena con el respaldo de RHEL.

Deben asegurarse de que puedan hacer sesiones de ssh (sin contraseña) desde su máquina a la instancia de AWS.

Para probar eso deben lanzar este comando de ansible:

ansible -m ping <IP de la instancia>

Y deben obtener una respuesta SUCCESS algo así como:


Eso quiere decir que su ansible está conectandose a su instancia y que puede controlarla usando esta poderosa herramienta.

Entonces vamos a crear un archivo en formato YAML (formato que usa Ansible para sus playbooks):

Que diga y haga lo siguiente:

---

- hosts: aws
become: true
tasks:

- name: Include a code to install latest version of pip with epel repository then deactivate epel
include: install_pip.yml

Noten que el archivo comienza con ---

Eso indica que es un archivo de YAML.

Luego tiene  la entrada - hosts: aws, eso significa que en nuestro archivo de configuración /etc/ansible/hosts existe una sección llamada AWS que incluye la IP de nuestra instancia y el usuario que tiene el poder de hacer sudo sin contraseña para ejecutar comandos como root, en este caso ec2-user


la línea become=true indica a Ansible que todas las tareas que siguen a continuación de la etiqueta

tasks: 

van a ser ejecutadas como root.

En el primer bloque se incluye un archivo externo (se llama a otro archivo que también incluye código YAML)

este archivo, llamado instal_pip.yml contiene:

- name: Add EPEL repository
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
gpgcheck: no

- name: install python2-pip
yum:
name:
- python2-pip
- nginx
state: present

- name: Force pip upgrade to the latest version
shell: pip install --upgrade pip

- name: install latest pyOpenSSL, pyMysql, botocore & boto3 with pip
pip:
name:
# - pyOpenSSL
- PyMySQL
- botocore
- boto3
# - enum
state: latest

- name: Deactivate EPEL repository
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
gpgcheck: no
enabled: no

En este trozo de código, activamos el repositorio EPEL e instalamos algunos aplicativos; entre ellos: python2-pip y nginx.

Luego utilizando el pip (recién instalado) NO EL YUM, instalamos PyMSQL, botocore y boto3 y por último desactivamos el repositorio EPEL, ya que en lo sucesivo utilizaremos repositorios oficiales de RedHat.

Luego de terminar este código el Ansible regresa al archivo original y sigue ejecutando el código del archivo original llamado: aws.yml

- name: Register as user (xyz)
redhat_subscription:
state: present
username: <username register in RedHat>
password: <passwd of user register in RedHat>
auto_attach: true



- name: Enable a RHSM repository
rhsm_repository:
name:
- rhel-7-server-extras-rpms
- rhel-7-server-optional-rpms
- rhel-server-rhscl-7-rpms
state: enabled



- name: System update
yum:
name: '*'
state: latest

El primer bloque registra la instancia en la RHN, luego activa los repositorios rhel-7-server-extras-rpm, rhel-7-server-optional-rpms y rhel-server-rhscl-7-rpms

Por último este comando es equivalente a ejecutar un yum -y update

Que actualiza todos los paquetes del sistema a su versión más reciente.

# Set SELinux to permissive mode
- selinux:
policy: targeted
state: permissive

- name: install needed packages
yum:
name:
- rh-nginx18
- mariadb-server
- rh-php72
- rh-php72-php-cli
- rh-php72-php-fpm
- rh-php72-php-mysqlnd
- rh-php72-php-opcache
- rh-php72-php-gd
- openssl
- firewalld
state: present

Luego coloca la política de selinux en modo "permissive" e instala algunos paquetes ahora de los repositorios de RedHat:

- name: Remove default nginx config
file: name=/etc/nginx/sites-enabled/default state=absent

- name: Create directory
file: name=/etc/ssl/private state=directory mode=0755

- name: Copy server.key file
copy:
src: templates/server.key
dest: /etc/ssl/private/server.key
mode: 0600

- name: Create directory
file: name=/etc/ssl/certs state=directory mode=0755

- name: Copy server.crt file
copy:
src: templates/server.crt
dest: /etc/ssl/certs/server.crt
mode: 0755

- name: Install system nginx config
template:
src: templates/nginx.conf
dest: /etc/nginx/nginx.conf

- name: Create directory
file: name=/var/www/html state=directory mode=0755

- name: create index.html
template:
src: templates/index.html
dest: /var/www/html/index.html
mode: 0755

- name: create pets.php
template:
src: templates/pets.php
dest: /var/www/html/pets.php
mode: 0755

En este bloque de código básicamente lo que hace es, borrar, crear o copiar archivos en ubicaciones de la máquina remota, desde un directorio llamado "templates" donde debemos tener los archivos previamente creados y siendo cuidadosos con los nombres de archivos para ser copiados de forma correcta.

- name: start mariadb
service:
name: mariadb
state: started
enabled: yes

- name: start nginx
service:
name: nginx
state: started
enabled: yes

- name: start php-fpm
service:
name: rh-php72-php-fpm
state: started
enabled: yes

# start the firewalld daemon

- name: start firewalld
service:
name: firewalld
state: started
enabled: yes

En este bloque básicamente iniciamos los servicios que necesitamos para poder prestar servicio: mariadb, nginx, php-fpm y firewalld

# enable http, https only, ssh is enable for default.

- name: activate http in firewall
firewalld:
zone: public
service: http
permanent: yes
state: enabled

- name: activate https in firewall
firewalld:
zone: public
service: https
permanent: yes
state: enabled

- name: firewalld reload
command: firewall-cmd --reload

En este bloque se configura el firewall para que sólo abra los puertos: 22, 80 y 443 y finalmente se reinicia el servicio firewalld.

- name: Copy database dump file
copy:
src: templates/pets.sql
dest: /tmp

- name: check if DB aws exists
# shell: mysql -e 'SHOW DATABASES;' | grep aws
shell: mysql -e "SHOW DATABASES LIKE 'aws'" -sN
register: dbstatus
failed_when: dbstatus.rc == 2


- name: Run mysql scripts if database aws don't exist
include: mysql.yml
when: dbstatus.stdout == ""

En este bloque finalmente se configura la base de datos para que "si no existe" la base de datos aws, ejecute el código externo mysql.yml para crearla (si la base de datos aws, existiese este código se saltaría y no ejecutaría nada).

El código del archivo mysql.yml es el siguiente:

- name: Create a new database with name 'aws'
mysql_db:
name: aws
collation: utf8_general_ci
encoding: utf8
state: present

# Removes all anonymous user accounts
- mysql_user:
name: ''
host_all: yes
state: absent

# Create database user with name 'aws' and password 'aws' with all database privileges
- mysql_user:
name: aws
password: aws
priv: '*.*:ALL'
state: present

#This module is not idempotent when state is import, and will import the dump file each time if run more than once.
- name: Import pets.sql
mysql_db:
state: import
name: aws
target: /tmp/pets.sql

Este código crea la base de datos aws, remueve los usuarios anónimos que se crean al instalar mariadb, crea el usuario aws con passwd aws y le da todos los privilegios sobre la base de datos del mismo nombre.

Finalmente toma el contenido del archivo /tmp/pets.sql y lo inserta en la base de datos aws.

Es un ejemplo práctico de lo que se puede hacer con Ansible, aunque realmente es muchísimo más lo puedes hacer.

Todas las funciones se encuentran documentadas en:

https://docs.ansible.com/ansible/latest/index.html

Finalmente puedes ejecutar el playbook con el siguiente comando:

ansible-playbook aws aws.yml

Donde:

ansible-playbook <conjunto de hosts> <nombre del playbook>

Comentarios

Entradas populares