Skip to content

Playbook Ejemplo

Requisitos:

  • Red Hat Enterprise Linux 9.x
  • Webserver: nginx o apache
  • Crear usuarios hugo, paco, luis (grupo devel)
  • Configurar firewall y acceso TCP/80, TCP/443 y SSH
  • Webserver sin versión visible
  • Document Root con grupo devel
  • Instalar: screen, tmux, vi
  • Colocar y eliminar prueba.html

Módulos a usar: - group, user, yum, service, uri, file, copy, firewalld Colecciones: - ansible.posix - ansible.builtin


Prepara el ambiente (Realizar esto únicamente en el bastion)

  1. Poder administrar via SSH por medio de llaves y configurado un usuario con SUDO.

    NOTA: Hacer referencia a secciones anterior de este curso. Recomendación (coloque la llave privada de student en /home/student/.ssh/id_rsa en el bastion)

  2. Crear Directorio para Playbook.

    mkdir ~/primer-playbook ; cd ~/primer-playbook
    

  3. Instalar Ansible Core.
    sudo dnf install ansible-core
    
  4. Listar las colecciones presentes:
    ansible-galaxy collection list
    
    NOTA: Si es la primera vez que ejecuta ansible, puede obtener este mensaje:
    ERROR! - None of the provided paths were usable. Please specify a valid path with --collections-path
    
  5. Si no existe la colección ansible.posix, proceder a instalarla.
    ansible-galaxy collection install ansible.posix
    
  6. Listar las colecciones presentes:
    ansible-galaxy collection list
    
    Salida similar:
    Collection    Version
    ------------- -------
    ansible.posix 2.0.0
    

Crear inventario

En el directorio: ~/primer-playbook.

NOTA:: Si utiliza vi para copiar/pegar este texto, se recomienda habilitar la opción set :paste .

  • Archivo: inventory
  • Contenido:

    [webservers]
    student-X-servera
    

  • Validar inventario y acceso a hosts administrados (manage nodes).

    ansible-inventory -i inventory --graph
    ansible-inventory -i inventory --list
    

  • Validar inventario y acceso a hosts administrados (manage nodes).
    ansible -m ping -i inventory webservers -u student
    
    Salida similar:
    student-X-servera | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python3"
        },
        "changed": false,
        "ping": "pong"
    }
    

Playbook

En el directorio: ~/primer-playbook.

  • Archivo: config-webservers.yaml
  • Contenido:

    ---
    - name: Configurar servidor Red Hat Enterprise Linux con Webserver y herramientas de desarrollo
      hosts: webservers
      become: true
      vars:
        test_page: False
        developers_group: devel
        developers_users:
          - hugo
          - paco
          - luis
        packages_common:
          - tmux
          - vim-enhanced
        webserver_pkg: nginx
        web_root: /usr/share/nginx/html
        prueba_file: prueba.html
    
      tasks:
    
        - name: Crear grupo de desarrolladores
          ansible.builtin.group:
            name: "{{ developers_group }}"
            state: present
    
        - name: Crear usuarios desarrolladores
          ansible.builtin.user:
            name: "{{ item }}"
            groups: "{{ developers_group }}"
            append: yes
            state: present
          loop: "{{ developers_users }}"
    
        - name: Instalar paquetes comunes de desarrollo
          ansible.builtin.yum:
            name: "{{ packages_common }}"
            state: present
    
        - name: Instalar el servidor web
          ansible.builtin.yum:
            name: "{{ webserver_pkg }}"
            state: present
    
        - name: Iniciar y habilitar el servicio del webserver
          ansible.builtin.service:
            name: "{{ webserver_pkg }}"
            state: started
            enabled: yes
    
        - name: Asegurar que el webserver no muestre la versión (nginx)
          ansible.builtin.lineinfile:
            path: /etc/nginx/nginx.conf
            regexp: '^.*server_tokens.*$'
            line: '    server_tokens off;'
            insertafter: '^http'
            backup: yes
          notify: Reiniciar nginx
    
        - name: Establecer propiedad del webroot al grupo de desarrolladores
          ansible.builtin.file:
            path: "{{ web_root }}"
            group: "{{ developers_group }}"
            recurse: yes
    
        - block:
            - name: Colocar archivo de prueba
              ansible.builtin.copy:
                dest: "{{ web_root }}/{{ prueba_file }}"
                content: "<h1>Página de prueba</h1>"
                owner: root
                group: "{{ developers_group }}"
                mode: '0644'
    
            - name: Validar webserver
              ansible.builtin.uri:
                url: "http://{{ inventory_hostname }}/{{ prueba_file }}"
                return_content: True
              delegate_to: localhost
              become: false
              register: check
    
            - name: Show check
              ansible.builtin.debug:
                var: check
    
            - name: Eliminar página de prueba
              ansible.builtin.file:
                path: "{{ web_root }}/{{ prueba_file }}"
                state: absent
          when:
          - test_page|bool
    
        - name: Asegurar firewalld está instalado
          ansible.builtin.yum:
            name: firewalld
            state: present
    
        - name: Habilitar e iniciar firewalld
          ansible.builtin.service:
            name: firewalld
            state: started
            enabled: yes
    
        - name: Permitir tráfico HTTP (80)
          ansible.posix.firewalld:
            port: 80/tcp
            permanent: true
            state: enabled
            immediate: yes
    
        - name: Permitir tráfico HTTPS (443)
          ansible.posix.firewalld:
            port: 443/tcp
            permanent: true
            state: enabled
            immediate: yes
    
        - name: Permitir tráfico SSH (22)
          ansible.posix.firewalld:
            port: 22/tcp
            permanent: true
            state: enabled
            immediate: yes
    
      handlers:
        - name: Reiniciar nginx
          ansible.builtin.service:
            name: nginx
            state: restarted
    

