Diferencia entre revisiones de «Ansible»
| (No se muestran 10 ediciones intermedias del mismo usuario) | |||
| Línea 10: | Línea 10: | ||
* é amplamente usada para xestionar a configuración de servidores, para tarefas de aprovisionamento de instancias cloud, operacións dev-ops, ... | * é amplamente usada para xestionar a configuración de servidores, para tarefas de aprovisionamento de instancias cloud, operacións dev-ops, ... | ||
* ten unha filosofía que pode resumirse en que o estado de configuración final que queres que teña un equipo queda definido nun arquivo de texto, chamado ''playbook'' | * ten unha filosofía que pode resumirse en que o estado de configuración final que queres que teña un equipo queda definido nun arquivo de texto, chamado ''playbook'' | ||
| − | |||
Máis datos: | Máis datos: | ||
| Línea 61: | Línea 60: | ||
Ansible utiliza SSH coma protocolo de comuncación cos hosts administados. Os módul referenciados nos playbooks copianse nos hosts administrados. Despois se executan, en orde, cos argumentos especificados no playbook. Os usuarios de Ansible poden escribir os seus propios módulos personalizados se é preciso pero os módulo s principais que veñen con Ansible poden realizar a maioría das tarefas de administración do sistema. | Ansible utiliza SSH coma protocolo de comuncación cos hosts administados. Os módul referenciados nos playbooks copianse nos hosts administrados. Despois se executan, en orde, cos argumentos especificados no playbook. Os usuarios de Ansible poden escribir os seus propios módulos personalizados se é preciso pero os módulo s principais que veñen con Ansible poden realizar a maioría das tarefas de administración do sistema. | ||
| + | |||
| + | == Primeiros pasos == | ||
| + | |||
| + | Traballar con Ansible hai que comprender os seguintes termos: | ||
| + | ; Host Inventory | ||
| + | : é unha descrición dos nodos (equipos a administrar) ós que poderemos acceder usando Ansible. O inventory máis básico contén ós nodos agrupados por grupos (ubicacións xeográficas, servizos ou calquera outro criterio que consideremos) e as direccións IP ou nomes. | ||
| + | |||
| + | Un exemplo de inventory podería ser: | ||
| + | <pre> | ||
| + | $ cat /etc/ansible/hosts | ||
| + | [infor1] | ||
| + | 192.168.1.193 | ||
| + | 192.168.1.194 | ||
| + | 192.168.1.195 | ||
| + | |||
| + | [profesores] | ||
| + | 192.168.1.201 | ||
| + | 192.168.2.201 | ||
| + | 192.168.3.201 | ||
| + | </pre> | ||
| + | |||
| + | ; Playbooks | ||
| + | : trátase de arquivos de texto onde se describen configuracións ou tarefas de despregue. Dentro dun playbook haberá 'xogadas' (plays) onde se indican unha serie de tarefas a executar; por exemplo, actualizar a lista de paquetes, instalar o servidor web apache, activar o módulo ssl, copiar os arquivos de configuración dos sitios web a aloxar, crear as carpetas dos DocumentRoot dos sitios e copiar os arquivos que forma os sitios, activar os sitios web, reiniciar o servidor Apache, ... Os playbooks poden verse como arquivos que describen a configuración desexada para un equipo ou conxunto de equipos. | ||
| + | |||
| + | No seguinte exemplo podemos ver un playbook que fixera no seu día para por en marcha e configurar os equipos Linux Lubuntu dunha clase de informática de ESO/Bach do centro. Podese ver como unha foto do estado que quería acadar nos equipos e que se resume en que: | ||
| + | * Copiamos a todos os equipos da clase un arquivo sources.list para que todos teñan e usen os mesmos repositorios. | ||
| + | * Copiamos a todos os equipos da clase o arquivo 01apt-cacherng-proxy para que usen o apt-cacher-ng e se aceleren os procesos de instalación/actualización de paquetes. | ||
| + | * Copiamos en /etc/skel unha plantilla para que os usuarios do equipo partan da mesma configuración de escritorio (iconas, menús, ligazóns de favoritos, ...). | ||
| + | * Creamos uns usuarios e configuramos o contrasinal de root. | ||
| + | * Configuramos a sincronización de hora para que vaian a un servidor de hora interno no IES. | ||
| + | * Borramos algúns programas que viñan coa instalación básica de Lubuntu (Abiword e gnumeric). | ||
| + | * Engadimos algúns repositorios ppa para ter as últimas versións de Inkscape e LibreOffice. | ||
| + | * Actualizamos os equipos e instalamos unha colección de paquetes indicada no arquivo paquetes_ESO1.yml (arandr, libreoffice, libreoffice-l10n-es, vlc, audacity, inkscape, ...). | ||
| + | * Deshabilitamos a impresión nos equipos. | ||
| + | |||
| + | <pre> | ||
| + | --- | ||
| + | - hosts: infor1 | ||
| + | become: yes | ||
| + | remote_user: magasix | ||
| + | become_method: sudo | ||
| + | gather_facts: false | ||
| + | vars_files: | ||
| + | - /media/DATOS/Tutoriales/ansible/paquetes_ESO1.yml | ||
| + | |||
| + | tasks: | ||
| + | - name: copiar fichero de repositorios | ||
| + | copy: src=/media/DATOS/Tutoriales/ansible/sources.list_ESO1.txt dest=/etc/apt/sources.list | ||
| + | |||
| + | - name: copiar fichero de apt-cacherng-proxy | ||
| + | copy: src=/media/DATOS/Tutoriales/ansible/01apt-cacherng-proxy_ESO1.txt dest=/etc/apt/apt.conf.d/01apt-cacherng-proxy | ||
| + | |||
| + | - name: crear grupo alumnos | ||
| + | group: name=alumnos state=present | ||
| + | |||
| + | - name: copiar skel | ||
| + | copy: src=/media/DATOS/Tutoriales/ansible/skel/ dest=/etc/skel/ | ||
| + | |||
| + | - name: crear usuario alumno | ||
| + | user: name=alumno comment="Alumno IES" shell=/bin/bash groups=alumnos state=present | ||
| + | |||
| + | - name: password en blanco | ||
| + | shell: passwd -d alumno | ||
| + | |||
| + | - name: crear usuario alumno TICs abc123. | ||
| + | user: name=alumnotics comment="Alumno TICs" shell=/bin/bash groups=alumnos password=ylMqA85PRieLg state=present | ||
| + | |||
| + | - name: password a root | ||
| + | user: name=root password=rDQVP5utaEC9E | ||
| + | |||
| + | - name: desinstalar ntp | ||
| + | apt: name=ntp state=absent purge=yes | ||
| + | |||
| + | - name: configurar ntpdate | ||
| + | copy: src=/media/DATOS/Tutoriales/ansible/ntpdate.conf_ESO1.txt dest=/etc/default/ntpdate | ||
| + | |||
| + | - name: fijar lubuntu-desktop | ||
| + | shell: apt-mark manual lubuntu-desktop | ||
| + | |||
| + | - name: borrar abiword | ||
| + | apt: name=abiword state=absent purge=yes | ||
| + | |||
| + | - name: borrar gnumeric | ||
| + | apt: name=gnumeric state=absent purge=yes | ||
| + | |||
| + | - name: repositorio inkscape | ||
| + | apt_repository: repo='ppa:inkscape.dev/stable' update_cache=no | ||
| + | |||
| + | - name: repositorio libreoffice 5 | ||
| + | apt_repository: repo='ppa:libreoffice/ppa' update_cache=no | ||
| + | |||
| + | - name: actualizar equipo | ||
| + | apt: upgrade=dist update_cache=yes | ||
| + | |||
| + | - name: instalacion de paquetes | ||
| + | apt: pkg={{ item }} state=installed | ||
| + | with_items: '{{system_packages}}' | ||
| + | |||
| + | - name: deshabilitar impresion | ||
| + | service: name=cups state=stopped enabled=no | ||
| + | </pre> | ||
| + | |||
| + | No exemplo podemos ver que aparecen palabras como user, shell, apt,_repository, apt, service, ..., e que correspóndense con nomes de módulos de ansible. Os módulos permiten efectuar tarefas de configuración nos equipos a administrar; por exemplo, o módulo apt permite xestionar paquetes .deb en equipos Debian/Ubuntu. | ||
| + | |||
| + | Pódese ver na sección de documentación todos os módulos dos que dispón Ansible: | ||
| + | |||
| + | Módulos Packaging | ||
| + | |||
| + | Fig. Módulos para a xestión de paquetes en Ansible | ||
| + | |||
| + | Para traballar con Ansible únicamente precisamos o seguinte: | ||
| + | * Un nodo de xestión con Ansible instalado (ten que ser unha máquina Linux). | ||
| + | * Nodo/s a xestionar con ssh instalado e configurado para permitir as conexións dende o nodo xestor. A diferenza doutro software semellante, como Puppet, Chef ou Salt, non é preciso instalar ningún software axente nos nodos administrados. Os nodos a administrar poden ser Linux ou Windows. | ||
| + | |||
| + | Resumindo o funcionamento nunha imaxe: as tarefas/configuracións recollidas no Playbook realizaranse no equipo indicado no Host Inventory, usando unha canle ssh para comunicarse o nodo xestor co nodo administrado. | ||
| + | |||
| + | Administración con ansible | ||
| + | |||
| + | Fig. Administración con Ansible. Fonte: 19 Minutes with Ansible | ||
| + | |||
| + | Se en vez de lanzar o playbook contra un equipo lánzase contra un grupo de equipos, teremos un grupo de equipos que comparten a mesma configuración. No exemplo anterior, lanzar o playbook contra os 20 Lubuntus recén instalados na aula, implica que ó cabo dun rato teremos 20 equipos configurados exactamente igual. Traballar con playbooks que recollan os cambios de configuración/tarefas a realizar facilita o mantemento dos sistemas, permite incorporar novos equipos que teñan exactamente a mesma configuración que o resto, ... Case podemos pensar nos playbooks como a nosa infraestrutura documentada. | ||
| + | |||
| + | Administración con ansible | ||
| + | |||
| + | Fig. Lanzando un playbook contra un grupo de nodos. Fonte: 19 Minutes with Ansible | ||
| + | |||
| + | A modo de exemplo amoso a saída resultante de lanzar o playbook anterior contra 3 equipos e podemos observar como se van realizando as diferentes tarefas (''tasks''), levando a todos os equipos ó mesmo estado de configuración: | ||
| + | $ ansible-playbook lubuntu_ies_alumnos_ntpdate_ESO1_casa.yml -K | ||
| + | <pre> | ||
| + | SUDO password: | ||
| + | |||
| + | PLAY *************************************************************************** | ||
| + | |||
| + | TASK [copiar fichero de repositorios] ****************************************** | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.194] | ||
| + | |||
| + | TASK [copiar fichero de apt-cacherng-proxy] ************************************ | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.194] | ||
| + | |||
| + | TASK [crear grupo alumnos] ***************************************************** | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | TASK [copiar skel] ************************************************************* | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.194] | ||
| + | |||
| + | TASK [crear usuario alumno] **************************************************** | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [password en blanco] ****************************************************** | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [crear usuario alumno TICs abc123.] *************************************** | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | TASK [password a root] ********************************************************* | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | TASK [desinstalar ntp] ********************************************************* | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [configurar ntpdate] ****************************************************** | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | TASK [fijar lubuntu-desktop] *************************************************** | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [borrar abiword] ********************************************************** | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [borrar gnumeric] ********************************************************* | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [repositorio inkscape] **************************************************** | ||
| + | changed: [192.168.1.195] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | |||
| + | TASK [repositorio libreoffice 5] *********************************************** | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | TASK [actualizar equipo] ******************************************************* | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | TASK [instalacion de paquetes] ************************************************* | ||
| + | ok: [192.168.1.194] => (item=[u'build-essential', u'arandr', u'libreoffice', u'libreoffice-l10n-es', u'lubuntu-restricted-addons', u'lubuntu-restricted-extras', u'ubuntu-restricted-extras', u'ubuntu-restricted-addons', u'icedtea-plugin', u'vlc', u'audacity', u'inkscape', u'openshot', u'sweethome3d', u'sweethome3d-furniture', u'sweethome3d-furniture-nonfree', u'gimp', u'gimp-data', u'gimp-data-extras', u'gimp-dcraw', u'gimp-gmic', u'gimp-help-es', u'gimp-plugin-registry', u'scribus', u'scribus-template', u'scribus-doc']) | ||
| + | ok: [192.168.1.193] => (item=[u'build-essential', u'arandr', u'libreoffice', u'libreoffice-l10n-es', u'lubuntu-restricted-addons', u'lubuntu-restricted-extras', u'ubuntu-restricted-extras', u'ubuntu-restricted-addons', u'icedtea-plugin', u'vlc', u'audacity', u'inkscape', u'openshot', u'sweethome3d', u'sweethome3d-furniture', u'sweethome3d-furniture-nonfree', u'gimp', u'gimp-data', u'gimp-data-extras', u'gimp-dcraw', u'gimp-gmic', u'gimp-help-es', u'gimp-plugin-registry', u'scribus', u'scribus-template', u'scribus-doc']) | ||
| + | ok: [192.168.1.195] => (item=[u'build-essential', u'arandr', u'libreoffice', u'libreoffice-l10n-es', u'lubuntu-restricted-addons', u'lubuntu-restricted-extras', u'ubuntu-restricted-extras', u'ubuntu-restricted-addons', u'icedtea-plugin', u'vlc', u'audacity', u'inkscape', u'openshot', u'sweethome3d', u'sweethome3d-furniture', u'sweethome3d-furniture-nonfree', u'gimp', u'gimp-data', u'gimp-data-extras', u'gimp-dcraw', u'gimp-gmic', u'gimp-help-es', u'gimp-plugin-registry', u'scribus', u'scribus-template', u'scribus-doc']) | ||
| + | |||
| + | TASK [deshabilitar impresion] ************************************************** | ||
| + | changed: [192.168.1.193] | ||
| + | changed: [192.168.1.194] | ||
| + | changed: [192.168.1.195] | ||
| + | |||
| + | PLAY RECAP ********************************************************************* | ||
| + | 192.168.1.193 : ok=18 changed=18 unreachable=0 failed=0 | ||
| + | 192.168.1.194 : ok=18 changed=18 unreachable=0 failed=0 | ||
| + | 192.168.1.195 : ok=18 changed=18 unreachable=0 failed=0 | ||
| + | </pre> | ||
| + | |||
| + | === Modo ''ad-hoc'' === | ||
| + | |||
| + | Aínda que traballar con playbooks é o recomendado, Ansible permite traballar en modo ad-hoc; é dicir, executar tarefas sen necesidade de crear e gardar un playbook. Por exemplo, comprobar o estado dos equipos, executar comandos do sistema, copias arquivos en calquera sentido, ... | ||
| + | |||
| + | A modo de exemplo: | ||
| + | $ ansible infor1 -m ping -u magasix | ||
| + | <pre> | ||
| + | 192.168.1.194 | SUCCESS => { | ||
| + | "changed": false, | ||
| + | "ping": "pong" | ||
| + | } | ||
| + | 192.168.1.195 | SUCCESS => { | ||
| + | "changed": false, | ||
| + | "ping": "pong" | ||
| + | } | ||
| + | 192.168.1.193 | SUCCESS => { | ||
| + | "changed": false, | ||
| + | "ping": "pong" | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | $ ansible infor1 -m shell -a "shutdown -h now" -u magasix --sudo -K | ||
| + | <pre> | ||
| + | SUDO password: | ||
| + | 192.168.1.194 | SUCCESS | rc=0 >> | ||
| + | 192.168.1.195 | SUCCESS | rc=0 >> | ||
| + | 192.168.1.193 | SUCCESS | rc=0 >> | ||
| + | </pre> | ||
== Alternativas == | == Alternativas == | ||
| Línea 120: | Línea 376: | ||
| 2012 | | 2012 | ||
|} | |} | ||
| + | |||
| + | = Escenario con Ansible = | ||
| + | == Configuración do escenario == | ||
| + | |||
| + | O obxectivo deste Escenario 8D é facer unha primeira aproximación a Ansible e ver as posibilidades que proporciona ós administradores de sistemas como ferramenta avanzada de configuración e automatización. O noso obxectivo será montar un sistema con tres servidores web idénticos que imos supoñer que forman parte dun backend e teñen as seguintes características: | ||
| + | * Hai que instalar e configurar fail2ban para que no arquivo de configuración jail.local o tempo de búsqueda sexa de 10 minutos, o de baneo 20 minutos e o número máximo de intentos sexa 3. | ||
| + | * Hai que configurar o syslog para que a reducción da repetición de mensaxes se desactive ( $RepeatedMsgReduction off ) | ||
| + | * Os servidores corren Apache e php 8.2 | ||
| + | * Responden a solicitudes por http e https (con certificado propio autofirmado) dirixidas a www.manuel2023.test | ||
| + | * Teñen unha páxina web index.php co seguinte contido: | ||
| + | <pre> | ||
| + | <?php | ||
| + | echo " | ||
| + | <html> | ||
| + | <head> | ||
| + | <title>Sitio web en ${_SERVER["SERVER_ADDR"]}</title> | ||
| + | </head> | ||
| + | <body> | ||
| + | <img src=”imaxes/logo.png” alt=”logotipo”> | ||
| + | <h1>Sitio Web www.manuel2023.test</h1> | ||
| + | Estás en ${_SERVER["SERVER_ADDR"]} | ||
| + | </body> | ||
| + | </html>"; | ||
| + | ?> | ||
| + | </pre> | ||
| + | * Non se permiten opcións como listado de directorios, seguir enlaces simbólicos, ... | ||
| + | * Non se permite personalizar as opcións usando arquivos htaccess. | ||
| + | * O sitio web ten os seus propios ficheros de log (o mesmo tanto para o acceso por http como https). | ||
| + | |||
| + | == Instalación e comandos ad-hoc == | ||
| + | |||
| + | === Instalación de Ansible === | ||
| + | |||
| + | [https://docs.ansible.com/ansible/latest/installation_guide/installation_distros.html Instalaremos Ansible] nun equipo Linux que exercerá de nodo administrador e os pasos a seguir son: | ||
| + | $ sudo apt update | ||
| + | $ sudo apt install software-properties-common | ||
| + | $ sudo apt-add-repository ppa:ansible/ansible | ||
| + | $ sudo apt install ansible | ||
| + | |||
| + | === Creación do inventory === | ||
| + | |||
| + | Unha vez rematada a instalación temos que crear un inventory cos equipos que queremos administrar. | ||
| + | |||
| + | '''NOTA'''. No caso de non estar creado o directorio /etc/ansible, hai que proceder a crealo mediante: | ||
| + | mkdir /etc/ansible | ||
| + | |||
| + | $ sudo nano /etc/ansible/hosts | ||
| + | <pre> | ||
| + | # grupo contedores | ||
| + | [incus] | ||
| + | 192.0.2.191 | ||
| + | 192.0.2.192 | ||
| + | 192.0.2.193 | ||
| + | </pre> | ||
| + | |||
| + | No inventory pódese engadir máis información asociada ós nodos a administrar como o usuario co que Ansible iniciará sesión, que no noso caso pode ser o usuario ubuntu ou o usuario magasix creada no aprovisionamento dos contedores: | ||
| + | $ sudo nano /etc/ansible/hosts | ||
| + | <pre> | ||
| + | # grupo contedores | ||
| + | [incus] | ||
| + | 192.0.2.191 | ||
| + | 192.0.2.192 | ||
| + | 192.0.2.193 | ||
| + | |||
| + | [incus:vars] | ||
| + | ansible_user=ubuntu | ||
| + | </pre> | ||
| + | |||
| + | === Autenticación mediante identidades dixitais === | ||
| + | |||
| + | Ansible usará ssh para entrar nos equipos a xestionar e unha práctica recomendada é [http://PENDIENTE autenticarse mediante identidades dixitais como se explicou PENDIENTE] polo que procedemos a autorizar unha clave dixital e a indicalo no inventory. Usamos o usuario ubuntu con contrasinal abc123. | ||
| + | |||
| + | $ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@192.0.2.191 | ||
| + | $ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@192.0.2.192 | ||
| + | $ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@192.0.2.193 | ||
| + | |||
| + | Despois de autorizar a clave, verificar que é posible conectarse. | ||
| + | |||
| + | $ sudo nano /etc/ansible/hosts | ||
| + | <pre> | ||
| + | # grupo contedores | ||
| + | [incus] | ||
| + | 192.0.2.191 | ||
| + | 192.0.2.192 | ||
| + | 192.0.2.193 | ||
| + | |||
| + | [incus:vars] | ||
| + | ansible_ssh_user=ubuntu | ||
| + | ansible_ssh_private_key_file=~/.ssh/id_rsa | ||
| + | ansible_python_interpreter=/usr/bin/python3 | ||
| + | </pre> | ||
| + | |||
| + | Vemos que no inventory é posible engadir variables asociadas a equipos ou grupos de equipos como ansible_ssh_private_key_file e ansible_python_interpreter (permite indicar que intérprete de python hai nos hosts sen necesidade que o detecte ansible). | ||
| + | |||
| + | === Verificación con ping === | ||
| + | |||
| + | Agora podemos verificar que Ansible é capaz de conectarse cos servers executando un 'ping': | ||
| + | |||
| + | $ ansible incus -m ansible.builtin.ping | ||
| + | <pre> | ||
| + | 192.0.2.191 | SUCCESS => { | ||
| + | "changed": false, | ||
| + | "ping": "pong" | ||
| + | } | ||
| + | 192.0.2.193 | SUCCESS => { | ||
| + | "changed": false, | ||
| + | "ping": "pong" | ||
| + | } | ||
| + | 192.0.2.192 | SUCCESS => { | ||
| + | "changed": false, | ||
| + | "ping": "pong" | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | === Comandos AD-HOC === | ||
| + | |||
| + | Os comandos ad-hoc están para cando se quere facer algo pero non queremos gardarlo para outras ocasións ou non se considera necesario escribir un playbook. Aínda que para aproveitar todo o potencial de Ansible están os playbooks, os comandos ad-hoc permiten facer cosas de forma rápida. Por exemplo, facemos un ss -ltnp: | ||
| + | $ ansible incus -m ansible.builtin.shell -a 'ss -ltnp' | ||
| + | <pre> | ||
| + | 192.0.2.193 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* | ||
| + | LISTEN 0 128 [::]:22 [::]:* | ||
| + | 192.0.2.192 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* | ||
| + | LISTEN 0 128 [::]:22 [::]:* | ||
| + | 192.0.2.191 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* | ||
| + | LISTEN 0 128 [::]:22 [::]:* | ||
| + | </pre> | ||
| + | |||
| + | Hai que sinalar qué ansible.builtin.shell é o nome completo do módulo de Ansible e shell é a forma abreviada. | ||
| + | |||
| + | $ ansible incus -m shell -a 'ss -ltnp' | ||
| + | <pre> | ||
| + | 192.0.2.191 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* | ||
| + | LISTEN 0 128 [::]:22 [::]:* | ||
| + | 192.0.2.193 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* | ||
| + | LISTEN 0 128 [::]:22 [::]:* | ||
| + | 192.0.2.192 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* | ||
| + | LISTEN 0 128 [::]:22 [::]:* | ||
| + | </pre> | ||
| + | |||
| + | Aínda que en moitos titoriais de Ansible aparece a forma abreviada, os desenvolvedores de Ansible recomendan usar o nome completo en vez da abreviada para evitar posibles conflictos. | ||
| + | |||
| + | No caso de querer executar o comando nos hosts como administrador pódese empregar as opcións -b e -K: | ||
| + | * -b (become): indica que se quere escalar privilexios nos hosts | ||
| + | * -K: pregunta polo contrasinal para elevar os privilexios | ||
| + | |||
| + | $ ansible incus -m ansible.builtin.shell -a 'ss -ltnp' -b -K | ||
| + | <pre> | ||
| + | BECOME password: | ||
| + | 192.0.2.192 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=165,fd=13)) | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=220,fd=3)) | ||
| + | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=220,fd=4)) | ||
| + | 192.0.2.191 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=166,fd=13)) | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=229,fd=3)) | ||
| + | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=229,fd=4)) | ||
| + | 192.0.2.193 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=166,fd=13)) | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=211,fd=3)) | ||
| + | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=211,fd=4)) | ||
| + | </pre> | ||
| + | |||
| + | O usuario ubuntu está autorizado para facer sudo sen necesidade de introducir o contrasinal, polo que no noso escenario o comando anterior podería executarse sen -K. Sinalar tamén que é posible gardar contrasinais cifradas empregando o concepto de vault. | ||
| + | |||
| + | === Posibles operacións === | ||
| + | |||
| + | Podemos copiar arquivos de local a remoto e viceversa, xestionar usuarios, servizos, paquetes, ... | ||
| + | |||
| + | Por exemplo, para copìar un arquivo local chamado backup.yml en todos os servidores podería executar: | ||
| + | $ ansible incus -m ansible.builtin.copy -a "src=config_backup.yml dest=/home/ubuntu/config.yml" | ||
| + | <pre> | ||
| + | 192.0.2.192 | CHANGED => { | ||
| + | "changed": true, | ||
| + | "checksum": "39244f4abbbb552d9d3e00eb27d05cfd6b8bfa44", | ||
| + | "dest": "/home/ubuntu/config.yml", | ||
| + | "gid": 1001, | ||
| + | "group": "ubuntu", | ||
| + | "md5sum": "1f5b15fb9e83f47d213637efe71f3d20", | ||
| + | "mode": "0664", | ||
| + | "owner": "ubuntu", | ||
| + | "size": 424, | ||
| + | "src": "/home/ubuntu/.ansible/tmp/ansible-tmp-1685284269.5834956-25446-44703324742452/source", | ||
| + | "state": "file", | ||
| + | "uid": 1001 | ||
| + | } | ||
| + | 192.0.2.191 | CHANGED => { | ||
| + | "changed": true, | ||
| + | "checksum": "39244f4abbbb552d9d3e00eb27d05cfd6b8bfa44", | ||
| + | "dest": "/home/ubuntu/config.yml", | ||
| + | "gid": 1001, | ||
| + | "group": "ubuntu", | ||
| + | "md5sum": "1f5b15fb9e83f47d213637efe71f3d20", | ||
| + | "mode": "0664", | ||
| + | "owner": "ubuntu", | ||
| + | "size": 424, | ||
| + | "src": "/home/ubuntu/.ansible/tmp/ansible-tmp-1685284269.628682-25444-43771047461490/source", | ||
| + | "state": "file", | ||
| + | "uid": 1001 | ||
| + | } | ||
| + | 192.0.2.193 | CHANGED => { | ||
| + | "changed": true, | ||
| + | "checksum": "39244f4abbbb552d9d3e00eb27d05cfd6b8bfa44", | ||
| + | "dest": "/home/ubuntu/config.yml", | ||
| + | "gid": 1001, | ||
| + | "group": "ubuntu", | ||
| + | "md5sum": "1f5b15fb9e83f47d213637efe71f3d20", | ||
| + | "mode": "0664", | ||
| + | "owner": "ubuntu", | ||
| + | "size": 424, | ||
| + | "src": "/home/ubuntu/.ansible/tmp/ansible-tmp-1685284269.6718416-25448-47330558216673/source", | ||
| + | "state": "file", | ||
| + | "uid": 1001 | ||
| + | } | ||
| + | </pre> | ||
| + | $ ansible incus -m ansible.builtin.shell -a 'ls -lhF' | ||
| + | <pre> | ||
| + | 192.0.2.193 | CHANGED | rc=0 >> | ||
| + | total 2,5K | ||
| + | -rw-rw-r-- 1 ubuntu ubuntu 2,1K mar 1 17:10 config.yml | ||
| + | 192.0.2.192 | CHANGED | rc=0 >> | ||
| + | total 2,5K | ||
| + | -rw-rw-r-- 1 ubuntu ubuntu 2,1K mar 1 17:10 config.yml | ||
| + | 192.0.2.191 | CHANGED | rc=0 >> | ||
| + | total 2,5K | ||
| + | -rw-rw-r-- 1 ubuntu ubuntu 2,1K mar 1 17:10 config.yml | ||
| + | </pre> | ||
| + | |||
| + | Na páxina [http://docs.ansible.com/ansible/latest/intro_adhoc.html Introduction To Ad-Hoc Commands] podemos ver máis exemplos desta forma de usar Ansible. | ||
| + | |||
| + | == Playbooks == | ||
| + | |||
| + | Despois de revisar por riba o uso de ansible chegamos o punto forte que son os playbooks. Como primeira aproximación executaremos o playbook actualizar.yml que permitirá actualizar os equipo servidores e como pode verse é moi sinxelo de entender: | ||
| + | * Aplícase os equipo incus definidos no inventory. | ||
| + | * Execútase como administrador (become: yes) | ||
| + | * Actualiza a lista de paquetes e fai unha actualización do sistema. | ||
| + | |||
| + | <pre> | ||
| + | --- | ||
| + | - hosts: incus | ||
| + | become: yes | ||
| + | tasks: | ||
| + | - name: actualizar lista de paquetes y el sistema | ||
| + | apt: | ||
| + | update_cache: yes | ||
| + | cache_valid_time: 3600 | ||
| + | - name: actualizar sistema | ||
| + | apt: | ||
| + | upgrade: dist | ||
| + | </pre> | ||
| + | |||
| + | Para lanzalo imos a carpeta de devops e: | ||
| + | $ ansible-playbook actualizar.yml -K | ||
| + | <pre> | ||
| + | SUDO password: | ||
| + | |||
| + | PLAY [incus] ************************************************************************************************************************************************************************************* | ||
| + | |||
| + | TASK [Gathering Facts] ************************************************************************************************************************************************************************* | ||
| + | ok: [192.0.2.191] | ||
| + | ok: [192.0.2.192] | ||
| + | ok: [192.0.2.193] | ||
| + | |||
| + | TASK [actualizar lista de paquetes y el sistema] *********************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | |||
| + | TASK [actualizar sistema] ********************************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | |||
| + | PLAY RECAP ************************************************************************************************************************************************************************************* | ||
| + | 192.0.2.191 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 | ||
| + | 192.0.2.192 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 | ||
| + | 192.0.2.193 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 | ||
| + | </pre> | ||
| + | |||
| + | Todas as actuacións a realizar para levar ós servidores ó estado de configuración indicado no enunciado sabemos facelas a man como fixemos ó longo de diversos escenarios do curso; sen embargo, agora imos a recollelas nun playbook que permitirá automatizar a súa execución. Non é obxectivo deste apartado explicar exhaustivamente como facelo; xa que Ansible daría para un curso enteiro, pero si revisar o playbook server-apache.yml vendo que é moi sinxelo de entender e executalo para ver a súa potencialidade. | ||
| + | |||
| + | Definimos os equipos ós que se vai aplicar o playbook que executarase como administrador e usando as variables recollidas no arquivo vars.yml | ||
| + | <pre> | ||
| + | --- | ||
| + | - hosts: incus | ||
| + | become: yes | ||
| + | vars_files: | ||
| + | - vars.yml | ||
| + | </pre> | ||
| + | |||
| + | Actualizamos a listaxe de paquetes e despois instalamos os seguintes: | ||
| + | <pre> | ||
| + | - name: instalar paquetes | ||
| + | ansible.builtin.apt: | ||
| + | name: | ||
| + | - curl | ||
| + | - unzip | ||
| + | - fail2ban | ||
| + | - apache2 | ||
| + | - php | ||
| + | - php-cli | ||
| + | - php-common | ||
| + | - php-curl | ||
| + | - php-gd | ||
| + | - libapache2-mod-php | ||
| + | state: latest | ||
| + | update_cache: yes | ||
| + | cache_valid_time: 3600 | ||
| + | </pre> | ||
| + | |||
| + | Creamos o arquivo jail.local a partir do jail.conf e procedemos a reemprazar os valores por defecto dos parámetros de configuración polos pedidos: | ||
| + | <pre> | ||
| + | - name: crear jail.local | ||
| + | ansible.builtin.copy: | ||
| + | src: /etc/fail2ban/jail.conf | ||
| + | dest: /etc/fail2ban/jail.local | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: 0644 | ||
| + | remote_src: True | ||
| + | |||
| + | - name: modificar parametro bantime en jail.local | ||
| + | ansible.builtin.lineinfile: | ||
| + | path: /etc/fail2ban/jail.local | ||
| + | regexp: '^bantime = 10m' | ||
| + | line: 'bantime = 1200' | ||
| + | state: present | ||
| + | notify: reiniciar fail2ban | ||
| + | |||
| + | - name: modificar parametro findtime en jail.local | ||
| + | ansible.builtin.lineinfile: | ||
| + | path: /etc/fail2ban/jail.local | ||
| + | regexp: '^findtime = 10m' | ||
| + | line: 'findtime = 300' | ||
| + | state: present | ||
| + | notify: reiniciar fail2ban | ||
| + | |||
| + | - name: modificar parametro maxretry en jail.local | ||
| + | ansible.builtin.replace: | ||
| + | path: /etc/fail2ban/jail.local | ||
| + | regexp: '^maxretry = 5' | ||
| + | replace: 'maxretry = 3' | ||
| + | notify: reiniciar fail2ban | ||
| + | Anulamos a reducción de mensaxe no rsyslog: | ||
| + | - name: anular reduccion mensajes rsyslog | ||
| + | ansible.builtin.lineinfile: | ||
| + | path: /etc/rsyslog.conf | ||
| + | regexp: '^\$RepeatedMsgReduction on' | ||
| + | line: '$RepeatedMsgReduction off' | ||
| + | state: present | ||
| + | backrefs: yes | ||
| + | notify: reiniciar syslog | ||
| + | </pre> | ||
| + | |||
| + | Asegurámonos que Apache e fail2ban estén funcionando: | ||
| + | <pre> | ||
| + | - name: Arrancar Apache y fail2ban | ||
| + | ansible.builtin.service: name={{ item }} state=started enabled=yes | ||
| + | with_items: | ||
| + | - apache2 | ||
| + | - fail2ban | ||
| + | </pre> | ||
| + | Habilitamos o módulo ssl para poder configurar o https: | ||
| + | <pre> | ||
| + | - name: habilitar módulo ssl | ||
| + | community.general.apache2_module: | ||
| + | state: present | ||
| + | name: ssl | ||
| + | notify: reiniciar Apache | ||
| + | </pre> | ||
| + | |||
| + | Engadimos o virtualhost http e https para o dominio: | ||
| + | <pre> | ||
| + | - name: añadir virtualhost para el dominio | ||
| + | ansible.builtin.template: | ||
| + | src: templates/sitio_web.conf.j2 | ||
| + | dest: /etc/apache2/sites-available/{{ nombre_dominio }}.conf | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: 0644 | ||
| + | |||
| + | - name: añadir virtualhost https para el dominio | ||
| + | ansible.builtin.template: | ||
| + | src: templates/sitio_web_https.conf.j2 | ||
| + | dest: /etc/apache2/sites-available/{{ nombre_dominio }}_https.conf | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: 0644 | ||
| + | </pre> | ||
| + | |||
| + | Copiamos os certificados e as páxinas do sitio web: | ||
| + | <pre> | ||
| + | - name: copiar certificados sitio web | ||
| + | ansible.builtin.copy: | ||
| + | src: '{{ item }}' | ||
| + | dest: /etc/apache2/certificados/ | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: 0644 | ||
| + | with_fileglob: | ||
| + | - '{{ nombre_dominio }}.*' | ||
| + | |||
| + | - name: copiar sitio web | ||
| + | ansible.builtin.copy: | ||
| + | src: web/ | ||
| + | dest: '{{ documentroot }}' | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: 0644 | ||
| + | </pre> | ||
| + | |||
| + | Habilitamos os sitios web http/https e deshabilitamos o sitio por defecto: | ||
| + | <pre> | ||
| + | - name: habilitar sitio web | ||
| + | ansible.builtin.file: | ||
| + | src: /etc/apache2/sites-available/{{ nombre_dominio }}.conf | ||
| + | dest: /etc/apache2/sites-enabled/{{ nombre_dominio }}.conf | ||
| + | state: link | ||
| + | notify: reload Apache | ||
| + | |||
| + | - name: habilitar sitio web https | ||
| + | ansible.builtin.file: | ||
| + | src: /etc/apache2/sites-available/{{ nombre_dominio }}_https.conf | ||
| + | dest: /etc/apache2/sites-enabled/{{ nombre_dominio }}_https.conf | ||
| + | state: link | ||
| + | notify: reload Apache | ||
| + | |||
| + | - name: deshabilitar sitio por defecto | ||
| + | ansible.builtin.file: | ||
| + | path: /etc/apache2/sites-enabled/000-default.conf | ||
| + | state: absent | ||
| + | notify: reload Apache | ||
| + | </pre> | ||
| + | |||
| + | Definimos os handler que encárganse de reiniciar os servizos cando haxa cambios na configuración: | ||
| + | <pre> | ||
| + | handlers: | ||
| + | - name: reiniciar Apache | ||
| + | ansible.builtin.service: | ||
| + | name: apache2 | ||
| + | state: restarted | ||
| + | |||
| + | - name: reload Apache | ||
| + | ansible.builtin.service: | ||
| + | name: apache2 | ||
| + | state: reloaded | ||
| + | |||
| + | - name: reiniciar fail2ban | ||
| + | ansible.builtin.service: | ||
| + | name: fail2ban | ||
| + | state: restarted | ||
| + | |||
| + | - name: reiniciar syslog | ||
| + | ansible.builtin.service: | ||
| + | name: rsyslog | ||
| + | state: restarted | ||
| + | </pre> | ||
| + | |||
| + | Lanzamos o playbook: | ||
| + | $ ansible-playbook server-apache.yml -K | ||
| + | <pre> | ||
| + | BECOME password: | ||
| + | |||
| + | PLAY [incus] ************************************************************************************************************************************************************************************** | ||
| + | |||
| + | TASK [Gathering Facts] ************************************************************************************************************************************************************************** | ||
| + | ok: [192.0.2.193] | ||
| + | ok: [192.0.2.191] | ||
| + | ok: [192.0.2.192] | ||
| + | |||
| + | TASK [instalar paquetes] ************************************************************************************************************************************************************************ | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | TASK [crear jail.local] ************************************************************************************************************************************************************************* | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | TASK [modificar parametro bantime en jail.local] ************************************************************************************************************************************************ | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | TASK [modificar parametro findtime en jail.local] *********************************************************************************************************************************************** | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | TASK [modificar parametro maxretry en jail.local] *********************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | TASK [anular reduccion mensajes rsyslog] ******************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | TASK [Arrancar Apache y fail2ban] *************************************************************************************************************************************************************** | ||
| + | ok: [192.0.2.191] => (item=apache2) | ||
| + | ok: [192.0.2.193] => (item=apache2) | ||
| + | ok: [192.0.2.192] => (item=apache2) | ||
| + | ok: [192.0.2.193] => (item=fail2ban) | ||
| + | ok: [192.0.2.191] => (item=fail2ban) | ||
| + | ok: [192.0.2.192] => (item=fail2ban) | ||
| + | |||
| + | TASK [habilitar módulo ssl] ********************************************************************************************************************************************************************* | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | |||
| + | TASK [añadir virtualhost para el dominio] ******************************************************************************************************************************************************* | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | TASK [añadir virtualhost https para el dominio] ************************************************************************************************************************************************* | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | TASK [copiar certificados sitio web] ************************************************************************************************************************************************************ | ||
| + | changed: [192.0.2.191] => (item=/home/manuel/devops/www.manuel2023.test.key) | ||
| + | changed: [192.0.2.192] => (item=/home/manuel/devops/www.manuel2023.test.key) | ||
| + | changed: [192.0.2.193] => (item=/home/manuel/devops/www.manuel2023.test.key) | ||
| + | changed: [192.0.2.191] => (item=/home/manuel/devops/www.manuel2023.test.crt) | ||
| + | changed: [192.0.2.192] => (item=/home/manuel/devops/www.manuel2023.test.crt) | ||
| + | changed: [192.0.2.193] => (item=/home/manuel/devops/www.manuel2023.test.crt) | ||
| + | |||
| + | TASK [copiar sitio web] ************************************************************************************************************************************************************************* | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | TASK [habilitar sitio web] ********************************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | TASK [habilitar sitio web https] **************************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | TASK [deshabilitar sitio por defecto] *********************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | RUNNING HANDLER [reiniciar Apache] ************************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | |||
| + | RUNNING HANDLER [reload Apache] ***************************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | |||
| + | RUNNING HANDLER [reiniciar fail2ban] ************************************************************************************************************************************************************ | ||
| + | changed: [192.0.2.191] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.192] | ||
| + | |||
| + | RUNNING HANDLER [reiniciar syslog] ************************************************************************************************************************************************************** | ||
| + | changed: [192.0.2.192] | ||
| + | changed: [192.0.2.193] | ||
| + | changed: [192.0.2.191] | ||
| + | |||
| + | PLAY RECAP ************************************************************************************************************************************************************************************** | ||
| + | 192.0.2.191 : ok=20 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 | ||
| + | 192.0.2.192 : ok=20 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 | ||
| + | 192.0.2.193 : ok=20 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 | ||
| + | </pre> | ||
| + | |||
| + | Uns comentarios sobre a saída: | ||
| + | * No caso de erro na execución dunha tarefa párase a execución do playbook. | ||
| + | * Lanzar repetidas veces o playbook non fará que cambie o estado final dos equipos. Este concepto é coñecido por 'idempotencia'. | ||
| + | |||
| + | O resultado é que nos tres servidores temos a configuración desexada (lembrar que para acceder usando www.manuel2023.test hai que configurar a resolución dns no equipo, por exemplo, a través do arquivo /etc/hosts): | ||
| + | |||
| + | Acceso por https ó servidor web | ||
| + | |||
| + | Fig. Acceso por http e https a www.manuel2023.com en server01 | ||
| + | |||
| + | $ ansible incus -m ansible.builtin.shell -a 'ss -ltnp' -b -K | ||
| + | <pre> | ||
| + | BECOME password: | ||
| + | 192.0.2.192 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=301,fd=13)) | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=986,fd=3)) | ||
| + | LISTEN 0 511 *:80 *:* users:(("apache2",pid=17251,fd=4),("apache2",pid=17250,fd=4),("apache2",pid=17249,fd=4),("apache2",pid=17248,fd=4),("apache2",pid=17247,fd=4),("apache2",pid=17211,fd=4)) | ||
| + | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=986,fd=4)) | ||
| + | LISTEN 0 511 *:443 *:* users:(("apache2",pid=17251,fd=6),("apache2",pid=17250,fd=6),("apache2",pid=17249,fd=6),("apache2",pid=17248,fd=6),("apache2",pid=17247,fd=6),("apache2",pid=17211,fd=6)) | ||
| + | 192.0.2.191 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=987,fd=3)) | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=301,fd=13)) | ||
| + | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=987,fd=4)) | ||
| + | LISTEN 0 511 *:443 *:* users:(("apache2",pid=17073,fd=6),("apache2",pid=16965,fd=6),("apache2",pid=16964,fd=6),("apache2",pid=16963,fd=6),("apache2",pid=16962,fd=6),("apache2",pid=16961,fd=6),("apache2",pid=16925,fd=6)) | ||
| + | LISTEN 0 511 *:80 *:* users:(("apache2",pid=17073,fd=4),("apache2",pid=16965,fd=4),("apache2",pid=16964,fd=4),("apache2",pid=16963,fd=4),("apache2",pid=16962,fd=4),("apache2",pid=16961,fd=4),("apache2",pid=16925,fd=4)) | ||
| + | 192.0.2.193 | CHANGED | rc=0 >> | ||
| + | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process | ||
| + | LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=301,fd=13)) | ||
| + | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=988,fd=3)) | ||
| + | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=988,fd=4)) | ||
| + | LISTEN 0 511 *:443 *:* users:(("apache2",pid=17244,fd=6),("apache2",pid=17243,fd=6),("apache2",pid=17242,fd=6),("apache2",pid=17241,fd=6),("apache2",pid=17240,fd=6),("apache2",pid=17204,fd=6)) | ||
| + | LISTEN 0 511 *:80 *:* users:(("apache2",pid=17244,fd=4),("apache2",pid=17243,fd=4),("apache2",pid=17242,fd=4),("apache2",pid=17241,fd=4),("apache2",pid=17240,fd=4),("apache2",pid=17204,fd=4)) | ||
| + | </pre> | ||
| + | |||
| + | $ ansible incus -m ansible.builtin.shell -a 'apache2ctl -S' -b -K | ||
| + | <pre> | ||
| + | BECOME password: | ||
| + | 192.0.2.191 | CHANGED | rc=0 >> | ||
| + | VirtualHost configuration: | ||
| + | *:80 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test.conf:1) | ||
| + | *:443 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test_https.conf:1) | ||
| + | ServerRoot: "/etc/apache2" | ||
| + | Main DocumentRoot: "/var/www/html" | ||
| + | Main ErrorLog: "/var/log/apache2/error.log" | ||
| + | Mutex ssl-stapling: using_defaults | ||
| + | Mutex ssl-cache: using_defaults | ||
| + | Mutex default: dir="/var/run/apache2/" mechanism=default | ||
| + | Mutex mpm-accept: using_defaults | ||
| + | Mutex watchdog-callback: using_defaults | ||
| + | Mutex ssl-stapling-refresh: using_defaults | ||
| + | PidFile: "/var/run/apache2/apache2.pid" | ||
| + | Define: DUMP_VHOSTS | ||
| + | Define: DUMP_RUN_CFG | ||
| + | User: name="www-data" id=33 | ||
| + | Group: name="www-data" id=33 | ||
| + | 192.0.2.193 | CHANGED | rc=0 >> | ||
| + | VirtualHost configuration: | ||
| + | *:80 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test.conf:1) | ||
| + | *:443 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test_https.conf:1) | ||
| + | ServerRoot: "/etc/apache2" | ||
| + | Main DocumentRoot: "/var/www/html" | ||
| + | Main ErrorLog: "/var/log/apache2/error.log" | ||
| + | Mutex watchdog-callback: using_defaults | ||
| + | Mutex ssl-stapling-refresh: using_defaults | ||
| + | Mutex ssl-stapling: using_defaults | ||
| + | Mutex ssl-cache: using_defaults | ||
| + | Mutex default: dir="/var/run/apache2/" mechanism=default | ||
| + | Mutex mpm-accept: using_defaults | ||
| + | PidFile: "/var/run/apache2/apache2.pid" | ||
| + | Define: DUMP_VHOSTS | ||
| + | Define: DUMP_RUN_CFG | ||
| + | User: name="www-data" id=33 | ||
| + | Group: name="www-data" id=33 | ||
| + | 192.0.2.192 | CHANGED | rc=0 >> | ||
| + | VirtualHost configuration: | ||
| + | *:80 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test.conf:1) | ||
| + | *:443 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test_https.conf:1) | ||
| + | ServerRoot: "/etc/apache2" | ||
| + | Main DocumentRoot: "/var/www/html" | ||
| + | Main ErrorLog: "/var/log/apache2/error.log" | ||
| + | Mutex ssl-stapling-refresh: using_defaults | ||
| + | Mutex ssl-stapling: using_defaults | ||
| + | Mutex ssl-cache: using_defaults | ||
| + | Mutex default: dir="/var/run/apache2/" mechanism=default | ||
| + | Mutex mpm-accept: using_defaults | ||
| + | Mutex watchdog-callback: using_defaults | ||
| + | PidFile: "/var/run/apache2/apache2.pid" | ||
| + | Define: DUMP_VHOSTS | ||
| + | Define: DUMP_RUN_CFG | ||
| + | User: name="www-data" id=33 | ||
| + | Group: name="www-data" id=33 | ||
| + | </pre> | ||
= Instalación = | = Instalación = | ||
| Línea 227: | Línea 1174: | ||
</pre> | </pre> | ||
| − | = Primeiras probas con ansible = | + | == Primeiras probas con ansible == |
Empregamos o módulo ping de ansible para comprobar a conexión cos nodos clientes (Importante: asegúrate que estén arrancados!!) | Empregamos o módulo ping de ansible para comprobar a conexión cos nodos clientes (Importante: asegúrate que estén arrancados!!) | ||
| Línea 234: | Línea 1181: | ||
: ansible aula1 -m ping | : ansible aula1 -m ping | ||
| − | Inicialmente, teremos erro: Ansible emprega ssh para conectarse co cliente, como é a | + | Inicialmente, teremos erro: Ansible emprega ssh para conectarse co cliente, como é a primeira vez que se conecta con ese cliente pídenos confirmación |
<pre> | <pre> | ||
| Línea 272: | Línea 1219: | ||
Instalamos sshpass: | Instalamos sshpass: | ||
| − | |||
root@servidorAnsible:/etc/ansible# apt install sshpass | root@servidorAnsible:/etc/ansible# apt install sshpass | ||
| − | |||
Ahora sí devolverá en cor verde (os erros estaban amosándose en vermello) indicando éxito. O equipo 10.0.2.10 respondeu o móudlo ping correctamente. A resposta é un JSON que pode conter moita información: | Ahora sí devolverá en cor verde (os erros estaban amosándose en vermello) indicando éxito. O equipo 10.0.2.10 respondeu o móudlo ping correctamente. A resposta é un JSON que pode conter moita información: | ||
Revisión actual del 20:23 4 mar 2026
Sumario
Introdución
Ansible:
- é unha plataforma de software libre para configurar e administrar equipos, permitindo a xestión da configuración e a orquestación de infraestruturas.
- é un proxecto de código aberto implementado en Python e ten unha arquitectura con módulos que poden manexar prácticamente calquera sistema operativo, contorna de nube e ferramenta ou marco de administración do sistema.
- é amplamente usada para xestionar a configuración de servidores, para tarefas de aprovisionamento de instancias cloud, operacións dev-ops, ...
- ten unha filosofía que pode resumirse en que o estado de configuración final que queres que teña un equipo queda definido nun arquivo de texto, chamado playbook
Máis datos:
- Lanzamento inicial no 2012 (escrito orixialmente por Michael DeHaan, o creador da aplicación de aprovisionamento Cobbler) e posteriormente adquirido por Red Hat.
- Combina instalación multi-nodo (permite despregar configuracións de servidores e servicios por lotes), execucións de taefas ad hoc e administración de configuracións.
- Arquitectura agentless. Non require un axente nos servidores cliente polo que optimiza o rendemento e evita abrir portos especiais, con utilizar só a conexión por SSH. O traballo envíaase aos hosts cando se executa Ansible. Os módulos son os programas que realizan o traballo real das tarefas dun play.
- Sintaxe moi sinxela con baixa curva de aprendizaxe e sen requirir coñecementos de programación
- Con máils de 1000 módulos disponibles. Asi para activos diferentes podemos falar a mesma lingua do dispositivo administrado; e tamén poderemos desenvolver módulos en python.
- Con adoptación masiva por ser fácil de usar para os administradores de sistemas
- Compatible con ferramentas DevOps coma Vagrant e Jenkins.
O deseño de Ansible contempla:
- Mínimo por natureza
- Os sistemas de administración non deben impoñer dependencias adicionais.
- Consistente
- Seguro
- Ansible non instala axentes vulnerables nos nodos. Manexa as máquinas remotamente a través de SSH, que é o seu único requisito xunto con Python
- Alta confiabilidade
- O modelo de idempotencia é aplicado para as instalacións e configuracións, para previr efectos secundarios na execución repetitiva de guións (scripts)
- Suave curva de aprendizaxe
- Os playbooks ou libretos usan unha linguaxe descriptiva simple baseada en YAML.
Resumindo, Ansible é unha utilidade de orquestación e administración de configuración de código aberto que pode automatizar e estandarizar a configuración de hosts remotos e máquinas virtuáis. A súa funcionalidade de orquestación permite a Ansible coordinar o lanzamento e o apagado seguro de aplicacións de varios niveles.
Así no canto de escribir scripts personalizados e individualizados, os administradores do sistema crean un play ou unha xogada de alto nivel en Ansible.
Ese play realiza unha serie de tarefas no host ou grupo de hosts especificados no play.
Un ficheiro que contén un ou máis plays chámase Playbook.
Qué non pode facer ansible?
- Non pode auditar os cambios realizados localmente por outros usuarios no sistema
- Pode agregar paquetes a unha instalación, pero NON realizar a instalación mínima inicial do sistema
- Pode modificar a configuración, pero NON a monitorea
- Non realiza un seguemento dos cambios realizados nos ficheiros do sistema, e de qué usuario ou proceso realizou os cambios
Arquitectura
Existen dous tipos de máquinas na arquitectura de Ansible:
- o nodo de control
- os hosts administrados
O software ansible está instalado no nodo de control e todos os seus compoñentes se manteñen nel.
Os hosts administrados enumeranse nun inventario de host ,un ficheirode texto no nodo de control que inclue unha lista de nomes de host administrados FQDN (fully qualified domain name) ou enderezos IP.
Ansible utiliza SSH coma protocolo de comuncación cos hosts administados. Os módul referenciados nos playbooks copianse nos hosts administrados. Despois se executan, en orde, cos argumentos especificados no playbook. Os usuarios de Ansible poden escribir os seus propios módulos personalizados se é preciso pero os módulo s principais que veñen con Ansible poden realizar a maioría das tarefas de administración do sistema.
Primeiros pasos
Traballar con Ansible hai que comprender os seguintes termos:
- Host Inventory
- é unha descrición dos nodos (equipos a administrar) ós que poderemos acceder usando Ansible. O inventory máis básico contén ós nodos agrupados por grupos (ubicacións xeográficas, servizos ou calquera outro criterio que consideremos) e as direccións IP ou nomes.
Un exemplo de inventory podería ser:
$ cat /etc/ansible/hosts [infor1] 192.168.1.193 192.168.1.194 192.168.1.195 [profesores] 192.168.1.201 192.168.2.201 192.168.3.201
- Playbooks
- trátase de arquivos de texto onde se describen configuracións ou tarefas de despregue. Dentro dun playbook haberá 'xogadas' (plays) onde se indican unha serie de tarefas a executar; por exemplo, actualizar a lista de paquetes, instalar o servidor web apache, activar o módulo ssl, copiar os arquivos de configuración dos sitios web a aloxar, crear as carpetas dos DocumentRoot dos sitios e copiar os arquivos que forma os sitios, activar os sitios web, reiniciar o servidor Apache, ... Os playbooks poden verse como arquivos que describen a configuración desexada para un equipo ou conxunto de equipos.
No seguinte exemplo podemos ver un playbook que fixera no seu día para por en marcha e configurar os equipos Linux Lubuntu dunha clase de informática de ESO/Bach do centro. Podese ver como unha foto do estado que quería acadar nos equipos e que se resume en que:
- Copiamos a todos os equipos da clase un arquivo sources.list para que todos teñan e usen os mesmos repositorios.
- Copiamos a todos os equipos da clase o arquivo 01apt-cacherng-proxy para que usen o apt-cacher-ng e se aceleren os procesos de instalación/actualización de paquetes.
- Copiamos en /etc/skel unha plantilla para que os usuarios do equipo partan da mesma configuración de escritorio (iconas, menús, ligazóns de favoritos, ...).
- Creamos uns usuarios e configuramos o contrasinal de root.
- Configuramos a sincronización de hora para que vaian a un servidor de hora interno no IES.
- Borramos algúns programas que viñan coa instalación básica de Lubuntu (Abiword e gnumeric).
- Engadimos algúns repositorios ppa para ter as últimas versións de Inkscape e LibreOffice.
- Actualizamos os equipos e instalamos unha colección de paquetes indicada no arquivo paquetes_ESO1.yml (arandr, libreoffice, libreoffice-l10n-es, vlc, audacity, inkscape, ...).
- Deshabilitamos a impresión nos equipos.
---
- hosts: infor1
become: yes
remote_user: magasix
become_method: sudo
gather_facts: false
vars_files:
- /media/DATOS/Tutoriales/ansible/paquetes_ESO1.yml
tasks:
- name: copiar fichero de repositorios
copy: src=/media/DATOS/Tutoriales/ansible/sources.list_ESO1.txt dest=/etc/apt/sources.list
- name: copiar fichero de apt-cacherng-proxy
copy: src=/media/DATOS/Tutoriales/ansible/01apt-cacherng-proxy_ESO1.txt dest=/etc/apt/apt.conf.d/01apt-cacherng-proxy
- name: crear grupo alumnos
group: name=alumnos state=present
- name: copiar skel
copy: src=/media/DATOS/Tutoriales/ansible/skel/ dest=/etc/skel/
- name: crear usuario alumno
user: name=alumno comment="Alumno IES" shell=/bin/bash groups=alumnos state=present
- name: password en blanco
shell: passwd -d alumno
- name: crear usuario alumno TICs abc123.
user: name=alumnotics comment="Alumno TICs" shell=/bin/bash groups=alumnos password=ylMqA85PRieLg state=present
- name: password a root
user: name=root password=rDQVP5utaEC9E
- name: desinstalar ntp
apt: name=ntp state=absent purge=yes
- name: configurar ntpdate
copy: src=/media/DATOS/Tutoriales/ansible/ntpdate.conf_ESO1.txt dest=/etc/default/ntpdate
- name: fijar lubuntu-desktop
shell: apt-mark manual lubuntu-desktop
- name: borrar abiword
apt: name=abiword state=absent purge=yes
- name: borrar gnumeric
apt: name=gnumeric state=absent purge=yes
- name: repositorio inkscape
apt_repository: repo='ppa:inkscape.dev/stable' update_cache=no
- name: repositorio libreoffice 5
apt_repository: repo='ppa:libreoffice/ppa' update_cache=no
- name: actualizar equipo
apt: upgrade=dist update_cache=yes
- name: instalacion de paquetes
apt: pkg={{ item }} state=installed
with_items: '{{system_packages}}'
- name: deshabilitar impresion
service: name=cups state=stopped enabled=no
No exemplo podemos ver que aparecen palabras como user, shell, apt,_repository, apt, service, ..., e que correspóndense con nomes de módulos de ansible. Os módulos permiten efectuar tarefas de configuración nos equipos a administrar; por exemplo, o módulo apt permite xestionar paquetes .deb en equipos Debian/Ubuntu.
Pódese ver na sección de documentación todos os módulos dos que dispón Ansible:
Módulos Packaging
Fig. Módulos para a xestión de paquetes en Ansible
Para traballar con Ansible únicamente precisamos o seguinte:
- Un nodo de xestión con Ansible instalado (ten que ser unha máquina Linux).
- Nodo/s a xestionar con ssh instalado e configurado para permitir as conexións dende o nodo xestor. A diferenza doutro software semellante, como Puppet, Chef ou Salt, non é preciso instalar ningún software axente nos nodos administrados. Os nodos a administrar poden ser Linux ou Windows.
Resumindo o funcionamento nunha imaxe: as tarefas/configuracións recollidas no Playbook realizaranse no equipo indicado no Host Inventory, usando unha canle ssh para comunicarse o nodo xestor co nodo administrado.
Administración con ansible
Fig. Administración con Ansible. Fonte: 19 Minutes with Ansible
Se en vez de lanzar o playbook contra un equipo lánzase contra un grupo de equipos, teremos un grupo de equipos que comparten a mesma configuración. No exemplo anterior, lanzar o playbook contra os 20 Lubuntus recén instalados na aula, implica que ó cabo dun rato teremos 20 equipos configurados exactamente igual. Traballar con playbooks que recollan os cambios de configuración/tarefas a realizar facilita o mantemento dos sistemas, permite incorporar novos equipos que teñan exactamente a mesma configuración que o resto, ... Case podemos pensar nos playbooks como a nosa infraestrutura documentada.
Administración con ansible
Fig. Lanzando un playbook contra un grupo de nodos. Fonte: 19 Minutes with Ansible
A modo de exemplo amoso a saída resultante de lanzar o playbook anterior contra 3 equipos e podemos observar como se van realizando as diferentes tarefas (tasks), levando a todos os equipos ó mesmo estado de configuración:
$ ansible-playbook lubuntu_ies_alumnos_ntpdate_ESO1_casa.yml -K
SUDO password: PLAY *************************************************************************** TASK [copiar fichero de repositorios] ****************************************** changed: [192.168.1.195] changed: [192.168.1.193] changed: [192.168.1.194] TASK [copiar fichero de apt-cacherng-proxy] ************************************ changed: [192.168.1.193] changed: [192.168.1.195] changed: [192.168.1.194] TASK [crear grupo alumnos] ***************************************************** changed: [192.168.1.193] changed: [192.168.1.194] changed: [192.168.1.195] TASK [copiar skel] ************************************************************* changed: [192.168.1.195] changed: [192.168.1.193] changed: [192.168.1.194] TASK [crear usuario alumno] **************************************************** changed: [192.168.1.195] changed: [192.168.1.194] changed: [192.168.1.193] TASK [password en blanco] ****************************************************** changed: [192.168.1.194] changed: [192.168.1.195] changed: [192.168.1.193] TASK [crear usuario alumno TICs abc123.] *************************************** changed: [192.168.1.193] changed: [192.168.1.194] changed: [192.168.1.195] TASK [password a root] ********************************************************* changed: [192.168.1.194] changed: [192.168.1.193] changed: [192.168.1.195] TASK [desinstalar ntp] ********************************************************* changed: [192.168.1.195] changed: [192.168.1.194] changed: [192.168.1.193] TASK [configurar ntpdate] ****************************************************** changed: [192.168.1.194] changed: [192.168.1.193] changed: [192.168.1.195] TASK [fijar lubuntu-desktop] *************************************************** changed: [192.168.1.194] changed: [192.168.1.195] changed: [192.168.1.193] TASK [borrar abiword] ********************************************************** changed: [192.168.1.194] changed: [192.168.1.195] changed: [192.168.1.193] TASK [borrar gnumeric] ********************************************************* changed: [192.168.1.195] changed: [192.168.1.194] changed: [192.168.1.193] TASK [repositorio inkscape] **************************************************** changed: [192.168.1.195] changed: [192.168.1.194] changed: [192.168.1.193] TASK [repositorio libreoffice 5] *********************************************** changed: [192.168.1.193] changed: [192.168.1.194] changed: [192.168.1.195] TASK [actualizar equipo] ******************************************************* changed: [192.168.1.194] changed: [192.168.1.193] changed: [192.168.1.195] TASK [instalacion de paquetes] ************************************************* ok: [192.168.1.194] => (item=[u'build-essential', u'arandr', u'libreoffice', u'libreoffice-l10n-es', u'lubuntu-restricted-addons', u'lubuntu-restricted-extras', u'ubuntu-restricted-extras', u'ubuntu-restricted-addons', u'icedtea-plugin', u'vlc', u'audacity', u'inkscape', u'openshot', u'sweethome3d', u'sweethome3d-furniture', u'sweethome3d-furniture-nonfree', u'gimp', u'gimp-data', u'gimp-data-extras', u'gimp-dcraw', u'gimp-gmic', u'gimp-help-es', u'gimp-plugin-registry', u'scribus', u'scribus-template', u'scribus-doc']) ok: [192.168.1.193] => (item=[u'build-essential', u'arandr', u'libreoffice', u'libreoffice-l10n-es', u'lubuntu-restricted-addons', u'lubuntu-restricted-extras', u'ubuntu-restricted-extras', u'ubuntu-restricted-addons', u'icedtea-plugin', u'vlc', u'audacity', u'inkscape', u'openshot', u'sweethome3d', u'sweethome3d-furniture', u'sweethome3d-furniture-nonfree', u'gimp', u'gimp-data', u'gimp-data-extras', u'gimp-dcraw', u'gimp-gmic', u'gimp-help-es', u'gimp-plugin-registry', u'scribus', u'scribus-template', u'scribus-doc']) ok: [192.168.1.195] => (item=[u'build-essential', u'arandr', u'libreoffice', u'libreoffice-l10n-es', u'lubuntu-restricted-addons', u'lubuntu-restricted-extras', u'ubuntu-restricted-extras', u'ubuntu-restricted-addons', u'icedtea-plugin', u'vlc', u'audacity', u'inkscape', u'openshot', u'sweethome3d', u'sweethome3d-furniture', u'sweethome3d-furniture-nonfree', u'gimp', u'gimp-data', u'gimp-data-extras', u'gimp-dcraw', u'gimp-gmic', u'gimp-help-es', u'gimp-plugin-registry', u'scribus', u'scribus-template', u'scribus-doc']) TASK [deshabilitar impresion] ************************************************** changed: [192.168.1.193] changed: [192.168.1.194] changed: [192.168.1.195] PLAY RECAP ********************************************************************* 192.168.1.193 : ok=18 changed=18 unreachable=0 failed=0 192.168.1.194 : ok=18 changed=18 unreachable=0 failed=0 192.168.1.195 : ok=18 changed=18 unreachable=0 failed=0
Modo ad-hoc
Aínda que traballar con playbooks é o recomendado, Ansible permite traballar en modo ad-hoc; é dicir, executar tarefas sen necesidade de crear e gardar un playbook. Por exemplo, comprobar o estado dos equipos, executar comandos do sistema, copias arquivos en calquera sentido, ...
A modo de exemplo:
$ ansible infor1 -m ping -u magasix
192.168.1.194 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.195 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.193 | SUCCESS => {
"changed": false,
"ping": "pong"
}
$ ansible infor1 -m shell -a "shutdown -h now" -u magasix --sudo -K
SUDO password: 192.168.1.194 | SUCCESS | rc=0 >> 192.168.1.195 | SUCCESS | rc=0 >> 192.168.1.193 | SUCCESS | rc=0 >>
Alternativas
| Puppet | Chef | Salt | Ansible | |
|---|---|---|---|---|
| Soporte | Puppet Labs | Opscode | SaltStack | Ansible Works |
| Control da interface | Manifest (DSL) | Recipes (DSL:Ruby) | SLS (SoLt Sate/YAML) | Playbook (YAML,JSON) |
| Axente | Master/Axente (Standalone) | Servidor/Cliente Chef-solo (Standalone) |
Master/Axente (minions) Standalone (masterless) |
Standalone (masterless) |
| Tecnoloxía core | Ruby | Ruby | Python | Python |
| Comunicación | http, ssh / SSL | STOMP, rest/SSL | ZeroMQ | SSH / JSON |
| Execución remota | Mcollective, complexa | Coitelo, complexa | Integrada por defecto, sinxela | Integrada por defecto, sinxela |
| Apoiado/usado por | Google, eBay, Twitter | Facebook, Ancestry, Splunk | Linkedin, HP Cloud | Rackspace, Evernote |
| Data de lanzamento | 2005 | 2009 | 2011 | 2012 |
Escenario con Ansible
Configuración do escenario
O obxectivo deste Escenario 8D é facer unha primeira aproximación a Ansible e ver as posibilidades que proporciona ós administradores de sistemas como ferramenta avanzada de configuración e automatización. O noso obxectivo será montar un sistema con tres servidores web idénticos que imos supoñer que forman parte dun backend e teñen as seguintes características:
- Hai que instalar e configurar fail2ban para que no arquivo de configuración jail.local o tempo de búsqueda sexa de 10 minutos, o de baneo 20 minutos e o número máximo de intentos sexa 3.
- Hai que configurar o syslog para que a reducción da repetición de mensaxes se desactive ( $RepeatedMsgReduction off )
- Os servidores corren Apache e php 8.2
- Responden a solicitudes por http e https (con certificado propio autofirmado) dirixidas a www.manuel2023.test
- Teñen unha páxina web index.php co seguinte contido:
<?php
echo "
<html>
<head>
<title>Sitio web en ${_SERVER["SERVER_ADDR"]}</title>
</head>
<body>
<img src=”imaxes/logo.png” alt=”logotipo”>
<h1>Sitio Web www.manuel2023.test</h1>
Estás en ${_SERVER["SERVER_ADDR"]}
</body>
</html>";
?>
- Non se permiten opcións como listado de directorios, seguir enlaces simbólicos, ...
- Non se permite personalizar as opcións usando arquivos htaccess.
- O sitio web ten os seus propios ficheros de log (o mesmo tanto para o acceso por http como https).
Instalación e comandos ad-hoc
Instalación de Ansible
Instalaremos Ansible nun equipo Linux que exercerá de nodo administrador e os pasos a seguir son:
$ sudo apt update $ sudo apt install software-properties-common $ sudo apt-add-repository ppa:ansible/ansible $ sudo apt install ansible
Creación do inventory
Unha vez rematada a instalación temos que crear un inventory cos equipos que queremos administrar.
NOTA. No caso de non estar creado o directorio /etc/ansible, hai que proceder a crealo mediante: mkdir /etc/ansible
$ sudo nano /etc/ansible/hosts
# grupo contedores [incus] 192.0.2.191 192.0.2.192 192.0.2.193
No inventory pódese engadir máis información asociada ós nodos a administrar como o usuario co que Ansible iniciará sesión, que no noso caso pode ser o usuario ubuntu ou o usuario magasix creada no aprovisionamento dos contedores:
$ sudo nano /etc/ansible/hosts
# grupo contedores [incus] 192.0.2.191 192.0.2.192 192.0.2.193 [incus:vars] ansible_user=ubuntu
Autenticación mediante identidades dixitais
Ansible usará ssh para entrar nos equipos a xestionar e unha práctica recomendada é autenticarse mediante identidades dixitais como se explicou PENDIENTE polo que procedemos a autorizar unha clave dixital e a indicalo no inventory. Usamos o usuario ubuntu con contrasinal abc123.
$ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@192.0.2.191 $ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@192.0.2.192 $ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@192.0.2.193
Despois de autorizar a clave, verificar que é posible conectarse.
$ sudo nano /etc/ansible/hosts
# grupo contedores [incus] 192.0.2.191 192.0.2.192 192.0.2.193 [incus:vars] ansible_ssh_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa ansible_python_interpreter=/usr/bin/python3
Vemos que no inventory é posible engadir variables asociadas a equipos ou grupos de equipos como ansible_ssh_private_key_file e ansible_python_interpreter (permite indicar que intérprete de python hai nos hosts sen necesidade que o detecte ansible).
Verificación con ping
Agora podemos verificar que Ansible é capaz de conectarse cos servers executando un 'ping':
$ ansible incus -m ansible.builtin.ping
192.0.2.191 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.0.2.193 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.0.2.192 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Comandos AD-HOC
Os comandos ad-hoc están para cando se quere facer algo pero non queremos gardarlo para outras ocasións ou non se considera necesario escribir un playbook. Aínda que para aproveitar todo o potencial de Ansible están os playbooks, os comandos ad-hoc permiten facer cosas de forma rápida. Por exemplo, facemos un ss -ltnp:
$ ansible incus -m ansible.builtin.shell -a 'ss -ltnp'
192.0.2.193 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* 192.0.2.192 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* 192.0.2.191 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:*
Hai que sinalar qué ansible.builtin.shell é o nome completo do módulo de Ansible e shell é a forma abreviada.
$ ansible incus -m shell -a 'ss -ltnp'
192.0.2.191 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* 192.0.2.193 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* 192.0.2.192 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:*
Aínda que en moitos titoriais de Ansible aparece a forma abreviada, os desenvolvedores de Ansible recomendan usar o nome completo en vez da abreviada para evitar posibles conflictos.
No caso de querer executar o comando nos hosts como administrador pódese empregar as opcións -b e -K:
- -b (become): indica que se quere escalar privilexios nos hosts
- -K: pregunta polo contrasinal para elevar os privilexios
$ ansible incus -m ansible.builtin.shell -a 'ss -ltnp' -b -K
BECOME password:
192.0.2.192 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=165,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=220,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=220,fd=4))
192.0.2.191 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=166,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=229,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=229,fd=4))
192.0.2.193 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=166,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=211,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=211,fd=4))
O usuario ubuntu está autorizado para facer sudo sen necesidade de introducir o contrasinal, polo que no noso escenario o comando anterior podería executarse sen -K. Sinalar tamén que é posible gardar contrasinais cifradas empregando o concepto de vault.
Posibles operacións
Podemos copiar arquivos de local a remoto e viceversa, xestionar usuarios, servizos, paquetes, ...
Por exemplo, para copìar un arquivo local chamado backup.yml en todos os servidores podería executar:
$ ansible incus -m ansible.builtin.copy -a "src=config_backup.yml dest=/home/ubuntu/config.yml"
192.0.2.192 | CHANGED => {
"changed": true,
"checksum": "39244f4abbbb552d9d3e00eb27d05cfd6b8bfa44",
"dest": "/home/ubuntu/config.yml",
"gid": 1001,
"group": "ubuntu",
"md5sum": "1f5b15fb9e83f47d213637efe71f3d20",
"mode": "0664",
"owner": "ubuntu",
"size": 424,
"src": "/home/ubuntu/.ansible/tmp/ansible-tmp-1685284269.5834956-25446-44703324742452/source",
"state": "file",
"uid": 1001
}
192.0.2.191 | CHANGED => {
"changed": true,
"checksum": "39244f4abbbb552d9d3e00eb27d05cfd6b8bfa44",
"dest": "/home/ubuntu/config.yml",
"gid": 1001,
"group": "ubuntu",
"md5sum": "1f5b15fb9e83f47d213637efe71f3d20",
"mode": "0664",
"owner": "ubuntu",
"size": 424,
"src": "/home/ubuntu/.ansible/tmp/ansible-tmp-1685284269.628682-25444-43771047461490/source",
"state": "file",
"uid": 1001
}
192.0.2.193 | CHANGED => {
"changed": true,
"checksum": "39244f4abbbb552d9d3e00eb27d05cfd6b8bfa44",
"dest": "/home/ubuntu/config.yml",
"gid": 1001,
"group": "ubuntu",
"md5sum": "1f5b15fb9e83f47d213637efe71f3d20",
"mode": "0664",
"owner": "ubuntu",
"size": 424,
"src": "/home/ubuntu/.ansible/tmp/ansible-tmp-1685284269.6718416-25448-47330558216673/source",
"state": "file",
"uid": 1001
}
$ ansible incus -m ansible.builtin.shell -a 'ls -lhF'
192.0.2.193 | CHANGED | rc=0 >> total 2,5K -rw-rw-r-- 1 ubuntu ubuntu 2,1K mar 1 17:10 config.yml 192.0.2.192 | CHANGED | rc=0 >> total 2,5K -rw-rw-r-- 1 ubuntu ubuntu 2,1K mar 1 17:10 config.yml 192.0.2.191 | CHANGED | rc=0 >> total 2,5K -rw-rw-r-- 1 ubuntu ubuntu 2,1K mar 1 17:10 config.yml
Na páxina Introduction To Ad-Hoc Commands podemos ver máis exemplos desta forma de usar Ansible.
Playbooks
Despois de revisar por riba o uso de ansible chegamos o punto forte que son os playbooks. Como primeira aproximación executaremos o playbook actualizar.yml que permitirá actualizar os equipo servidores e como pode verse é moi sinxelo de entender:
- Aplícase os equipo incus definidos no inventory.
- Execútase como administrador (become: yes)
- Actualiza a lista de paquetes e fai unha actualización do sistema.
---
- hosts: incus
become: yes
tasks:
- name: actualizar lista de paquetes y el sistema
apt:
update_cache: yes
cache_valid_time: 3600
- name: actualizar sistema
apt:
upgrade: dist
Para lanzalo imos a carpeta de devops e:
$ ansible-playbook actualizar.yml -K
SUDO password: PLAY [incus] ************************************************************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************************************************* ok: [192.0.2.191] ok: [192.0.2.192] ok: [192.0.2.193] TASK [actualizar lista de paquetes y el sistema] *********************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.193] changed: [192.0.2.191] TASK [actualizar sistema] ********************************************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.193] changed: [192.0.2.191] PLAY RECAP ************************************************************************************************************************************************************************************* 192.0.2.191 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.0.2.192 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.0.2.193 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Todas as actuacións a realizar para levar ós servidores ó estado de configuración indicado no enunciado sabemos facelas a man como fixemos ó longo de diversos escenarios do curso; sen embargo, agora imos a recollelas nun playbook que permitirá automatizar a súa execución. Non é obxectivo deste apartado explicar exhaustivamente como facelo; xa que Ansible daría para un curso enteiro, pero si revisar o playbook server-apache.yml vendo que é moi sinxelo de entender e executalo para ver a súa potencialidade.
Definimos os equipos ós que se vai aplicar o playbook que executarase como administrador e usando as variables recollidas no arquivo vars.yml
---
- hosts: incus
become: yes
vars_files:
- vars.yml
Actualizamos a listaxe de paquetes e despois instalamos os seguintes:
- name: instalar paquetes
ansible.builtin.apt:
name:
- curl
- unzip
- fail2ban
- apache2
- php
- php-cli
- php-common
- php-curl
- php-gd
- libapache2-mod-php
state: latest
update_cache: yes
cache_valid_time: 3600
Creamos o arquivo jail.local a partir do jail.conf e procedemos a reemprazar os valores por defecto dos parámetros de configuración polos pedidos:
- name: crear jail.local
ansible.builtin.copy:
src: /etc/fail2ban/jail.conf
dest: /etc/fail2ban/jail.local
owner: root
group: root
mode: 0644
remote_src: True
- name: modificar parametro bantime en jail.local
ansible.builtin.lineinfile:
path: /etc/fail2ban/jail.local
regexp: '^bantime = 10m'
line: 'bantime = 1200'
state: present
notify: reiniciar fail2ban
- name: modificar parametro findtime en jail.local
ansible.builtin.lineinfile:
path: /etc/fail2ban/jail.local
regexp: '^findtime = 10m'
line: 'findtime = 300'
state: present
notify: reiniciar fail2ban
- name: modificar parametro maxretry en jail.local
ansible.builtin.replace:
path: /etc/fail2ban/jail.local
regexp: '^maxretry = 5'
replace: 'maxretry = 3'
notify: reiniciar fail2ban
Anulamos a reducción de mensaxe no rsyslog:
- name: anular reduccion mensajes rsyslog
ansible.builtin.lineinfile:
path: /etc/rsyslog.conf
regexp: '^\$RepeatedMsgReduction on'
line: '$RepeatedMsgReduction off'
state: present
backrefs: yes
notify: reiniciar syslog
Asegurámonos que Apache e fail2ban estén funcionando:
- name: Arrancar Apache y fail2ban
ansible.builtin.service: name={{ item }} state=started enabled=yes
with_items:
- apache2
- fail2ban
Habilitamos o módulo ssl para poder configurar o https:
- name: habilitar módulo ssl
community.general.apache2_module:
state: present
name: ssl
notify: reiniciar Apache
Engadimos o virtualhost http e https para o dominio:
- name: añadir virtualhost para el dominio
ansible.builtin.template:
src: templates/sitio_web.conf.j2
dest: /etc/apache2/sites-available/{{ nombre_dominio }}.conf
owner: root
group: root
mode: 0644
- name: añadir virtualhost https para el dominio
ansible.builtin.template:
src: templates/sitio_web_https.conf.j2
dest: /etc/apache2/sites-available/{{ nombre_dominio }}_https.conf
owner: root
group: root
mode: 0644
Copiamos os certificados e as páxinas do sitio web:
- name: copiar certificados sitio web
ansible.builtin.copy:
src: '{{ item }}'
dest: /etc/apache2/certificados/
owner: root
group: root
mode: 0644
with_fileglob:
- '{{ nombre_dominio }}.*'
- name: copiar sitio web
ansible.builtin.copy:
src: web/
dest: '{{ documentroot }}'
owner: root
group: root
mode: 0644
Habilitamos os sitios web http/https e deshabilitamos o sitio por defecto:
- name: habilitar sitio web
ansible.builtin.file:
src: /etc/apache2/sites-available/{{ nombre_dominio }}.conf
dest: /etc/apache2/sites-enabled/{{ nombre_dominio }}.conf
state: link
notify: reload Apache
- name: habilitar sitio web https
ansible.builtin.file:
src: /etc/apache2/sites-available/{{ nombre_dominio }}_https.conf
dest: /etc/apache2/sites-enabled/{{ nombre_dominio }}_https.conf
state: link
notify: reload Apache
- name: deshabilitar sitio por defecto
ansible.builtin.file:
path: /etc/apache2/sites-enabled/000-default.conf
state: absent
notify: reload Apache
Definimos os handler que encárganse de reiniciar os servizos cando haxa cambios na configuración:
handlers:
- name: reiniciar Apache
ansible.builtin.service:
name: apache2
state: restarted
- name: reload Apache
ansible.builtin.service:
name: apache2
state: reloaded
- name: reiniciar fail2ban
ansible.builtin.service:
name: fail2ban
state: restarted
- name: reiniciar syslog
ansible.builtin.service:
name: rsyslog
state: restarted
Lanzamos o playbook:
$ ansible-playbook server-apache.yml -K
BECOME password: PLAY [incus] ************************************************************************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************************** ok: [192.0.2.193] ok: [192.0.2.191] ok: [192.0.2.192] TASK [instalar paquetes] ************************************************************************************************************************************************************************ changed: [192.0.2.191] changed: [192.0.2.193] changed: [192.0.2.192] TASK [crear jail.local] ************************************************************************************************************************************************************************* changed: [192.0.2.193] changed: [192.0.2.191] changed: [192.0.2.192] TASK [modificar parametro bantime en jail.local] ************************************************************************************************************************************************ changed: [192.0.2.193] changed: [192.0.2.191] changed: [192.0.2.192] TASK [modificar parametro findtime en jail.local] *********************************************************************************************************************************************** changed: [192.0.2.191] changed: [192.0.2.192] changed: [192.0.2.193] TASK [modificar parametro maxretry en jail.local] *********************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.191] changed: [192.0.2.193] TASK [anular reduccion mensajes rsyslog] ******************************************************************************************************************************************************** changed: [192.0.2.191] changed: [192.0.2.193] changed: [192.0.2.192] TASK [Arrancar Apache y fail2ban] *************************************************************************************************************************************************************** ok: [192.0.2.191] => (item=apache2) ok: [192.0.2.193] => (item=apache2) ok: [192.0.2.192] => (item=apache2) ok: [192.0.2.193] => (item=fail2ban) ok: [192.0.2.191] => (item=fail2ban) ok: [192.0.2.192] => (item=fail2ban) TASK [habilitar módulo ssl] ********************************************************************************************************************************************************************* changed: [192.0.2.192] changed: [192.0.2.193] changed: [192.0.2.191] TASK [añadir virtualhost para el dominio] ******************************************************************************************************************************************************* changed: [192.0.2.191] changed: [192.0.2.193] changed: [192.0.2.192] TASK [añadir virtualhost https para el dominio] ************************************************************************************************************************************************* changed: [192.0.2.191] changed: [192.0.2.193] changed: [192.0.2.192] TASK [copiar certificados sitio web] ************************************************************************************************************************************************************ changed: [192.0.2.191] => (item=/home/manuel/devops/www.manuel2023.test.key) changed: [192.0.2.192] => (item=/home/manuel/devops/www.manuel2023.test.key) changed: [192.0.2.193] => (item=/home/manuel/devops/www.manuel2023.test.key) changed: [192.0.2.191] => (item=/home/manuel/devops/www.manuel2023.test.crt) changed: [192.0.2.192] => (item=/home/manuel/devops/www.manuel2023.test.crt) changed: [192.0.2.193] => (item=/home/manuel/devops/www.manuel2023.test.crt) TASK [copiar sitio web] ************************************************************************************************************************************************************************* changed: [192.0.2.192] changed: [192.0.2.191] changed: [192.0.2.193] TASK [habilitar sitio web] ********************************************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.191] changed: [192.0.2.193] TASK [habilitar sitio web https] **************************************************************************************************************************************************************** changed: [192.0.2.191] changed: [192.0.2.192] changed: [192.0.2.193] TASK [deshabilitar sitio por defecto] *********************************************************************************************************************************************************** changed: [192.0.2.191] changed: [192.0.2.192] changed: [192.0.2.193] RUNNING HANDLER [reiniciar Apache] ************************************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.191] changed: [192.0.2.193] RUNNING HANDLER [reload Apache] ***************************************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.193] changed: [192.0.2.191] RUNNING HANDLER [reiniciar fail2ban] ************************************************************************************************************************************************************ changed: [192.0.2.191] changed: [192.0.2.193] changed: [192.0.2.192] RUNNING HANDLER [reiniciar syslog] ************************************************************************************************************************************************************** changed: [192.0.2.192] changed: [192.0.2.193] changed: [192.0.2.191] PLAY RECAP ************************************************************************************************************************************************************************************** 192.0.2.191 : ok=20 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.0.2.192 : ok=20 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.0.2.193 : ok=20 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Uns comentarios sobre a saída:
- No caso de erro na execución dunha tarefa párase a execución do playbook.
- Lanzar repetidas veces o playbook non fará que cambie o estado final dos equipos. Este concepto é coñecido por 'idempotencia'.
O resultado é que nos tres servidores temos a configuración desexada (lembrar que para acceder usando www.manuel2023.test hai que configurar a resolución dns no equipo, por exemplo, a través do arquivo /etc/hosts):
Acceso por https ó servidor web
Fig. Acceso por http e https a www.manuel2023.com en server01
$ ansible incus -m ansible.builtin.shell -a 'ss -ltnp' -b -K
BECOME password:
192.0.2.192 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=301,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=986,fd=3))
LISTEN 0 511 *:80 *:* users:(("apache2",pid=17251,fd=4),("apache2",pid=17250,fd=4),("apache2",pid=17249,fd=4),("apache2",pid=17248,fd=4),("apache2",pid=17247,fd=4),("apache2",pid=17211,fd=4))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=986,fd=4))
LISTEN 0 511 *:443 *:* users:(("apache2",pid=17251,fd=6),("apache2",pid=17250,fd=6),("apache2",pid=17249,fd=6),("apache2",pid=17248,fd=6),("apache2",pid=17247,fd=6),("apache2",pid=17211,fd=6))
192.0.2.191 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=987,fd=3))
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=301,fd=13))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=987,fd=4))
LISTEN 0 511 *:443 *:* users:(("apache2",pid=17073,fd=6),("apache2",pid=16965,fd=6),("apache2",pid=16964,fd=6),("apache2",pid=16963,fd=6),("apache2",pid=16962,fd=6),("apache2",pid=16961,fd=6),("apache2",pid=16925,fd=6))
LISTEN 0 511 *:80 *:* users:(("apache2",pid=17073,fd=4),("apache2",pid=16965,fd=4),("apache2",pid=16964,fd=4),("apache2",pid=16963,fd=4),("apache2",pid=16962,fd=4),("apache2",pid=16961,fd=4),("apache2",pid=16925,fd=4))
192.0.2.193 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=301,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=988,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=988,fd=4))
LISTEN 0 511 *:443 *:* users:(("apache2",pid=17244,fd=6),("apache2",pid=17243,fd=6),("apache2",pid=17242,fd=6),("apache2",pid=17241,fd=6),("apache2",pid=17240,fd=6),("apache2",pid=17204,fd=6))
LISTEN 0 511 *:80 *:* users:(("apache2",pid=17244,fd=4),("apache2",pid=17243,fd=4),("apache2",pid=17242,fd=4),("apache2",pid=17241,fd=4),("apache2",pid=17240,fd=4),("apache2",pid=17204,fd=4))
$ ansible incus -m ansible.builtin.shell -a 'apache2ctl -S' -b -K
BECOME password: 192.0.2.191 | CHANGED | rc=0 >> VirtualHost configuration: *:80 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test.conf:1) *:443 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test_https.conf:1) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex ssl-stapling: using_defaults Mutex ssl-cache: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default Mutex mpm-accept: using_defaults Mutex watchdog-callback: using_defaults Mutex ssl-stapling-refresh: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 Group: name="www-data" id=33 192.0.2.193 | CHANGED | rc=0 >> VirtualHost configuration: *:80 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test.conf:1) *:443 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test_https.conf:1) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex watchdog-callback: using_defaults Mutex ssl-stapling-refresh: using_defaults Mutex ssl-stapling: using_defaults Mutex ssl-cache: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default Mutex mpm-accept: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 Group: name="www-data" id=33 192.0.2.192 | CHANGED | rc=0 >> VirtualHost configuration: *:80 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test.conf:1) *:443 www.manuel2023.test (/etc/apache2/sites-enabled/www.manuel2023.test_https.conf:1) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex ssl-stapling-refresh: using_defaults Mutex ssl-stapling: using_defaults Mutex ssl-cache: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default Mutex mpm-accept: using_defaults Mutex watchdog-callback: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 Group: name="www-data" id=33
Instalación
Python
Na máquina servidora e cliente require Python (no momento actual v2.6 ou superior):
usuario@servidorAnsible:~$ python3 -V Python 3.12.1
Dependencias
Para as dependencias:
apt install software-properties-common
Ansible
Para instalar Ansible:
root@servidorAnsible:~# apt install ansible
Comprobamos que queda instalado:
root@servidorAnsible:~# ansible --version ansible [core 2.14.3] config file = None configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3/dist-packages/ansible
Configuración
Non xerou ficheiro de configuración, e precisamos dous:
config file = None
- /etc/ansible/ansible.cfg
- Configuración de ansible
- /etc/ansible/hosts
- Inventario de equipos
- Especificamos os equipos que serán administrados por ansible
- Podemos especificalos empregando FQDN ou IP’s
- Para empregar FQDN precisamos ter un servidor DNS na nosa rede
- Permite agrupar os equipos en aulas ou departamentos
Configuración de Ansible - ansible.cfg
Creamos o arquivo de configuración a man na ruta por defecto:
root@servidorAnsible:~# mkdir /etc/ansible/ root@servidorAnsible:~# cd /etc/ansible/ root@servidorAnsible:/etc/ansible# vi ansible.cfg [defaults] inventory=/etc/ansible/hosts
Comprobamos como xa emprega o noso arquivo de configuración:
root@servidorAnsible:/etc/ansible# ansible --version ansible [core 2.14.3] config file = /etc/ansible/ansible.cfg configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
Configuración de Ansible - inventario
Crearemos os arquivos de configuración en /etc/ansible
- Temos que engadir os clientes en /etc/ansible/hosts. Este é un arquivo moi importante no que seDefine o inventario de equipos a xestionar mediante ansible
- Definimos dous grupos de clientes correspondentes a dúas aulas ficticias
- Poderemos xestionalos de xeito individual ou de xeito conxunto
- Se tivésemos un Servidor DNS poderíamos empregar nomes de equipos, de momento só IP’s
[aula1] 10.0.2.10 [aula2] 10.0.2.20
Para crear o arquivo de inventario (aínda que só temos dous equipos clientes, damos de alta outros dous ficticios):
root@servidorAnsible:/etc/ansible# vi hosts #Definimos os equipos da Aula1 [aula1] 10.0.2.10 Definimos os equipos da Aula2 [aula2] 10.0.2.20
Para comprobar que o inventario está correctamente configurado:
root@servidorAnsible:/etc/ansible# ansible all --list-hosts hosts (2): 10.0.2.10 10.0.2.20
Primeiras probas con ansible
Empregamos o módulo ping de ansible para comprobar a conexión cos nodos clientes (Importante: asegúrate que estén arrancados!!)
- Sintaxe: ansible Equipos -m módulo
- Se queremos saber se os equipos da Aula1 están acendidos
- ansible aula1 -m ping
Inicialmente, teremos erro: Ansible emprega ssh para conectarse co cliente, como é a primeira vez que se conecta con ese cliente pídenos confirmación
root@servidorAnsible:/etc/ansible# ansible aula1 -m ping
The authenticity of host '10.0.2.10 (10.0.2.10)' can't be established.
ED25519 key fingerprint is SHA256:/E+kj4vt6mKk2ud2cbKew2816I0ZwmM2I8RMhXefUQM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
10.0.2.10 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.2.10'
(ED25519) to the list of known hosts.\r\nroot@10.0.2.10: Permission denied
(publickey,password).",
"unreachable": true
}
Con -u indicamos usuario, pero falla novamente porque non sabe o contrasinal dese usuario para realizar a conexión por ssh:
root@servidorAnsible:/etc/ansible# ansible aula1 -m ping -u usuario 10.0.2.10 | UNREACHABLE! => {
"changed": false, "msg": "Failed to connect to the host via ssh: usuario@10.0.2.10: Permission denied
(publickey,password).",
"unreachable": true
}
Con -k contrasinal, pero falla unha vez máis porque é necesario ter instalado sshpass no servidor ansible
root@servidorAnsible:/etc/ansible# ansible aula1 -m ping -u usuario -k
SSH password:
10.0.2.10 | FAILED! => {
"msg": "to use the 'ssh' connection type with passwords or pkcs11_provider, you must
install the sshpass program"
Instalamos sshpass:
root@servidorAnsible:/etc/ansible# apt install sshpass
Ahora sí devolverá en cor verde (os erros estaban amosándose en vermello) indicando éxito. O equipo 10.0.2.10 respondeu o móudlo ping correctamente. A resposta é un JSON que pode conter moita información:
root@servidorAnsible:/etc/ansible# ansible aula1 -m ping -u usuario -k
SSH password:
10.0.2.10 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
De non estar acendido, a resposta sería:
root@servidorAnsible:/etc/ansible# ansible aula1 -m ping -u usuario -k
SSH password:
10.0.2.10 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
10.0.2.11 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.2.11 port
22: No route to host",
"unreachable": true
Con isto so fixemos un ping a un equipo mais se tivésemos dados de alta 100 equipos dentro da categoría aula1 con un só comando, veríamos cales responden e polo tanto saberíamos cales están acendidos
Ampliación
Tarefas
Referencias
- Z2301118 - Aprovisionamento automatizado con Ansible (Curso 23/24). José Luis Rojas Alonso baixo licenza CC BY-SA 4.0
- Seminario Ferramentas DevOps para Sysadmin con Vagrant, Packer e Terraform. Alberto García.
- Herramientas Devops: Docker y Vagrant
- Documentation - Getting started with Ansible