My Profile Photo

Mauricio Villagran - Blog


#Cloud #DevOps #Azure #Powershell #Microsoft


Ansible

Hoy en día el mundo de la nube es una realidad, está creciendo a un ritmo muy alto y los administradores de sistemas no debemos pasar dicha realidad por alto. Entonces debemos encontrar nuevas herramientas que nos permitan solucinar tareas que venimos haciendo de manera repetitiva. Configurar, actualizar maquinas, etc. Toda tarea mecánica que llega a ser identica y que la debemos repetir en grandes grupos de servidores en el menor tiempo posible. A raíz de esta necesidad han surgido diferentes herramientas que nos permiten automiatizar muchas tareas que se volverían repetitivas si las tuvieramos que aplicar en muchos servidores. Alguna de las herramientas a las que me refiero son los llamados gestores de configuración, Puppet, Chef, Salt, PowerShell DSC, y hoy les voy a hablar sobre Ansible.

AnsibleLogo_Logo

Introducción

Ansible es una herramienta open-source desarrollada en python. Actualmente la definen como un motor de orquestación muy simple que automatiza las tareas necesarias. La palabra clave en esta definición es simple y es que Ansible posee unas características que junto su amplia e inteligible documentación hacen esta herramienta realmente atractiva para aquellos que aún no automatizan sus tareas de administración ya que su curva de aprendizaje crece muy rápido.

Características más importantes

Estas son quizás las características más importantes:

  • Clientes sin agentes (Overhead muy bajo)
  • Método de autenticación por ssh (preferiblemente con claves) en paralelo, o mediante WMI y PowerShell para el caso de Windows.
  • No necesita usuario root (permite la utilización de sudo)
  • Permite utilizar comandos básicos
  • Para configurar tareas complejas utiliza lenguaje YAML (Playbooks)

Estructura de Ansible

Ansible permite diferentes formas de configuración, una podría ser mediante un solo fichero llamado playbook que contendría todos los parámetros para hacer una determinada tarea sobre un determinado grupo de servidores o mediante una estructura de directorios por cada proyecto separando los parámetros en ficheros, que luego nos permitirán importarlos desde otros playbooks.

A continuación haremos una introducción de la estructura simple de Ansible definiendo sus componentes para un proyecto concreto:

.
├── hosts <- inventory
├── playbook.yml <-playbook
└── roles
    └── webserver <- role webserver
        ├── files
        │   └── index.php
        └── tasks
            └── main.yml <- fichero de tareas

Modules: Los módulos son las librerías que utiliza para controlar servicios, ficheros, paquetes o comandos. Por ejemplo, si quisieramos instalar un paquete usando apt para el caso de Ubuntu o yum para el caso de CentOS.

Inventory: Fichero donde se definen hosts, o grupos de hosts y sus variables como podria ser el puerto ssh al que hay que conectarse. Por defecto /etc/ansible/hosts aunque también se puede crear uno por proyecto en la raiź del directorio.

# hosts

[webserver]
10.0.0.1    ansible_ssh_user=usuario    ansible_ssh_private_key_file=~/.ssh/id_rsa    ansible_ssh_port=22
[dbserver]
10.0.0.2    ansible_ssh_user=usuario_db    ansible_ssh_private_key_file=~/.ssh/id_rsa    ansible_ssh_port=22

Roles: Los roles son grupos de ficheros y tareas parecidos sobre un determinado grupo de hosts, por ejemplo, en el caso de la instalación de un WebServer podríamos tener un role para WebServer y otro para dbserver.

Files: En este directorio se almacenarán los ficheros que se deben copiar en los hosts que pertencen a ese role.

Tasks: Dentro de este directorio se debe crear el fichero main.yml donde definiremos las tareas que se deben ejecutar en los hosts que pertenecen a ese role.

# roles/webserver/tasks/main.yml
---
- name: 1. Instalar Apache
  apt: name=apache2 state=present

- name: 2. Instalar PHP
  apt: name=libapache2-mod-php5 state=present

- name: 3. Start Apache
  service: name=apache2 state=running enabled=yes

- name: 4. Copiar index.php
  copy: src=index.php dest=/var/www/index.php mode=0664

Una vez tenemos los ficheros ejecutamos Ansible

ansible-playbook -i hosts playbook.yml --sudo --verbose

PLAY [webserver] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [10.0.0.1]

TASK: [webserver | 1. Instalar Apache] **************************************** 
ok: [10.0.0.1] => {"changed": false, "item": ""}

TASK: [webserver | 2. Instalar PHP] ******************************************* 
ok: [10.0.0.1] => {"changed": false, "item": ""}

TASK: [webserver | 3. start Apache] ******************************************* 
ok: [10.0.0.1] => {"changed": false, "enabled": true, "item": "", "name": "apache2", "state": "started"}

