Ejemplo: Automatización con ANSIBLE

Entorno de pruebas

Script de instalación GNU/Linux: ejercicio-ansible.sh

Script de instalación Windows: ejercicio-ansible.ps1 [aportado por Adrián Otero]

Recursos

Uso básico de Ansible

Desde la máquina ansible (logueado como root/purple), crear directorio de trabajo y fichero con el inventario de los equipos.

root@ansible:~/# mkdir ejemplo_ansible
root@ansible:~/# cd ejemplo_ansible
root@ansible:~/ejemplo_ansible# nano inventario

[web]
web1.cda.net
web2.cda.net
web3.cda.net

[haproxy]
haproxy.cda.net

[bd]
bd.cda.net

Crear par de claves RSA para SSH y propogarlas a las máquinas del ejercicio (pedirá la contraseña del usario1: usuario1).

root@ansible:~/ejemplo_ansible# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
9a:a0:d0:cc:b9:78:a8:24:15:ce:58:49:0f:5c:c8:33 root@ansible
The key's randomart image is:
+---[RSA 2048]----+
| ooo.            |
| .E+             |
|  +o.            |
| O o             |
|o O .   S        |
| = o . o         |
|+.+   o          |
|+.               |
|.                |
+-----------------+

root@ansible:~/ejemplo_ansible# ssh-copy-id usuario1@web1.cda.net
root@ansible:~/ejemplo_ansible# ssh-copy-id usuario1@web2.cda.net
root@ansible:~/ejemplo_ansible# ssh-copy-id usuario1@web3.cda.net
root@ansible:~/ejemplo_ansible# ssh-copy-id usuario1@haproxy.cda.net
root@ansible:~/ejemplo_ansible# ssh-copy-id usuario1@bd.cda.net

Comprobar la accesibilidad al usuario1 de esas máquinas con el módulo ping de Ansible.

root@ansible:~/ejemplo_ansible# ansible all -i inventario -u usuario1 -m ping
haproxy.cda.net | success >> {
    "changed": false, 
    "ping": "pong"
}

bd.cda.net | success >> {
    "changed": false, 
    "ping": "pong"
}

web1.cda.net | success >> {
    "changed": false, 
    "ping": "pong"
}

web3.cda.net | success >> {
    "changed": false, 
    "ping": "pong"
}

web2.cda.net | success >> {
    "changed": false, 
    "ping": "pong"
}

Para evitar indicar el inventario y el usuario en cada invocación, declarar esos datos en el fichero ansible.cfg.

root@ansible:~/ejemplo_ansible# nano ansible.cfg

[defaults]
hostfile = inventario
remote_user = usuario1

Ejecución de comandos en las máquinas administradas (módulo command)

root@ansible:~/ejemplo_ansible# ansible all -m command -a "/usr/bin/free"
root@ansible:~/ejemplo_ansible# ansible all -m command -a "/bin/df"

Consulta de información en las máquinas administradas (serán las variables disponibles en los playbooks) (módulo setup)

root@ansible:~/ejemplo_ansible# ansible all -m setup

Estructura de los Playbooks (sin roles)

Esquema Playbook (sin roles)

Playbooks sencillos: instalación de Apache2

Crear el fichero playbook_apache.yml y lanzarlos sobre los servidores web con el comando ansible-playbook (pedirá la contraseña del usario1: usuario1).

root@ansible:~/ejemplo_ansible# nano playbook_apache.yml
---
- name: instalacion de apache2 y php
  hosts: web
  sudo: yes
  tasks:
    - name: instalar apache2
      apt: name=apache2 update_cache=yes state=latest
root@ansible:~/ejemplo_ansible# ansible-playbook playbook_apache.yml --ask-sudo-pass

Crear los directorios plantillas y ficheros.

root@ansible:~/ejemplo_ansible# mkdir plantillas
root@ansible:~/ejemplo_ansible# mkdir ficheros

Crear el fichero index.html.j2 con la plantilla parametrizable del home por defecto.

