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.
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.