¿Cómo solucionar el error 'Permiso denegado' en el módulo script de Ansible?

AnsibleBeginner
Practicar Ahora

Introducción

Ansible es una poderosa herramienta de automatización que simplifica la gestión y configuración de la infraestructura. El módulo script de Ansible permite ejecutar scripts personalizados dentro de sus playbooks, extendiendo la funcionalidad de Ansible más allá de sus módulos integrados. Sin embargo, los usuarios a menudo se encuentran con el error "Permission denied" (Permiso denegado) al usar este módulo, lo que puede impedir los flujos de trabajo de automatización.

Este laboratorio le guiará a través de la comprensión y resolución de problemas relacionados con los permisos en el módulo script de Ansible. Aprenderá a identificar las causas de los errores de permisos e implementará varias soluciones para asegurar que sus scripts de Ansible se ejecuten con éxito.

Instalación de Ansible y Configuración del Entorno

Antes de que podamos explorar los problemas de permisos con los scripts de Ansible, necesitamos configurar nuestro entorno. Vamos a instalar Ansible y crear una estructura básica para nuestro entorno de prueba.

Instalación de Ansible

Primero, actualicemos el índice de paquetes e instalemos Ansible:

sudo apt update
sudo apt install -y ansible

Una vez que la instalación esté completa, verifique que Ansible esté instalado correctamente:

ansible --version

Debería ver una salida similar a esta, que muestra la versión de Ansible y los detalles de configuración:

ansible [core 2.12.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, Mar 01 2023, 12:34:56) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

Configuración de la Estructura del Proyecto

Ahora, creemos una estructura de directorio de proyecto para nuestro playbook y scripts de Ansible:

mkdir -p ~/project/ansible-lab/{playbooks,scripts}
cd ~/project/ansible-lab

En esta estructura:

  • playbooks/ contendrá nuestros playbooks de Ansible
  • scripts/ contendrá nuestros scripts de shell para ser ejecutados por Ansible

Creación de un Script Simple

Creemos un script de shell simple que usaremos con Ansible. Cree un archivo llamado hello.sh en el directorio de scripts:

cd ~/project/ansible-lab/scripts
touch hello.sh

Abra el archivo hello.sh en el editor y agregue el siguiente contenido:

#!/bin/bash
echo "Hello from $(hostname)!"
echo "Current time: $(date)"
echo "Current user: $(whoami)"

Este script mostrará el nombre de host, la hora actual y el usuario que ejecutó el script.

Creación de un Archivo de Inventario

A continuación, creemos un archivo de inventario simple para Ansible. En Ansible, un archivo de inventario define los hosts y grupos que Ansible administrará:

cd ~/project/ansible-lab
touch inventory.ini

Abra el archivo inventory.ini y agregue lo siguiente:

[local]
localhost ansible_connection=local

Este archivo de inventario le dice a Ansible que ejecute comandos en la máquina local.

Creación de un Playbook Básico

Ahora, creemos un playbook básico de Ansible que use el módulo script:

cd ~/project/ansible-lab/playbooks
touch run_script.yml

Abra el archivo run_script.yml y agregue el siguiente contenido:

---
- name: Run a script
  hosts: local
  tasks:
    - name: Execute the hello script
      script: ../scripts/hello.sh

Este playbook intentará ejecutar nuestro script hello.sh en la máquina local.

Con esta configuración básica, estamos listos para explorar los problemas de permisos con los scripts de Ansible en los siguientes pasos.

Encontrando el Error "Permission Denied" (Permiso Denegado)

Ahora que hemos configurado nuestro entorno, intentemos ejecutar nuestro playbook de Ansible y comprender qué sucede cuando encontramos un error de "permission denied" (permiso denegado).

Ejecutando el Playbook

Intentemos ejecutar nuestro playbook:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/run_script.yml

Probablemente encontrará un mensaje de error similar a este:

TASK [Execute the hello script] *******************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "failed to execute the script: /bin/sh: 1: /home/labex/.ansible/tmp/ansible-tmp-1234567890.12-123456789012345/AnsiballZ_script.py: Permission denied"}

Este es un error común de "permission denied" (permiso denegado) al usar el módulo script de Ansible. El error ocurre porque nuestro script no tiene el permiso de ejecución, que es necesario para que se ejecute.

Entendiendo los Permisos de Archivos en Linux