root@ansible:~/ejemplo_ansible# nano plantillas/index.html.j2
<html>
<body>
<h1>Pagina por defecto de apache</h1>

<p>Contenido estático, contenido estático</p>
<p>Contenido estático, contenido estático</p>

<h1>Servido por {{ansible_hostname}} </h2>
</body>
</html>

Crear el fichero phpinfo.php con un ejemplo de página PHP.

root@ansible:~/ejemplo_ansible# nano ficheros/phpinfo.php
<?php
phpinfo();
phpinfo(INFO_MODULES);
?>

Completar el playbook de Apache con las siguientes tareas.

El fichero playbook_apache.yml resultante debe de quedar como:

---
- name: instalacion de apache2 y php
  hosts: web
  sudo: yes
  tasks:
    - name: instalar apache2
      apt: name=apache2 update_cache=yes state=latest

    - name: instalar php
      apt: name={{item}} state=latest
      with_items:
        - libapache2-mod-php
        - php-mysql
        - php-pear
      notify:
        - restart apache2

    - name: crear index.html
      template: src=plantillas/index.html.j2
         dest=/var/www/html/index.html
         backup=yes

    - name: copiar phpinfo.php
      copy: src=ficheros/phpinfo.php
         dest=/var/www/html/phpinfo.php

    - name: deshabilitar keepalive
      replace: dest='/etc/apache2/apache2.conf' 
         regexp='KeepAlive On'
         replace='KeepAlive Off'
      notify:
        - restart apache2

  handlers:
    - name: restart apache2
      service: name=apache2 state=restarted

Volver a lanzar el playbook y comprobar con un navegador web desde la máquina ansible que se accede a los ficheros index.html y phpinfo.php.

root@ansible:~/ejemplo_ansible# ansible-playbook playbook_apache.yml --ask-sudo-pass

Comprobar con el comando aptitude search apache2 la instalación de los paquetes en las máquinas web1, web2 y web3.

Playbooks sencillos: instalación de HAProxy

Crear el fichero playbook_haproxy.yml

---
- name: instalacion y configuracion de haproxy
  hosts: haproxy
  sudo: yes
  vars:
    haproxy_bind_address:  10.10.10.10
    haproxy_bind_port:     80
    haproxy_balance:       roundrobin
    haproxy_cluster_name:  ha_ansible
    haproxy_servers:
      - name: web1
        address: web1.cda.net:80
      - name: web2
        address: web2.cda.net:80
      - name: web3
        address: web3.cda.net:80
  tasks:
    - name: instalar paquete haproxy
      apt: name=haproxy state=installed

    - name: habilitar arranque haproxy
      lineinfile:
        dest: /etc/default/haproxy
        regexp: "^ENABLED.+$"
        line: "ENABLED=1"
        state: present

    - name: crear fichero configuracion
      template:
        src: plantillas/haproxy.cfg.j2
        dest: /etc/haproxy/haproxy.cfg
        mode: 0644
      notify: restart haproxy

  handlers:
    - name: restart haproxy
      service: name=haproxy state=restarted

Crear el fichero plantillas/haproxy.cfg.j2

global
        daemon
        user    haproxy
        group   haproxy
        log     127.0.0.1       local0
        log     127.0.0.1       local1  notice

defaults
        mode    http
        log     global
        timeout connect 10000ms
        timeout client  50000ms
        timeout server  50000ms

listen {{haproxy_cluster_name}}
        bind {{haproxy_bind_address}}:{{haproxy_bind_port}}
        mode http
        stats enable
        stats auth  cda:cda
        balance {{haproxy_balance}}
        cookie PHPSESSID prefix
{% for backend in haproxy_servers %}
        server {{ backend.name }} {{ backend.address }} cookie {{ backend.name }} check
{% endfor %}

Lanzar el playbook

root@ansible:~/ejemplo# ansible-playbook playbook_haproxy.yml --ask-sudo-pass

Desde un navegador web comprobar el funcionamiento del balanceador de carga accediendo a la URL haproxy.cda.net.

Comprobar en la máquina haproyx la configuración de HAProxy

Uso de Roles

(pendiente)