Como corrigir o erro 'Permission denied' no módulo script do Ansible

AnsibleBeginner
Pratique Agora

Introdução

Ansible é uma ferramenta de automação poderosa que simplifica o gerenciamento e a configuração da infraestrutura. O módulo script do Ansible permite que você execute scripts personalizados dentro de seus playbooks, estendendo a funcionalidade do Ansible além de seus módulos integrados. No entanto, os usuários frequentemente encontram o erro 'Permission denied' (Permissão negada) ao usar este módulo, o que pode impedir os fluxos de trabalho de automação.

Este laboratório irá guiá-lo através da compreensão e resolução de problemas relacionados a permissões no módulo script do Ansible. Você aprenderá como identificar as causas dos erros de permissão e implementar várias soluções para garantir que seus scripts Ansible sejam executados com sucesso.

Instalando o Ansible e Configurando o Ambiente

Antes de explorarmos os problemas de permissão com os scripts Ansible, precisamos configurar nosso ambiente. Vamos instalar o Ansible e criar uma estrutura básica para nosso ambiente de teste.

Instalando o Ansible

Primeiro, vamos atualizar o índice de pacotes e instalar o Ansible:

sudo apt update
sudo apt install -y ansible

Após a conclusão da instalação, verifique se o Ansible está instalado corretamente:

ansible --version

Você deve ver uma saída semelhante a esta, mostrando a versão do Ansible e os detalhes da configuração:

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

Configurando a Estrutura do Projeto

Agora, vamos criar uma estrutura de diretórios de projeto para nosso playbook e scripts Ansible:

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

Nesta estrutura:

  • playbooks/ conterá nossos playbooks Ansible
  • scripts/ conterá nossos scripts de shell a serem executados pelo Ansible

Criando um Script Simples

Vamos criar um script de shell simples que usaremos com o Ansible. Crie um arquivo chamado hello.sh no diretório scripts:

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

Abra o arquivo hello.sh no editor e adicione o seguinte conteúdo:

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

Este script irá exibir o hostname, a hora atual e o usuário que executou o script.

Criando um Arquivo de Inventário

Em seguida, vamos criar um arquivo de inventário simples para o Ansible. No Ansible, um arquivo de inventário define os hosts e grupos que o Ansible irá gerenciar:

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

Abra o arquivo inventory.ini e adicione o seguinte:

[local]
localhost ansible_connection=local

Este arquivo de inventário diz ao Ansible para executar comandos na máquina local.

Criando um Playbook Básico

Agora, vamos criar um playbook Ansible básico que usa o módulo script:

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

Abra o arquivo run_script.yml e adicione o seguinte conteúdo:

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

Este playbook tentará executar nosso script hello.sh na máquina local.

Com esta configuração básica, estamos prontos para explorar os problemas de permissão com os scripts Ansible nos próximos passos.

Encontrando o Erro de Permissão Negada

Agora que configuramos nosso ambiente, vamos tentar executar nosso playbook Ansible e entender o que acontece quando encontramos um erro de permissão negada.

Executando o Playbook

Vamos tentar executar nosso playbook:

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

Você provavelmente encontrará uma mensagem de erro semelhante a esta:

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 é um erro comum de permissão negada ao usar o módulo script do Ansible. O erro ocorre porque nosso script não tem a permissão de execução, que é necessária para que ele seja executado.

Entendendo as Permissões de Arquivos no Linux

No Linux, cada arquivo tem permissões que determinam quem pode ler, escrever ou executá-lo. Existem três tipos de permissões:

  1. Read (r) (Leitura): Permite a leitura do conteúdo do arquivo
  2. Write (w) (Escrita): Permite a modificação do arquivo
  3. Execute (x) (Execução): Permite a execução do arquivo como um programa

Essas permissões são atribuídas a três categorias diferentes de usuários:

  1. User (owner) (Usuário (proprietário)): O proprietário do arquivo
  2. Group (Grupo): Usuários que são membros do grupo do arquivo
  3. Others (Outros): Todos os outros usuários

Você pode visualizar as permissões de um arquivo usando o comando ls -l:

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

Você pode ver uma saída como esta:

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