En Linux, cada archivo tiene permisos que determinan quién puede leerlo, escribirlo o ejecutarlo. Hay tres tipos de permisos:

  1. Read (r): Permite leer el contenido del archivo
  2. Write (w): Permite modificar el archivo
  3. Execute (x): Permite ejecutar el archivo como un programa

Estos permisos se asignan a tres categorías de usuarios diferentes:

  1. User (owner): El propietario del archivo
  2. Group: Usuarios que son miembros del grupo del archivo
  3. Others: Todos los demás usuarios

Puede ver los permisos de un archivo usando el comando ls -l:

ls -l ~/project/ansible-lab/scripts/hello.sh

Podría ver una salida como esta:

-rw-rw-r-- 1 labex labex 95 Jun 10 12:34 /home/labex/project/ansible-lab/scripts/hello.sh

En esta salida, el primer conjunto de caracteres (-rw-rw-r--) representa los permisos del archivo:

  • El primer carácter (-) indica que es un archivo regular
  • Los siguientes tres caracteres (rw-) son los permisos del propietario (lectura, escritura, sin ejecución)
  • Los siguientes tres (rw-) son los permisos del grupo
  • Los tres finales (r--) son permisos para otros

Observe que el permiso de ejecución (x) falta para todas las categorías de usuarios, que es la razón por la que obtenemos el error de "permission denied" (permiso denegado).

Verificando los Permisos Actuales

Examinemos los permisos actuales de nuestro script:

ls -l ~/project/ansible-lab/scripts/hello.sh

Verá que al script le falta el permiso de ejecución, que es necesario para que Ansible lo ejecute.

En el siguiente paso, aprenderemos cómo solucionar este problema de permisos y ejecutar con éxito nuestro playbook de Ansible.

Solucionando Problemas de Permisos con chmod

La forma más común de solucionar el error "Permission denied" (permiso denegado) es agregar permisos de ejecución al archivo de script. Podemos hacer esto usando el comando chmod.

Entendiendo el Comando chmod

El comando chmod se utiliza para cambiar los permisos de archivos o directorios en Linux. El comando tiene varias formas de especificar permisos:

  1. Modo simbólico: Usa letras (r, w, x) para representar los permisos
  2. Modo numérico: Usa números (4, 2, 1) para representar los permisos

Para nuestro propósito, usaremos el modo simbólico para agregar permisos de ejecución.

Agregando Permisos de Ejecución al Script

Agreguemos permisos de ejecución a nuestro script:

chmod +x ~/project/ansible-lab/scripts/hello.sh

La opción +x agrega el permiso de ejecución para todas las categorías de usuarios (usuario, grupo y otros).

Verifiquemos que los permisos se hayan actualizado:

ls -l ~/project/ansible-lab/scripts/hello.sh

Ahora debería ver una salida similar a esta:

-rwxrwxr-x 1 labex labex 95 Jun 10 12:34 /home/labex/project/ansible-lab/scripts/hello.sh

Observe la x en la cadena de permisos, lo que indica que se ha agregado el permiso de ejecución.

Ejecutando el Playbook de Nuevo

Ahora que hemos agregado permisos de ejecución a nuestro script, ejecutemos el playbook de Ansible de nuevo:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/run_script.yml

Esta vez, el playbook debería ejecutarse con éxito:

PLAY [Run a script] ******************************************

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

TASK [Execute the hello script] *****************************
changed: [localhost]

PLAY RECAP *************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Visualizando la Salida del Script

Veamos la salida de nuestro script. Ansible captura la salida del script y la incluye en los resultados de la tarea. Para ver la salida detallada, modifiquemos nuestro playbook para registrar y mostrar la salida:

cd ~/project/ansible-lab/playbooks

Edite el archivo run_script.yml para incluir las tareas de registro y depuración:

---
- name: Run a script
  hosts: local
  tasks:
    - name: Execute the hello script
      script: ../scripts/hello.sh
      register: script_output

    - name: Display script output
      debug:
        var: script_output.stdout_lines

Ahora ejecutemos el playbook de nuevo:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/run_script.yml

Debería ver una salida como esta:

PLAY [Run a script] ******************************************

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

TASK [Execute the hello script] *****************************
changed: [localhost]

TASK [Display script output] ********************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "Hello from localhost!",
        "Current time: Wed Jun 10 12:34:56 UTC 2023",
        "Current user: labex"
    ]
}