Ejecución

  1. Validar sintaxys.
    cd ~/primer-playbook
    ansible-playbook -i inventory config-webservers.yaml --syntax-check
    
  2. Ejecutar en Modo Check con dos niveles de verbose -vv.
    ansible-playbook -i inventory config-webservers.yaml --check -vv
    
    Es normal obtener un error similar a:
    fatal: [student-X-servera]: FAILED! => {"changed": false, "msg": "Could not find the requested service nginx: host"}
    
    Ya que no todos los módulos son compatible con check.
  3. Ejecutar el Playbook.
    ansible-playbook -i inventory config-webservers.yaml
    
  4. Vuelva a ejecutar el Playbook y note que en esta ocasión no se ha realizdo ningun cambio changed=0,ok=13 .
    ansible-playbook -i inventory config-webservers.yaml
    
    Debe obtener al finalizar la ejecución na salida similar a:
    PLAY RECAP **********************************************************************************************
    student-X-servera : ok=13   changed=0    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0
    
  5. Ejecutar el Playbook modificando el valor de una variable test_page, desde la linea de comando.
    ansible-playbook -i inventory config-webservers.yaml -e test_page=True
    
    Notar que en esta ejecución, se han ejecutado las tareas que buscan que la condición de test_page|bool == True se cumpla changed=1, ok=17 . Obtendrá una salida similar a:
    TASK [Show check] **********************************************
    ok: [student-5-servera] => {
        "check": {
            "accept_ranges": "bytes",
            "changed": false,
            "connection": "close",
            "content": "<h1>Página de prueba</h1>",
            "content_length": "26",
            "content_type": "text/html",
            "cookies": {},
            "cookies_string": "",
            "date": "Wed, 23 Apr 2025 16:34:00 GMT",
            "elapsed": 0,
            "etag": "\"68091628-1a\"",
            "failed": false,
            "last_modified": "Wed, 23 Apr 2025 16:32:40 GMT",
            "msg": "OK (26 bytes)",
            "redirected": false,
            "server": "nginx",
            "status": 200,
            "url": "http://student-X-servera/prueba.html"
        }
    }
    ...
    PLAY RECAP ****************************************************
    student-5-servera : ok=17   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
  6. Modifique el Playbook para revertir algunas de las configuraciones. Ajuste el playbook para:

    • Eliminar los usuario y grupos creados.
    • Eliminar el software instalado
    • Quitar las configuraciones del firewall

    Versión sugerida:

    • Archivo: revert-config-webservers.yaml
    • Contenido:
    ---
    - name: Revertir configuración Red Hat Enterprise Linux eliminar Webserver y herramientas de desarrollo
      hosts: webservers
      become: true
      vars:
        test_page: False
        developers_group: devel
        developers_users:
          - hugo
          - paco
          - luis
        packages_common:
          - tmux
          - vim-enhanced
        webserver_pkg: nginx
        web_root: /usr/share/nginx/html
        prueba_file: prueba.html
    
      tasks:
    
        - name: Eliminar grupo de desarrolladores
          ansible.builtin.group:
            name: "{{ developers_group }}"
            state: absent
    
        - name: Eliminar usuarios desarrolladores
          ansible.builtin.user:
            name: "{{ item }}"
            groups: "{{ developers_group }}"
            append: yes
            state: absent
          loop: "{{ developers_users }}"
    
        - name: Eliminar paquetes comunes de desarrollo
          ansible.builtin.yum:
            name: "{{ packages_common }}"
            state: absent
    
        - name: Desinstalar el servidor web
          ansible.builtin.yum:
            name: "{{ webserver_pkg }}"
            state: absent
    
        - name: Asegurar firewalld está instalado
          ansible.builtin.yum:
            name: firewalld
            state: present
    
        - name: Habilitar e iniciar firewalld
          ansible.builtin.service:
            name: firewalld
            state: started
            enabled: yes
    
        - name: Denegar tráfico HTTP (80)
          ansible.posix.firewalld:
            port: 80/tcp
            permanent: true
            state: disabled
            immediate: yes
    
        - name: Denegar tráfico HTTPS (443)
          ansible.posix.firewalld:
            port: 443/tcp
            permanent: true
            state: disabled
            immediate: yes
    
        - name: Permitir tráfico SSH (22)
          ansible.posix.firewalld:
            port: 22/tcp
            permanent: true
            state: enabled
            immediate: yes
    
  7. Ejecutar el Playbook.

    cd ~/primer-playbook
    ansible-playbook -i inventory revert-config-webservers.yaml