TASK: [webserver | 4. Copiar index.php] *************************************** 
changed: [10.0.0.1] => {"changed": true, "dest": "/var/www/index.php", "gid": 1000, "group": "xavi", "item": "", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0664", "owner": "xavi", "size": 0, "src": "/home/xavi/.ansible/tmp/ansible-tmp-1398516303.41-96546412744806/source", "state": "file", "uid": 1000}

PLAY RECAP ******************************************************************** 
10.0.0.1                  : ok=5    changed=1    unreachable=0    failed=0

Creación de una maquina virtual Linux con Ansible

A continuación vamos a ver como crear una maquina virtual Linux en Azure y configuraremos los componentes necesarios para que dicha maquina virtual funcione. Para ello vamos a necesitar una maquina virtual con ansible que oficie de orquestador. Para ello podemos crear dicha maquina desde el portal de Azure, AzCli, o PowerShell.

En nuestro caso usaremos AzCli para crear dicha VM:

az vm create \
    --name AnsibleVM \
    --resource-group Ansible-RG \
    --image UbuntuLTS \
    --admin-username sadmin \
    --generate-ssh-keys

Una vez que creamos la maquina, nos conectamos por SSH a la misma e instalaremos los paquetes necesarios y porsupuesto Ansible.

sudo apt-get update && sudo apt-get install -y libssl-dev libffi-dev python-dev python-pip

pip install ansible[azure]

sudo apt install ansible

Creación de credenciales en Azure.

Ansible se comunica con Azure mediante un nombre de usuario y una contraseña, o a través de una entidad de servicio. Para ello debemos crear previamente una entidad de servicio en Azure para que podamos hacer que Ansible autentique.

Una vez que tenemos creada la entidad de servicio, debemos crear un archivo de credenciales de Ansible, para ello debemos hacer los siguiente:

mkdir ~/.azure
vi ~/.azure/credentials

Dentro del archivo de credenciales especificamos los datos de conexión contra Azure.

[default]
subscription_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_id=eec5624a-90f8-4386-8a87-02730b5410d5
secret=531dcffa-3aff-4488-99bb-4816c395ea3f
tenant=72f988bf-86f1-41af-91ab-2d7cd011db47

Creacion del playbook para la maquina virtual

Con un editor de textos generamos el archivo LinuxVm.yml el cual tendra la siguiente receta para crear nuestra VM en Azure.

- name: Create Azure VM
  hosts: localhost
  connection: local
  tasks:
  - name: Create virtual network
    azure_rm_virtualnetwork:
      resource_group: Ansible-RG
      name: Vnet
      address_prefixes: "10.0.0.0/16"
  - name: Add subnet
    azure_rm_subnet:
      resource_group: Ansible-RG
      name: Subnet
      address_prefix: "10.0.1.0/24"
      virtual_network: Vnet
  - name: Create public IP address
    azure_rm_publicipaddress:
      resource_group: Ansible-RG
      allocation_method: Static
      name: PublicIP
  - name: Create Network Security Group that allows SSH
    azure_rm_securitygroup:
      resource_group: Ansible-RG
      name: NetworkSecurityGroup
      rules:
        - name: SSH
          protocol: Tcp
          destination_port_range: 22
          access: Allow
          priority: 1001
          direction: Inbound
  - name: Create virtual network inteface card
    azure_rm_networkinterface:
      resource_group: Ansible-RG
      name: NIC
      virtual_network: Vnet
      subnet: Subnet
      public_ip_name: PublicIP
      security_group: NetworkSecurityGroup
  - name: Create VM
    azure_rm_virtualmachine:
      resource_group: Ansible-RG
      name: Linux-VM
      vm_size: Standard_D2_v3
      admin_username: azureuser
      ssh_password_enabled: true
      admin_password: Nacional1980
      #ssh_public_keys: 
      #  - path: /home/azureuser/.ssh/authorized_keys
      #    key_data: "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
      network_interfaces: NIC
      image:
        offer: CentOS
        publisher: OpenLogic
        sku: '7.3'
        version: latest

Luego ejecutaremos el siguiente comando:

ansible-playbook linux.yml

Luego que termine la ejecución veremos la siguiente salida:

PLAY [Create Azure VM] ****************************************************

TASK [Gathering Facts] ****************************************************
ok: [localhost]

TASK [Create virtual network] *********************************************
changed: [localhost]

TASK [Add subnet] *********************************************************
changed: [localhost]

TASK [Create public IP address] *******************************************
changed: [localhost]

TASK [Create Network Security Group that allows SSH] **********************
changed: [localhost]

TASK [Create virtual network inteface card] *******************************
changed: [localhost]

TASK [Create VM] **********************************************************
changed: [localhost]

PLAY RECAP ****************************************************************
localhost                  : ok=7    changed=6    unreachable=0    failed=0

Siguiendo los pasos que les mostré anteriormente creamos una VM Linux en Azure, pero no solo podemos crear VM sino que podemos aplicar una infinidad de configuraciones tanto en servidores que tengamos en la nube como onpremise.

Azure Ansible Official Page