PLAY RECAP *************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Ahora puede ver la salida completa de nuestro script. El script se ejecutó como el usuario labex, que es nuestro usuario actual.

Al agregar permisos de ejecución con chmod +x, hemos solucionado con éxito el error "Permission denied" (permiso denegado) y ahora podemos ejecutar nuestro script a través de Ansible.

Usando Become para la Escalada de Privilegios

A veces, necesita ejecutar scripts con privilegios elevados, como ejecutar comandos que requieren acceso root. En estos casos, simplemente agregar permisos de ejecución al script podría no ser suficiente. Ansible proporciona la directiva become para ejecutar tareas con escalada de privilegios.

Entendiendo la Directiva Become

La directiva become en Ansible le permite ejecutar tareas como un usuario diferente, típicamente con privilegios elevados. Esto es similar a usar sudo en la línea de comandos.

Las opciones clave para la directiva become incluyen:

  • become: yes: Habilita la escalada de privilegios
  • become_user: <username>: Especifica qué usuario convertirse (el valor predeterminado es root)
  • become_method: <method>: Especifica cómo convertirse en el usuario (el valor predeterminado es sudo)

Creando un Script que Requiere Privilegios Root

Creemos un script que requiera privilegios root para ejecutarse con éxito:

cd ~/project/ansible-lab/scripts
touch system_info.sh

Agregue el siguiente contenido al archivo system_info.sh:

#!/bin/bash
echo "System information - requires root privileges"
echo "Hostname: $(hostname)"
echo "Kernel version: $(uname -r)"
echo "Available disk space:"
df -h /
echo "User executing the script: $(whoami)"

Haga que el script sea ejecutable:

chmod +x ~/project/ansible-lab/scripts/system_info.sh

Creando un Playbook con Become

Ahora, creemos un playbook que use la directiva become:

cd ~/project/ansible-lab/playbooks
touch root_script.yml

Agregue el siguiente contenido al archivo root_script.yml:

---
- name: Run a script as root
  hosts: local
  tasks:
    - name: Execute the system info script
      script: ../scripts/system_info.sh
      become: yes
      register: script_output

    - name: Display script output
      debug:
        var: script_output.stdout_lines

La directiva become: yes le dice a Ansible que ejecute el script con privilegios elevados.

Ejecutando el Playbook con Become

Ejecutemos nuestro nuevo playbook:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/root_script.yml

El playbook debería ejecutarse con éxito, y debería ver una salida similar a esta:

PLAY [Run a script as root] *********************************

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

TASK [Execute the system info script] **********************
changed: [localhost]

TASK [Display script output] *******************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "System information - requires root privileges",
        "Hostname: localhost",
        "Kernel version: 5.15.0-1015-aws",
        "Available disk space:",
        "Filesystem      Size  Used Avail Use% Mounted on",
        "/dev/root        59G   17G   42G  29% /",
        "User executing the script: root"
    ]
}

PLAY RECAP ************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Observe que en la salida del script, el "User executing the script" (Usuario que ejecuta el script) ahora es root, no labex. Esto muestra que nuestro script se ejecutó con privilegios elevados debido a la directiva become: yes.

Entendiendo Cuándo Usar Become

Debería usar la directiva become en las siguientes situaciones:

  1. Cuando el script necesita acceder a archivos o directorios del sistema que requieren privilegios root
  2. Cuando el script necesita instalar paquetes o modificar configuraciones del sistema
  3. Cuando el script necesita ejecutar comandos que normalmente requerirían sudo en la línea de comandos

Al usar la directiva become apropiadamente, puede asegurarse de que sus scripts tengan los permisos necesarios para ejecutarse con éxito, evitando errores de "permission denied" (permiso denegado).

Mejores Prácticas para Evitar Problemas de Permisos

Ahora que entendemos cómo solucionar problemas de permisos usando chmod y become, exploremos algunas de las mejores prácticas para evitar que los problemas de permisos ocurran en primer lugar.

1. Siempre Haga que los Scripts Sean Ejecutables Antes de Usarlos

Antes de usar un script en Ansible, siempre asegúrese de que tenga el permiso de ejecución:

chmod +x path/to/script.sh

Es una buena práctica hacer esto como parte de su proceso de creación de scripts.

2. Use el Control de Versiones con los Modos de Archivo Correctos

Si está usando Git u otro sistema de control de versiones, asegúrese de que preserve los modos de archivo (permisos). En Git, puede configurar esto con:

