Introdução
Neste laboratório, você aprenderá as habilidades fundamentais para implantar e gerenciar arquivos em um sistema Red Hat Enterprise Linux (RHEL) usando Ansible. Você ganhará experiência prática com alguns dos módulos Ansible mais comuns e poderosos projetados para operações de arquivo, passando da implantação básica de arquivos para manipulação de conteúdo mais avançada e gerenciamento de estado.
Você começará usando o módulo ansible.builtin.copy para transferir um arquivo estático e definir seus atributos. Em seguida, você modificará o conteúdo do arquivo com lineinfile e blockinfile, e gerará um MOTD personalizado usando o módulo ansible.builtin.template. O laboratório também abrange a criação de links simbólicos, a verificação de estados de arquivo com stat, a recuperação de logs com fetch e a limpeza de arquivos gerenciados, fornecendo uma visão abrangente das capacidades de gerenciamento de arquivos do Ansible.
Copiar um Arquivo Estático e Definir Atributos com o Módulo ansible.builtin.copy
Nesta etapa, você aprenderá a usar um dos módulos Ansible mais fundamentais: ansible.builtin.copy. Este módulo é usado para transferir arquivos do seu nó de controle (a VM LabEx) para um local especificado em seus hosts gerenciados. Em nosso caso, o host gerenciado será o próprio localhost. Além de simplesmente copiar, o módulo copy permite controlar precisamente os atributos do arquivo, como seu proprietário, grupo e modo de permissão, o que é essencial para a configuração adequada do sistema.
Primeiro, vamos configurar nosso ambiente de projeto. Todo o nosso trabalho será feito dentro do diretório ~/project.
Navegue até o diretório do projeto e crie um subdiretório para nossos arquivos de origem. Esta é uma prática comum para manter seu projeto organizado.
Instale o pacote
ansible-core.sudo dnf install -y ansible-coreEm seguida, navegue até o diretório do projeto e crie um subdiretório para nossos arquivos de origem.
cd ~/project mkdir filesEm seguida, crie um arquivo de texto simples que copiaremos. Usaremos um comando
catcom um "here document" para criar o arquivoinfo.txtdentro do diretóriofiles.cat << EOF > ~/project/files/info.txt This file was deployed by Ansible. It contains important system information. EOFAgora, crie um arquivo de inventário Ansible. O inventário informa ao Ansible quais hosts gerenciar. Para este laboratório, gerenciaremos a máquina local. Crie um arquivo chamado
inventory.ini.cat << EOF > ~/project/inventory.ini localhost ansible_connection=local EOFNeste inventário,
localhosté o host que estamos visando. A variávelansible_connection=localinstrui o Ansible a executar as tarefas diretamente no nó de controle, sem usar SSH.Crie seu primeiro playbook Ansible. Este playbook conterá as instruções para copiar o arquivo. Use
nanooucatpara criar um arquivo chamadocopy_file.yml.nano ~/project/copy_file.ymlAdicione o seguinte conteúdo ao arquivo. Este playbook define uma tarefa: copiar
info.txtpara o diretório/tmp/e definir seus atributos.--- - name: Deploy a static file to localhost hosts: localhost tasks: - name: Copy info.txt and set attributes ansible.builtin.copy: src: files/info.txt dest: /tmp/info.txt owner: labex group: labex mode: "0640"Vamos detalhar os parâmetros na tarefa
copy:src: files/info.txt: O caminho para o arquivo de origem no nó de controle, relativo à localização do playbook.dest: /tmp/info.txt: O caminho absoluto onde o arquivo será colocado no host gerenciado.owner: labex: Define o proprietário do arquivo como o usuáriolabex.group: labex: Define o grupo do arquivo como o grupolabex.mode: '0640': Define as permissões do arquivo.0640significa que o proprietário pode ler/escrever, o grupo pode ler e os outros não têm permissões.
Execute o playbook usando o comando
ansible-playbook. O sinalizador-iespecifica nosso arquivo de inventário.ansible-playbook -i inventory.ini copy_file.ymlVocê deverá ver uma saída indicando a execução bem-sucedida do playbook, semelhante a esta:
PLAY [Deploy a static file to localhost] *************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Copy info.txt and set attributes] **************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Finalmente, verifique se o arquivo foi copiado corretamente e possui os atributos corretos. Use o comando
ls -lpara verificar as permissões, proprietário e grupo.ls -l /tmp/info.txtA saída deve mostrar que
labexé o proprietário e grupo, e as permissões são-rw-r-----.-rw-r----- 1 labex labex 72 Jul 10 14:30 /tmp/info.txtVocê também pode visualizar o conteúdo do arquivo para garantir que ele foi copiado completamente.
cat /tmp/info.txtThis file was deployed by Ansible. It contains important system information.
Você usou com sucesso o módulo ansible.builtin.copy para implantar um arquivo e configurar seus atributos em seu sistema local.
Modificar Conteúdo de Arquivo com lineinfile e blockinfile
Nesta etapa, você aprenderá a modificar arquivos existentes em um host gerenciado sem substituir o arquivo inteiro. O Ansible fornece módulos poderosos para esse fim: ansible.builtin.lineinfile para gerenciar linhas únicas e ansible.builtin.blockinfile para gerenciar blocos de texto com várias linhas. Estes são extremamente úteis para tarefas como alterar configurações ou adicionar entradas a arquivos de log.
Continuaremos trabalhando com o arquivo info.txt que você criou na etapa anterior, localizado em /tmp/info.txt.
Primeiro, certifique-se de estar no diretório do projeto.
cd ~/projectCrie um novo playbook chamado
modify_file.yml. Este playbook conterá duas tarefas: uma para adicionar uma linha única e outra para adicionar um bloco de texto ao nosso arquivo existente.nano ~/project/modify_file.ymlAdicione o seguinte conteúdo ao seu playbook
modify_file.yml. Este playbook tem como alvolocalhoste usa tantolineinfilequantoblockinfilepara anexar conteúdo a/tmp/info.txt.--- - name: Modify an existing file hosts: localhost tasks: - name: Add a single line of text to a file ansible.builtin.lineinfile: path: /tmp/info.txt line: This line was added by the lineinfile module. state: present - name: Add a block of text to an existing file ansible.builtin.blockinfile: path: /tmp/info.txt block: | ## BEGIN ANSIBLE MANAGED BLOCK This block of text consists of two lines. They have been added by the blockinfile module. ## END ANSIBLE MANAGED BLOCK state: presentVamos examinar os módulos usados:
ansible.builtin.lineinfile: Este módulo garante que uma linha específica esteja presente em um arquivo. Se a linha já existir, o Ansible não faz nada, tornando a tarefa idempotente.path: O arquivo a ser modificado.line: A linha de texto que deve estar no arquivo.state: present: Isso garante que a linha exista. Você poderia usarstate: absentpara removê-la.
ansible.builtin.blockinfile: Este módulo gerencia um bloco de texto, cercado por linhas de marcador (por exemplo,## BEGIN ANSIBLE MANAGED BLOCK). Isso é ideal para gerenciar seções de configuração.path: O arquivo a ser modificado.block: A string de várias linhas a ser inserida. O|é sintaxe YAML para um bloco literal, preservando novas linhas.state: present: Garante que o bloco exista.
Execute o playbook usando o comando
ansible-playbooke seu arquivoinventory.ini.ansible-playbook -i inventory.ini modify_file.ymlA saída mostrará que ambas as tarefas fizeram alterações no arquivo.
PLAY [Modify an existing file] ************************************************* TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Add a single line of text to a file] ************************************* changed: [localhost] TASK [Add a block of text to an existing file] ********************************* changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Finalmente, verifique as alterações visualizando o conteúdo de
/tmp/info.txt.cat /tmp/info.txtVocê deverá ver o conteúdo original, seguido pela nova linha e o novo bloco de texto.
This file was deployed by Ansible. It contains important system information. This line was added by the lineinfile module. ## BEGIN ANSIBLE MANAGED BLOCK This block of text consists of two lines. They have been added by the blockinfile module. ## END ANSIBLE MANAGED BLOCKSe você executar o playbook novamente, o Ansible relatará
ok=3echanged=0porque o conteúdo já está presente, demonstrando a natureza idempotente desses módulos.
Gerar um MOTD Personalizado com o Módulo ansible.builtin.template
Nesta etapa, você avançará da cópia de arquivos estáticos para a geração de arquivos dinâmicos usando o módulo ansible.builtin.template. Este módulo utiliza o motor de templates Jinja2 para criar arquivos personalizados com variáveis e informações do sistema, conhecidas como "fatos" (facts), que o Ansible coleta de seus hosts gerenciados. Criaremos uma Mensagem do Dia (MOTD) dinâmica que exibe informações específicas do sistema.
Primeiro, certifique-se de estar no diretório
~/projecte crie um subdiretório dedicado para seus templates. É uma prática recomendada padrão do Ansible armazenar templates Jinja2 em um diretóriotemplates.cd ~/project mkdir templatesEm seguida, crie o arquivo de template Jinja2. Este arquivo,
motd.j2, conterá a estrutura do nosso MOTD, com placeholders para dados dinâmicos. A extensão.j2é uma convenção comum para templates Jinja2.nano ~/project/templates/motd.j2Adicione o seguinte conteúdo ao arquivo. Observe a sintaxe
{{ ... }}, que denota um placeholder para uma variável ou fato.################################################################# ## Welcome to {{ ansible_facts['fqdn'] }} # ## This is a {{ ansible_facts['distribution'] }} system. ## System managed by Ansible. # ## For support, contact: {{ admin_email }} #################################################################Neste template:
{{ ansible_facts['fqdn'] }}será substituído pelo Nome de Domínio Totalmente Qualificado (Fully Qualified Domain Name) do host.{{ ansible_facts['distribution'] }}será substituído pelo nome da distribuição Linux (por exemplo, RedHat).{{ admin_email }}é uma variável personalizada que definiremos em nosso playbook.
Agora, crie um novo playbook chamado
template_motd.yml. Este playbook usará o template para gerar/etc/motd.nano ~/project/template_motd.ymlAdicione o seguinte conteúdo. Este playbook requer privilégios elevados (
become: true) para escrever no diretório/etc. Ele também define a variável personalizadaadmin_email.--- - name: Deploy a custom MOTD from a template hosts: localhost become: true vars: admin_email: admin@labex.io tasks: - name: Generate /etc/motd from template ansible.builtin.template: src: templates/motd.j2 dest: /etc/motd owner: root group: root mode: "0644"Parâmetros chave neste playbook:
become: true: Isso informa ao Ansible para usarsudopara executar a tarefa, o que é necessário para escrever em/etc/motd.vars: Esta seção é onde definimos variáveis personalizadas, comoadmin_email.ansible.builtin.template: O módulo que processa o template Jinja2.srcaponta para nosso arquivo.j2, edesté o arquivo de destino no host gerenciado.
Execute o playbook.
ansible-playbook -i inventory.ini template_motd.ymlA saída deve confirmar que a tarefa foi bem-sucedida.
PLAY [Deploy a custom MOTD from a template] ************************************ TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Generate /etc/motd from template] **************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Verifique o resultado. Verifique o conteúdo do arquivo
/etc/motdrecém-gerado.cat /etc/motdVocê verá a saída renderizada, com os placeholders Jinja2 substituídos por fatos reais do sistema e a variável personalizada que você definiu. O
fqdncorresponderá ao nome do host do seu ambiente de laboratório.################################################################# ## Welcome to host.labex.io # ## This is a RedHat system. ## System managed by Ansible. # ## For support, contact: admin@labex.io #################################################################
Você agora usou com sucesso um template para criar um arquivo personalizado, uma habilidade central na automação de infraestrutura.
Implantar Arquivos de Suporte e Criar um Link Simbólico com copy e file
Nesta etapa, você combinará seu conhecimento do módulo copy com um novo e versátil módulo: ansible.builtin.file. Enquanto copy é para transferir conteúdo, file é usado para gerenciar o estado de arquivos, diretórios e links simbólicos no host gerenciado. Você o usará para criar diretórios, definir permissões e, o mais importante para este exercício, criar links simbólicos.
Nosso cenário é configurar as mensagens de pré-login exibidas pelo sistema. Em muitos sistemas Linux, /etc/issue é mostrado a usuários de terminal locais, e /etc/issue.net é mostrado a usuários remotos (como via SSH). Implantaremos um único arquivo issue e, em seguida, criaremos um link simbólico para que /etc/issue.net aponte para /etc/issue, garantindo que eles sempre exibam a mesma mensagem.
Primeiro, certifique-se de estar no diretório
~/projecte crie o arquivo de origem para nossa mensagem de issue. Colocaremos este arquivo no subdiretóriofilesque você criou anteriormente.cd ~/project cat << EOF > ~/project/files/issue Authorized access only. All connections are logged and monitored. EOFCrie um novo playbook chamado
deploy_issue.yml. Este playbook conterá duas tarefas: uma para copiar o arquivoissuee outra para criar o link simbólico.nano ~/project/deploy_issue.ymlAdicione o seguinte conteúdo ao seu playbook
deploy_issue.yml. Este playbook requer privilégios elevados (become: true) para gerenciar arquivos no diretório/etc/.--- - name: Configure system issue files hosts: localhost become: true tasks: - name: Copy custom /etc/issue file ansible.builtin.copy: src: files/issue dest: /etc/issue owner: root group: root mode: "0644" - name: Ensure /etc/issue.net is a symlink to /etc/issue ansible.builtin.file: src: /etc/issue dest: /etc/issue.net state: link force: yesVamos analisar a nova tarefa
ansible.builtin.file:src: /etc/issue: Quandostateélink,srcespecifica o arquivo para o qual o link simbólico deve apontar.dest: /etc/issue.net: Este é o caminho onde o próprio link simbólico será criado.state: link: Este parâmetro crucial informa ao módulofilepara criar um link simbólico, não um arquivo ou diretório regular.force: yes: Esta é uma opção útil que garante a idempotência. Se/etc/issue.netjá existir como um arquivo regular, o Ansible o removerá e criará o link. Semforce: yes, o playbook falharia nessa situação.
Execute o playbook.
ansible-playbook -i inventory.ini deploy_issue.ymlA saída mostrará ambas as tarefas fazendo alterações com sucesso.
PLAY [Configure system issue files] ******************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Copy custom /etc/issue file] ********************************************* changed: [localhost] TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ************************ changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Verifique o resultado usando o comando
ls -l. Este comando fornece uma listagem detalhada que mostra claramente os links simbólicos.ls -l /etc/issue /etc/issue.netA saída deve mostrar que
/etc/issueé um arquivo regular e/etc/issue.neté um link simbólico apontando para ele. Olno início das permissões para/etc/issue.netindica que é um link.-rw-r--r--. 1 root root 65 Jul 10 15:00 /etc/issue lrwxrwxrwx. 1 root root 10 Jul 10 15:00 /etc/issue.net -> /etc/issue
Você agora implantou com sucesso um arquivo de configuração e usou o módulo ansible.builtin.file para criar um link simbólico, um padrão comum e poderoso para gerenciar configurações do sistema.
Verificar Estado do Arquivo com stat e Buscar Logs com fetch
Nesta etapa, você aprenderá sobre dois importantes módulos de coleta de dados: ansible.builtin.stat e ansible.builtin.fetch. O módulo stat é usado para verificar o status de um arquivo ou diretório em um host gerenciado — por exemplo, para ver se ele existe, quais são suas permissões ou quando foi modificado pela última vez. Ele não altera nada, tornando-o perfeito para verificações e lógica condicional. O módulo fetch faz o oposto de copy: ele recupera arquivos do host gerenciado e os salva em seu nó de controle, o que é ideal para fazer backup de configurações ou coletar arquivos de log para análise.
Criaremos um playbook que primeiro verifica a existência do arquivo /etc/motd que você criou anteriormente e, em seguida, busca o arquivo de log do gerenciador de pacotes DNF (/var/log/dnf.log) para um diretório local em sua VM LabEx.
Primeiro, certifique-se de estar no diretório
~/projecte crie um novo subdiretório para armazenar os arquivos que você buscará.cd ~/project mkdir fetched_logsCrie um novo playbook chamado
check_and_fetch.yml. Este playbook conterá as tarefas para verificar o arquivo e recuperar o log.nano ~/project/check_and_fetch.ymlAdicione o seguinte conteúdo ao seu playbook
check_and_fetch.yml. Este playbook usastatpara obter detalhes do arquivo,registerpara armazenar esses detalhes em uma variável,debugpara exibir a variável efetchpara recuperar o arquivo de log.--- - name: Check file status and fetch logs hosts: localhost become: true tasks: - name: Check if /etc/motd exists ansible.builtin.stat: path: /etc/motd register: motd_status - name: Display stat results ansible.builtin.debug: var: motd_status.stat - name: Fetch the dnf log file from managed host ansible.builtin.fetch: src: /var/log/dnf.log dest: fetched_logs/ flat: yesVamos detalhar os conceitos-chave:
register: motd_status: Este é um recurso crucial do Ansible. Ele pega toda a saída de uma tarefa e a salva em uma nova variável chamadamotd_status.ansible.builtin.debug: Este módulo é usado para imprimir valores durante a execução de um playbook. Aqui, imprimimos o objetostatdentro de nossa variável registrada (motd_status.stat) para ver as propriedades do arquivo.ansible.builtin.fetch: Este módulo recupera um arquivo do host gerenciado.src: O caminho do arquivo a ser recuperado do host gerenciado.dest: O diretório no nó de controle (sua VM LabEx) onde o arquivo será salvo.flat: yes: Por padrão,fetchcria uma estrutura de subdiretórios correspondente ao host e ao caminho de origem.flat: yessimplifica isso copiando o arquivo diretamente para o diretóriodestsem subdiretórios extras.
Execute o playbook. Como estamos lendo um arquivo de log do sistema,
become: trueé usado para obter as permissões necessárias.ansible-playbook -i inventory.ini check_and_fetch.ymlA saída mostrará os resultados da verificação
statna tarefa de depuração, seguida pela tarefafetch.PLAY [Check file status and fetch logs] **************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Check if /etc/motd exists] *********************************************** ok: [localhost] TASK [Display stat results] **************************************************** ok: [localhost] => { "motd_status.stat": { "exists": true, "gid": 0, "isreg": true, "mode": "0644", "path": "/etc/motd", ... } } TASK [Fetch the dnf log file from managed host] ******************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Verifique se o arquivo de log foi buscado com sucesso. Liste o conteúdo do diretório
fetched_logs.ls -l ~/project/fetched_logs/Você deverá ver o arquivo
dnf.log, agora armazenado localmente em seu nó de controle.total 4 -rw-r--r--. 1 labex labex 1234 Jul 10 15:30 dnf.log
Você agora aprendeu como inspecionar propriedades de arquivos sem fazer alterações e como recuperar arquivos importantes de seus sistemas gerenciados de volta para seu nó de controle.
Limpar Arquivos Gerenciados no Host com o Módulo file
Nesta etapa final, você aprenderá a usar o módulo ansible.builtin.file para garantir que arquivos e diretórios não estejam presentes em um sistema. Uma parte crítica do gerenciamento de configuração não é apenas criar e modificar recursos, mas também limpá-los. Ao definir o parâmetro state como absent, você pode instruir o Ansible a remover arquivos, links simbólicos ou até mesmo diretórios inteiros.
Para concluir este laboratório, escreveremos um único playbook de "limpeza" que remove todos os artefatos que criamos nas etapas anteriores: /tmp/info.txt, /etc/motd, /etc/issue e o link simbólico /etc/issue.net.
Primeiro, certifique-se de estar no diretório
~/project.cd ~/projectCrie um novo playbook chamado
cleanup.yml. Este playbook conterá todas as tarefas necessárias para reverter nossas alterações.nano ~/project/cleanup.ymlAdicione o seguinte conteúdo ao seu playbook
cleanup.yml. Este playbook usa uma lista de tarefas, cada uma visando um dos arquivos que criamos. Observe quebecome: trueé definido no nível do play, portanto, todas as tarefas serão executadas com privilégios elevados.--- - name: Clean up managed files from the system hosts: localhost become: true tasks: - name: Remove the temporary info file ansible.builtin.file: path: /tmp/info.txt state: absent - name: Remove the custom MOTD file ansible.builtin.file: path: /etc/motd state: absent - name: Remove the custom issue file ansible.builtin.file: path: /etc/issue state: absent - name: Remove the issue.net symbolic link ansible.builtin.file: path: /etc/issue.net state: absentA chave para este playbook é o parâmetro
state: absentem cada tarefa. Isso informa ao módulofilepara garantir que o item nopathespecificado não exista. Se ele encontrar o arquivo, ele o removerá. Se o arquivo já tiver sido removido, ele não fará nada, mantendo a idempotência.Execute o playbook de limpeza.
ansible-playbook -i inventory.ini cleanup.ymlA saída mostrará que cada tarefa fez uma alteração bem-sucedida ao remover um arquivo.
PLAY [Clean up managed files from the system] ********************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Remove the temporary info file] ****************************************** changed: [localhost] TASK [Remove the custom MOTD file] ********************************************* changed: [localhost] TASK [Remove the custom issue file] ******************************************** changed: [localhost] TASK [Remove the issue.net symbolic link] ************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Verifique se os arquivos foram removidos. Você pode usar o comando
lspara verificar sua existência. O comando relatará que não pode acessá-los porque eles não existem mais.ls /tmp/info.txt /etc/motd /etc/issue /etc/issue.netA saída esperada é uma série de erros, confirmando que a limpeza foi bem-sucedida.
ls: cannot access '/tmp/info.txt': No such file or directory ls: cannot access '/etc/motd': No such file or directory ls: cannot access '/etc/issue': No such file or directory ls: cannot access '/etc/issue.net': No such file or directory
Você agora usou com sucesso o Ansible para remover arquivos e limpar um sistema, completando o ciclo de vida completo do gerenciamento de arquivos, desde a criação até a exclusão.
Resumo
Neste laboratório, você aprendeu os fundamentos do gerenciamento de arquivos em sistemas RHEL usando Ansible. Você começou usando o módulo ansible.builtin.copy para transferir um arquivo estático para um host gerenciado, definindo propriedade e permissões específicas. Em seguida, explorou como modificar arquivos existentes garantindo que uma linha específica esteja presente com lineinfile e gerenciando blocos de texto de várias linhas com blockinfile. Uma habilidade chave abordada foi a geração de conteúdo de arquivo dinâmico usando o módulo ansible.builtin.template e a sintaxe Jinja2 para criar uma Mensagem do Dia (MOTD) personalizada, preenchida com fatos do sistema.
Além disso, você praticou a implantação de arquivos de suporte e a criação de links simbólicos usando o módulo ansible.builtin.file. Para garantir que suas implantações fossem bem-sucedidas, você usou o módulo stat para verificar o estado e os atributos dos arquivos e o módulo fetch para recuperar arquivos, como logs, do host gerenciado de volta para o nó de controle. Finalmente, você aprendeu como realizar operações de limpeza usando o módulo file com state: absent para remover os arquivos e diretórios criados durante o laboratório, garantindo um estado limpo no host gerenciado.


