introducción a ansible
Post on 12-Apr-2017
431 Views
Preview:
TRANSCRIPT
Ansible: Provisionando el futuroIntroducción, instalación y uso
@pabloros
De dónde venimos…
Nuestro entorno de desarrollo utiliza una máquina virtual gestionada por Vagrant y provisionada con Puppet
Nuestros servidores de producción se configuran de forma manual con muchos ficheros de configuración versionados.
… A dónde vamos
Nuestro entorno de desarrollo utiliza una máquina virtual gestionada por Vagrant y provisionada con Ansible
Nuestros servidores de producción se provisionarán con Ansible.
Nuestro Objetivo
Automatizar el provision de máquinas tanto de producción como de desarrollo.
Conseguir tener el mismo entorno en producción que en desarrollo (al menos lo más similar posible)
¿Qué fue primero?
Empezaremos configurando nuestro Ansible en desarrollo
Utilizaremos Vagrant para levantar la máquina virtual
Una vez finalizado, provisionaremos producción.
VagrantAcercándonos a producción
Por qué Vagrant ?
Nos simplifica la puesta en marcha de la máquina virtual.
Nos da herramientas para provisionar nuestra MV.
Fácil de compartir: puedes tener tu MV con un sólo fichero: VagrantFile
Vagrant.require_version ">= 1.5"Vagrant.configure("2") do |config| config.vm.box = "centos64_x86" config.ssh.forward_agent = true config.vm.synced_folder "../ansible", "/ansible" config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] v.customize ["modifyvm", :id, "--natdnsproxy1", "on"] end config.vm.define "web", primary: true do |web| web.vm.network :private_network, ip: "192.168.33.10" web.vm.network :forwarded_port, guest: 80, host: 8080, auto_correct: true web.vm.network :forwarded_port, guest: 443, host: 8081, auto_correct: true web.vm.hostname = "uvinumVm" web.vm.provision :shell, path: "shell/web_provision_ansible.sh", args: ["uvinumVm"] web.vm.synced_folder "./shared/www", "/var/www", create: true web.vm.synced_folder "./shared/logs", "/var/log/verticomm", create: true end config.vm.define "marawler_node", autostart: false do |marawler_node| marawler_node.vm.hostname = "marawlerNode" marawler_node.vm.network :private_network, ip: "192.168.33.11" marawler_node.vm.provision :shell, path: "shell/marawler_node.sh", args: ["marawlerNode"] endend
VagrantFile
Box que vamos a utilzar. CentOS
Hacemos forward agent para poder disponer de las keys de la máquina host.
Compartimos el directorio Ansible (veremos más adelante)
config.vm.box = "centos64_x86" config.ssh.forward_agent = true config.vm.synced_folder "../ansible", "/ansible"
VagrantFile
Configuramos que nuestra máquina virtual use la misma resolución de DNS que el host.
Esto es necesario ya que no usamos las default del ISP sino que nuestro propio servidor de DNS.
config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] v.customize ["modifyvm", :id, "--natdnsproxy1", "on"] end
VagrantFile
Dentro del mismo VagrantFile podemos definir varias máquinas virtuales.
La configuración en el interior de este módulo es propia de esta máquina.
Parámetros:
Nombre de la máquina (web)
Definimos que es la primaria.
config.vm.define "web", primary: true do |web| … end
VagrantFile
Definimos la IP de la red privada que queremos usar.
Hacemos forwarding de puertos para poder acceder a nuestra MV desde el exterior (otra máquina diferente a nuestro host)
web.vm.network :private_network, ip: "192.168.33.10"web.vm.network :forwarded_port, guest: 80, host: 8080, auto_correct: trueweb.vm.network :forwarded_port, guest: 443, host: 8081, auto_correct: true
VagrantFile
Definimos el HostName de nuestra máquina virtual.
Compartimos directorios en host y MV
create: true Crea el directorio en el host en caso de no existir.
Podemos compartir usando: VirtualBox o NFS
web.vm.hostname = "uvinumVm"web.vm.synced_folder "./shared/www", "/var/www", create: trueweb.vm.synced_folder "./shared/logs", "/var/log/verticomm", create: true
VagrantFile
Provisionamos nuestra máquina usando el tipo de porvision vía Shell.
Este script se ejecuta siempre que povisionamos la máquina.
web.vm.provision :shell, path: "shell/web_provision_ansible.sh", args: ["uvinumVm"]
VagrantFile
Otra MV gestiona por el mismo VagrantFile.
Parámetros:
autostart: false No se inicia al hacer un vagrant up
config.vm.define "marawler_node", autostart: false do |marawler_node| marawler_node.vm.hostname = "marawlerNode" marawler_node.vm.network :private_network, ip: "192.168.33.11" marawler_node.vm.provision :shell, path: "shell/marawler_node.sh", args: ["marawlerNode"] end
Y… Ansible?Y la Europea?
Intro a Ansible
Simple y directo para configurar una máquina
Usa YAML para definir la infraestructura. Es Human-readable y es como una documentación.
No necesita instalar nada en los nodos que vamos a provisionar :) (Bueno… ssh + Python 2.5)
Lo usa Twitter, Atlassian, Spotify, etc…
Diagrama Ansible
Diagrama Ansible
Instalación
Sólo hay que instalar Ansible en la Controller Machine
Requisitos: Python 2.6 or 2.7 installed (Windows no soportado)
En Mac (usando Brew)
$ brew install ansible
Playbook
Un Playbook es el término que usa Ansible para un script que gestiona configuraciones.
Escrito en YAML
Es siempre nuestro punto de entrada en la ejecución de Ansible.
Playbook
- name: My first playbook :) hosts: web-test sudo: true tasks: - name: Install Apache yum: pkg=httpd state=present
Playbook
Un Playbook es una lista de Plays
Cada Play debe contener:
hosts
tasks
Usan modules: yum, file, copy, service…
Inventories
Inventories son los hosts que Ansible podrá provisionar.
Contenido del fichero: inventories/hosts web-test 192.168.33.10
…Otro ejemplo web-test ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user=vagrant ansible_ssh_private_key_file=../vagrant/.vagrant/machines/web/virtualbox/private_key
Ejecución
$ ansible-playbook playbook_test.yml -i inventories/hosts
Escribiendo Playbooks: Variables
En nuestro Playbook podemos utilizar variables: ---- name: My first playbook :) hosts: web-test sudo: true vars: webserver: httpd state: present tasks: - name: Install Apache yum: pkg={{ webserver }} state= {{ state }}
Escribiendo Playbooks: Condicionales
Condicionales ---- name: My first playbook :) hosts: web-test sudo: true vars: webserver: httpd state: present tasks: - name: Install Apache yum: pkg={{ webserver }} state={{ state }} when: ansible_os_family == "RedHat"
Escribiendo Playbooks: Condicionales
- name: Check if PHP is installed register: php_installed command: php -v ignore_errors: true- name: Do something if PHP is installed debug: var=php_installed when: php_installed|success- name: Do something if PHP is NOT installed debug: msg='PHP is NOT installed' when: php_installed|failed
Escribiendo Playbooks: Iteraciones
- name: Install multiple packages yum: name={{item}} state=installed with_items: - vim - telnet - gcc
Escribiendo Playbooks: Iteraciones
---- name: My first playbook :) hosts: web-test sudo: true vars: common_packages: - vim - telnet - gcc tasks: - name: Install multiple packages yum: name={{item}} state=installed with_items: common_packages
Escribiendo Playbooks: Templates
Un template es un fichero que puede utilizar nuestras variables: templates/index.html
<h1>Hello {{ name_to_say_hello }}!</h1>
Y en nuestro Playbook:
- name: Use template template: src=templates/index.html dest=/home/vagrant/index_file.html
Escribiendo Playbooks: Handlers
Los handlers nos permiten gestionar servicios de nuestro sistema. Ejemplo: reiniciar Apache.
---- name: My first playbook :) hosts: web-test sudo: true vars: name_to_say_hello: Pablo tasks: - name: Use template template: src=templates/index.html dest=/home/vagrant/index_new.html notify: restart apache handlers: - name: restart apache service: name=httpd state=restarted
Organizando Playbooks
Los playbooks pueden crecer hasta el infinito y por ello podemos organizarlos usando:
inclusión de Plays
Roles
Organizando Playbooks: inclusión
---- name: My first playbook :) hosts: web-test sudo: true vars: name_to_say_hello: Pablo tasks: - include: tasks/writeFile.yml handlers: - name: restart apache service: name=httpd state=restarted
Organizando Playbooks: Roles
---- name: My first playbook :) hosts: web-test sudo: true vars: name_to_say_hello: Pablo roles: - writeFile
Organizando Playbooks: Roles
Los roles tienen que seguir esta estructura. Obligatorio un main.yml
Organizando Playbooks: Galaxy Ansible
Galaxy Ansible es un repositorio de roles públicos que se pueden usar en nuestros Playbooks isntalándolos previamente en la Controller Machine.
$ ansible-galaxy install geerlingguy.git
$ ansible-galaxy install geerlingguy.git,1.1.1
https://galaxy.ansible.com/geerlingguy/git/
Organizando Playbooks: Galaxy Ansible
Uso desde el playbook: ---- name: My first playbook :) hosts: web-test sudo: true vars: name_to_say_hello: Pablo roles: - { role: geerlingguy.git }
Organizando Playbooks: Group Vars
Podemos agrupar variables dentro del directorio group_vars, por inventories y por roles.
Añadimos grupos en los inventories:
[web]web-test ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user=vagrant ansible_ssh_private_key_file=../vagrant/.vagrant/machines/web/virtualbox/private_key
Organizando Playbooks: Group Vars
Nombre directorio por inventario y nombre de fichero por role.
Vagrant + Ansible
Provisionando Entorno de Desarrollo
Provision
Tenemos dos opciones:
Vagrant soporta Ansible como provisioner
Usar Ansible desde dentro de la MV que levanta Vagrant.
Provision
Vagrant soporta Ansible como provisioner:
PRO: Usamos un método nativo de Vagrant para provisionar.
CON: Dependemos que todas las máquinas hosts tengan instalado Ansible y los módulos que queremos utilizar.
CON: Y que no sea Windows…
Provision
Usar Ansible desde dentro de la MV:
PRO: La máquina host no necesita nada.
PRO: Los módulos se gestionan con vagrant y así tener mayor control de versiones.
CONS: Contra: usamos provision Shell de vagrant.
Provision
Nos quedamos con la opción de usar Ansible desde la MV para tener mayor control y ninguna dependencia con la máquina host.
web.vm.provision :shell, path: "shell/web_provision_ansible.sh", args: ["uvinumVm"]
#!/usr/bin/env bashif ! rpm -qa | grep -qw ansible;then echo "-> Installing Ansible" # Add Ansible Repository & Install Ansible wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm sudo rpm -Uvh epel-release-*.rpm sudo sed -i "s/mirrorlist=https/mirrorlist=http/" /etc/yum.repos.d/epel.repo # Install Ansible sudo yum -y install ansible # Add SSH key cat /ansible/files/authorized_keys >> /home/vagrant/.ssh/authorized_keyselse echo "-> Ansible already Installed!"fi # Install Ansible Galaxy modules# To review in furure: http://docs.ansible.com/ansible/galaxy.html#id12echo "-> Installing Ansibe Galaxy Modules"roles_list[8]='geerlingguy.git,1.1.0'for role_and_version in "${roles_list[@]}"do role_and_version_for_grep="${role_and_version/,/, }" if ! sudo ansible-galaxy list | grep -qw "$role_and_version_for_grep"; then echo "Installing ${role_and_version}" sudo ansible-galaxy -f install $role_and_version else echo "Already installed ${role_and_version}" fi done# Execute Ansibleecho "-> Execute Ansible"sudo ansible-playbook /ansible/playbook_test.yml -e hostname=$1 -i /ansible/inventories/hosts --connection=local
Bibliografia
Book: Lorin Hochstein. Ansible Up and Runnig. O’Reilly
Ansible Docs: http://docs.ansible.com/ansible/index.html
@erikaheidi slides: https://speakerdeck.com/erikaheidi/vagrant-provisioning-with-ansible
Dudas??La semana que viene Más!!! :D
top related