git config core.fileMode true

Para repositorios existentes, es posible que deba actualizar los modos de archivo:

git update-index --chmod=+x path/to/script.sh

3. Cree un Script para Verificar y Corregir Permisos

Creemos un script de utilidad que verifique y corrija los permisos para todos los scripts en nuestro proyecto:

cd ~/project/ansible-lab
touch fix_permissions.sh

Agregue el siguiente contenido al archivo fix_permissions.sh:

#!/bin/bash
echo "Fixing permissions for scripts in ansible-lab"

## Find all .sh files and make them executable
find ~/project/ansible-lab -name "*.sh" -type f -exec chmod +x {} \;

echo "Done. All script files now have execute permissions."

Haga que el script sea ejecutable:

chmod +x ~/project/ansible-lab/fix_permissions.sh

Ejecute el script para asegurarse de que todos los scripts en su proyecto tengan permisos de ejecución:

./fix_permissions.sh

4. Use el Módulo File de Ansible para Establecer Permisos

También puede usar el módulo file de Ansible para asegurarse de que los archivos de script tengan los permisos correctos. Creemos un playbook que haga esto:

cd ~/project/ansible-lab/playbooks
touch set_permissions.yml

Agregue el siguiente contenido al archivo set_permissions.yml:

---
- name: Set correct permissions for scripts
  hosts: local
  tasks:
    - name: Find all script files
      find:
        paths: /home/labex/project/ansible-lab
        patterns: "*.sh"
        recurse: yes
      register: script_files

    - name: Make script files executable
      file:
        path: "{{ item.path }}"
        mode: "0755"
      loop: "{{ script_files.files }}"

Ejecute este playbook para asegurarse de que todos los scripts tengan los permisos correctos:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/set_permissions.yml

5. Cree un Playbook de Verificación Previa

Finalmente, creemos un playbook de verificación previa que se ejecute antes de sus playbooks principales para verificar que todo esté configurado correctamente:

cd ~/project/ansible-lab/playbooks
touch preflight_check.yml

Agregue el siguiente contenido al archivo preflight_check.yml:

---
- name: Pre-flight checks
  hosts: local
  tasks:
    - name: Check if scripts are executable
      find:
        paths: /home/labex/project/ansible-lab
        patterns: "*.sh"
        recurse: yes
      register: script_files

    - name: Verify script permissions
      stat:
        path: "{{ item.path }}"
      register: stat_results
      loop: "{{ script_files.files }}"
      failed_when: not stat_results.stat.executable
      ignore_errors: yes

Este playbook verifica si todos los archivos .sh son ejecutables e informa cualquier archivo que no lo sea.

Ejecutemos la verificación previa:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini playbooks/preflight_check.yml

Si todos sus scripts tienen los permisos correctos, el playbook debería completarse sin errores. Si a algún script le faltan permisos de ejecución, verá una notificación.

Siguiendo estas mejores prácticas, puede evitar errores de "permission denied" (permiso denegado) en sus scripts de Ansible y asegurarse de que su automatización se ejecute sin problemas.

Resumen

En este laboratorio, ha aprendido a identificar y resolver errores de "Permission denied" (Permiso denegado) al usar el módulo script de Ansible.

Las conclusiones clave de este laboratorio incluyen:

  1. Comprender la importancia de los permisos de archivo en Linux y cómo afectan la ejecución de scripts en Ansible
  2. Usar el comando chmod para agregar permisos de ejecución a los archivos de script
  3. Utilizar la directiva become de Ansible para la escalada de privilegios al ejecutar scripts que requieren acceso root
  4. Implementar las mejores prácticas para prevenir problemas de permisos, incluyendo:
    • Hacer que los scripts sean ejecutables antes de usarlos
    • Mantener los modos de archivo correctos en el control de versiones
    • Crear scripts de utilidad para verificar y corregir permisos
    • Usar el módulo file de Ansible para establecer permisos
    • Implementar verificaciones previas (pre-flight checks) para verificar su entorno

Al aplicar estas técnicas, puede asegurarse de que sus scripts de Ansible se ejecuten sin problemas, sin errores de permisos, mejorando la fiabilidad de sus flujos de trabajo de automatización.

Las habilidades que ha aprendido en este laboratorio son fundamentales para trabajar eficazmente con Ansible y se pueden aplicar a una amplia gama de escenarios de automatización.