Nesta saída, o primeiro conjunto de caracteres (-rw-rw-r--) representa as permissões do arquivo:

  • O primeiro caractere (-) indica que este é um arquivo regular
  • Os três caracteres seguintes (rw-) são as permissões do proprietário (leitura, escrita, sem execução)
  • Os três seguintes (rw-) são as permissões do grupo
  • Os três finais (r--) são as permissões para outros

Observe que a permissão de execução (x) está ausente para todas as categorias de usuários, e é por isso que estamos recebendo o erro de permissão negada.

Verificando as Permissões Atuais

Vamos examinar as permissões atuais do nosso script:

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

Você verá que o script está sem a permissão de execução, que é necessária para que o Ansible o execute.

No próximo passo, aprenderemos como corrigir esse problema de permissão e executar com sucesso nosso playbook Ansible.

Corrigindo Problemas de Permissão com chmod

A maneira mais comum de corrigir o erro "Permission denied" (Permissão negada) é adicionar permissões de execução ao arquivo de script. Podemos fazer isso usando o comando chmod.

Entendendo o Comando chmod

O comando chmod é usado para alterar as permissões de arquivos ou diretórios no Linux. O comando tem várias maneiras de especificar permissões:

  1. Symbolic mode (Modo simbólico): Usa letras (r, w, x) para representar permissões
  2. Numeric mode (Modo numérico): Usa números (4, 2, 1) para representar permissões

Para nosso propósito, usaremos o modo simbólico para adicionar permissões de execução.

Adicionando Permissões de Execução ao Script

Vamos adicionar permissões de execução ao nosso script:

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

A opção +x adiciona permissão de execução para todas as categorias de usuários (usuário, grupo e outros).

Vamos verificar se as permissões foram atualizadas:

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

Agora você deve ver uma saída semelhante a esta:

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

Observe o x na string de permissões, indicando que a permissão de execução foi adicionada.

Executando o Playbook Novamente

Agora que adicionamos permissões de execução ao nosso script, vamos executar o playbook Ansible novamente:

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

Desta vez, o playbook deve ser executado com sucesso:

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 a Saída do Script

Vamos verificar a saída do nosso script. O Ansible captura a saída do script e a inclui nos resultados da tarefa. Para ver a saída detalhada, vamos modificar nosso playbook para registrar e exibir a saída:

cd ~/project/ansible-lab/playbooks

Edite o arquivo run_script.yml para incluir as tarefas de registro e depuração:

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

Agora vamos executar o playbook novamente:

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

Você deve ver uma saída 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

Agora você pode ver a saída completa do nosso script. O script foi executado como o usuário labex, que é nosso usuário atual.

Ao adicionar permissões de execução com chmod +x, corrigimos com sucesso o erro "Permission denied" e agora podemos executar nosso script através do Ansible.

Usando Become para Escalada de Privilégios

Às vezes, você precisa executar scripts com privilégios elevados, como executar comandos que exigem acesso root. Nesses casos, simplesmente adicionar permissões de execução ao script pode não ser suficiente. O Ansible fornece a diretiva become para executar tarefas com escalada de privilégios.

Entendendo a Diretiva Become

A diretiva become no Ansible permite que você execute tarefas como um usuário diferente, normalmente com privilégios elevados. Isso é semelhante ao uso de sudo na linha de comando.

As principais opções para a diretiva become incluem:

  • become: yes: Habilita a escalada de privilégios
  • become_user: <username>: Especifica qual usuário se tornar (o padrão é root)
  • become_method: <method>: Especifica como se tornar o usuário (o padrão é sudo)

Criando um Script que Requer Privilégios Root

Vamos criar um script que requer privilégios root para ser executado com sucesso:

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

Adicione o seguinte conteúdo ao arquivo 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)"

Torne o script executável:

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

Criando um Playbook com Become

Agora, vamos criar um playbook que usa a diretiva become:

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

Adicione o seguinte conteúdo ao arquivo 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

A diretiva become: yes diz ao Ansible para executar o script com privilégios elevados.

Executando o Playbook com Become

Vamos executar nosso novo playbook:

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

O playbook deve ser executado com sucesso, e você deve ver uma saída semelhante 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 na saída do script, o "User executing the script" (Usuário executando o script) agora é root, não labex. Isso mostra que nosso script foi executado com privilégios elevados devido à diretiva become: yes.

Entendendo Quando Usar Become

Você deve usar a diretiva become nas seguintes situações:

  1. Quando o script precisa acessar arquivos ou diretórios do sistema que exigem privilégios root
  2. Quando o script precisa instalar pacotes ou modificar configurações do sistema
  3. Quando o script precisa executar comandos que normalmente exigiriam sudo na linha de comando

Ao usar a diretiva become apropriadamente, você pode garantir que seus scripts tenham as permissões necessárias para serem executados com sucesso, evitando erros de permissão negada.

Melhores Práticas para Evitar Problemas de Permissão

Agora que entendemos como corrigir problemas de permissão usando chmod e become, vamos explorar algumas melhores práticas para evitar que problemas de permissão ocorram em primeiro lugar.

1. Sempre Torne os Scripts Executáveis Antes de Usá-los

Antes de usar um script no Ansible, sempre certifique-se de que ele tenha a permissão de execução:

chmod +x path/to/script.sh

É uma boa prática fazer isso como parte do seu processo de criação de script.

2. Use o Controle de Versão com Modos de Arquivo Adequados

Se você estiver usando Git ou outro sistema de controle de versão, certifique-se de que ele preserve os modos de arquivo (permissões). No Git, você pode configurar isso com:

git config core.fileMode true

Para repositórios existentes, pode ser necessário atualizar os modos de arquivo:

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

3. Crie um Script para Verificar e Corrigir Permissões

Vamos criar um script utilitário que verifica e corrige as permissões de todos os scripts em nosso projeto:

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

Adicione o seguinte conteúdo ao arquivo 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."

Torne o script executável:

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

Execute o script para garantir que todos os scripts em seu projeto tenham permissões de execução:

./fix_permissions.sh

4. Use o Módulo File do Ansible para Definir Permissões

Você também pode usar o módulo file do Ansible para garantir que os arquivos de script tenham as permissões corretas. Vamos criar um playbook que faz isso:

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

Adicione o seguinte conteúdo ao arquivo 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 }}"

Execute este playbook para garantir que todos os scripts tenham as permissões corretas:

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

5. Crie um Playbook de Verificação Pré-Voo

Finalmente, vamos criar um playbook de verificação pré-voo que é executado antes de seus playbooks principais para verificar se tudo está configurado corretamente:

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

Adicione o seguinte conteúdo ao arquivo 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 se todos os arquivos .sh são executáveis e relata aqueles que não são.

Vamos executar a verificação pré-voo:

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

Se todos os seus scripts tiverem as permissões corretas, o playbook deve ser concluído sem erros. Se algum script estiver faltando permissões de execução, você verá uma notificação.

Ao seguir estas melhores práticas, você pode evitar erros de permissão negada em seus scripts Ansible e garantir que sua automação seja executada sem problemas.

Resumo

Neste laboratório, você aprendeu como identificar e resolver erros de 'Permission denied' (Permissão negada) ao usar o módulo script do Ansible.

Os principais pontos deste laboratório incluem:

  1. Compreender a importância das permissões de arquivo no Linux e como elas afetam a execução de scripts no Ansible
  2. Usar o comando chmod para adicionar permissões de execução aos arquivos de script
  3. Utilizar a diretiva become do Ansible para escalada de privilégios ao executar scripts que exigem acesso root
  4. Implementar as melhores práticas para evitar problemas de permissão, incluindo:
    • Tornar os scripts executáveis antes de usá-los
    • Manter os modos de arquivo adequados no controle de versão
    • Criar scripts utilitários para verificar e corrigir permissões
    • Usar o módulo file do Ansible para definir permissões
    • Implementar verificações pré-voo para verificar seu ambiente

Ao aplicar essas técnicas, você pode garantir que seus scripts Ansible sejam executados sem problemas, sem erros de permissão, aprimorando a confiabilidade de seus fluxos de trabalho de automação.

As habilidades que você aprendeu neste laboratório são fundamentais para trabalhar de forma eficaz com o Ansible e podem ser aplicadas a uma ampla gama de cenários de automação.