Open britho opened 3 years ago
Neste exercício, você criará, instalará, editará e removerá arquivos em hosts gerenciados e gerenciará as permissões, a propriedade e os contextos do SELinux desses arquivos.
Resultados
Você deverá ser capaz de:
Recuperar arquivos de hosts gerenciados, por nome do host, e armazená-los localmente.
Criar playbooks que usam módulos comuns de gerenciamento de arquivos, como copy
, file
, lineinfile
e blockinfile
.
Faça login na workstation
como student
usando a senha student
.
Na workstation
, execute o comando lab file-manage start. O script cria o diretório de projeto file-manage
e faz download dos arquivos de configuração e de inventário de host do Ansible necessários para o exercício.
[student@workstation ~]$
lab file-manage start
Em workstation
, como usuário student
, acesse o diretório de trabalho /home/student/file-manage
. Crie um playbook chamado secure_log_backups.yml
no diretório de trabalho atual. Configure o playbook para usar o módulo fetch
para recuperar o arquivo de log /var/log/secure
de cada um dos hosts gerenciados e armazená-los no nó de controle. O playbook deve criar o diretório secure-backups
com subdiretórios com o nome do host de cada host gerenciado.
Armazene os arquivos de backup em seus respectivos subdiretórios.
Navegue até o diretório de trabalho /home/student/file-manage
.
[student@workstation ~]$
cd ~/file-manage
[student@workstation file-manage]$
Crie o playbook secure_log_backups.yml
com o conteúdo inicial:
--- - name: Use the fetch module to retrieve secure log files hosts: all remote_user: root
Adicione uma tarefa ao playbook secure_log_backups.yml
que recupere o arquivo de log /var/log/secure
dos hosts gerenciados e os armazene no diretório ~/file-manage/secure-backups
. O módulo fetch
cria o diretório ~/file-manage/secure-backups
se ele ainda não existir. Use o parâmetro flat: no
para garantir o comportamento padrão de anexar o nome do host, o caminho e o nome do arquivo ao destino:
tasks: - name: Fetch the /var/log/secure log file from managed hosts fetch: src: /var/log/secure dest: secure-backups flat: no
Antes de executar o playbook, execute o comando ansible-playbook --syntax-check secure_log_backups.yml para verificar sua sintaxe. Corrija os erros antes de passar para a próxima etapa.
[student@workstation file-manage]$
ansible-playbook --syntax-check \
>
secure_log_backups.yml
playbook: secure_log_backups.yml
Execute o comando ansible-playbook secure_log_backups.yml para executar o playbook:
[student@workstation file-manage]$
ansible-playbook secure_log_backups.yml
PLAY [Use the fetch module to retrieve secure log files] ****************** TASK [Gathering Facts] **************************************************** ok: [servera.lab.example.com] ok: [serverb.lab.example.com] TASK [Fetch the /var/log/secure file from managed hosts] ****************** changed: [serverb.lab.example.com] changed: [servera.lab.example.com] PLAY RECAP **************************************************************** servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Verifique os resultados do playbook:
[student@workstation file-manage]$
tree -F secure-backups
secure-backups ├── servera.lab.example.com/ │ └── var/ │ └── log/ │ └──secure
└── serverb.lab.example.com/ └── var/ └── log/ └──secure
Crie o playbook copy_file.yml
no diretório de trabalho atual. Configure o playbook para copiar o arquivo /home/student/file-manage/files/users.txt
em todos os hosts gerenciados como o usuário root.
Adicione o seguinte conteúdo inicial ao playbook copy_file.yml
:
--- - name: Using the copy module hosts: all remote_user: root
Adicione uma tarefa para usar o módulo copy
para copiar o arquivo /home/student/file-manage/files/users.txt
para todos os hosts gerenciados. Use o módulo copy
para definir os seguintes parâmetros para o arquivo users.txt
:
tasks: - name: Copy a file to managed hosts and set attributes copy: src: files/users.txt dest: /home/devops/users.txt owner: devops group: devops mode: u+rw,g-wx,o-rwx setype: samba_share_t
Use o comando ansible-playbook --syntax-check copy_file.yml para verificar a sintaxe do playbook copy_file.yml
.
[student@workstation file-manage]$
ansible-playbook --syntax-check copy_file.yml
playbook: copy_file.yml
Execute o playbook:
[student@workstation file-manage]$
ansible-playbook copy_file.yml
PLAY [Using the copy module] ******************************************* TASK [Gathering Facts] ************************************************* ok: [serverb.lab.example.com] ok: [servera.lab.example.com] TASK [Copy a file to managed hosts and set attributes] ***************** changed: [servera.lab.example.com] changed: [serverb.lab.example.com] PLAY RECAP ************************************************************* servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Use um comando ad hoc para executar o comando ls -Z como usuário devops
para verificar os atributos do arquivo users.txt
nos hosts gerenciados.
[student@workstation file-manage]$
ansible all -m command -a 'ls -Z' -u devops
servera.lab.example.com | CHANGED | rc=0 >> unconfined_u:object_r:samba_share_t
:s0 users.txt serverb.lab.example.com | CHANGED | rc=0 >> unconfined_u:object_r:samba_share_t
:s0 users.txt
Em uma etapa anterior, o campo do tipo do SELinux samba_share_t
foi definido para o arquivo users.txt
. No entanto, agora foi determinado que os valores padrão devem ser definidos para o contexto do arquivo do SELinux.
Crie um playbook chamado selinux_defaults.yml
no diretório de trabalho atual. Configure o playbook para usar o módulo file
para garantir o contexto padrão do SELinux nos campos user
, role
, type
e level
.
No mundo real, você também editaria o copy_file.yml
e removeria a palavra-chave setype
.
Crie o playbook selinux_defaults.yml
:
--- - name: Using the file module to ensure SELinux file context hosts: all remote_user: root tasks: - name: SELinux file context is set to defaults file: path: /home/devops/users.txt seuser: _default serole: _default setype: _default selevel: _default
Use o comando ansible-playbook --syntax-check selinux_defaults.yml para verificar a sintaxe do playbook selinux_defaults.yml
.
[student@workstation file-manage]$
ansible-playbook --syntax-check \
>
selinux_defaults.yml
playbook: selinux_defaults.yml
Execute o playbook:
[student@workstation file-manage]$
ansible-playbook selinux_defaults.yml
PLAY [Using the file module to ensure SELinux file context] ************ TASK [Gathering Facts] ************************************************* ok: [serverb.lab.example.com] ok: [servera.lab.example.com] TASK [SELinux file context is set to defaults] ************************* changed: [serverb.lab.example.com] changed: [servera.lab.example.com] PLAY RECAP ************************************************************* servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Use um comando ad hoc para executar o comando ls -Z como usuário devops
para verificar os atributos do arquivo padrão de unconfined_u:object_r:user_home_t:s0
.
[student@workstation file-manage]$
ansible all -m command -a 'ls -Z' -u devops
servera.lab.example.com | CHANGED | rc=0 >> unconfined_u:object_r:user_home_t
:s0 users.txt serverb.lab.example.com | CHANGED | rc=0 >> unconfined_u:object_r:user_home_t
:s0 users.txt
Crie um playbook chamado add_line.yml
no diretório de trabalho atual. Configure o playbook para usar o módulo lineinfile
a fim de anexar a linha This line was added by the lineinfile module.
ao arquivo /home/devops/users.txt
em todos os hosts gerenciados.
Crie o playbook add_line.yml
:
--- - name: Add text to an existing file hosts: all remote_user: devops tasks: - name: Add a single line of text to a file lineinfile: path: /home/devops/users.txt line: This line was added by the lineinfile module. state: present
Use o comando ansible-playbook --syntax-check add_line.yml para verificar a sintaxe do playbook add_line.yml
.
[student@workstation file-manage]$
ansible-playbook --syntax-check add_line.yml
playbook: add_line.yml
Execute o playbook:
[student@workstation file-manage]$
ansible-playbook add_line.yml
PLAY [Add text to an existing file] ************************************ TASK [Gathering Facts] ************************************************* ok: [serverb.lab.example.com] ok: [servera.lab.example.com] TASK [Add a single line of text to a file] ***************************** changed: [servera.lab.example.com] changed: [serverb.lab.example.com] PLAY RECAP ************************************************************* servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Como usuário devops
, use o módulo command
com a opção cat para verificar o conteúdo do arquivo users.txt
nos hosts gerenciados.
[student@workstation file-manage]$
ansible all -m command \
>
-a 'cat users.txt' -u devops
serverb.lab.example.com | CHANGED | rc=0 >> This line was added by the lineinfile module. servera.lab.example.com | CHANGED | rc=0 >> This line was added by the lineinfile module.
Crie um playbook chamado add_block.yml
no diretório de trabalho atual. Configure o playbook para usar o módulo blockinfile
a fim de acrescentar o seguinte bloco de texto ao arquivo /home/devops/users.txt
em todos os hosts gerenciados.
This block of text consists of two lines. They have been added by the blockinfile module.
Crie o playbook add_block.yml
:
--- - name: Add block of text to a file hosts: all remote_user: devops tasks: - name: Add a block of text to an existing file blockinfile: path: /home/devops/users.txt block: | This block of text consists of two lines. They have been added by the blockinfile module. state: present
Use o comando ansible-playbook --syntax-check add_block.yml para verificar a sintaxe do playbook add_block.yml
.
[student@workstation file-manage]$
ansible-playbook --syntax-check add_block.yml
playbook: add_block.yml
Execute o playbook:
[student@workstation file-manage]$
ansible-playbook add_block.yml
PLAY [Add block of text to a file] **************************************** TASK [Gathering Facts] **************************************************** ok: [serverb.lab.example.com] ok: [servera.lab.example.com] TASK [Add a block of text to an existing file] **************************** changed: [servera.lab.example.com] changed: [serverb.lab.example.com] PLAY RECAP **************************************************************** servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Use o módulo command
com o comando cat para verificar o conteúdo correto do arquivo /home/devops/users.txt
no host gerenciado.
[student@workstation file-manage]$
ansible all -m command \
>
-a 'cat users.txt' -u devops
serverb.lab.example.com | CHANGED | rc=0 >> 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 BLOCK servera.lab.example.com | CHANGED | rc=0 >> 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 BLOCK
Crie um playbook chamado remove_file.yml
no diretório de trabalho atual. Configure o playbook para usar o módulo file
a fim de remover o arquivo /home/devops/users.txt
de todos os hosts gerenciados.
Crie o playbook remove_file.yml
:
--- - name: Use the file module to remove a file hosts: all remote_user: devops tasks: - name: Remove a file from managed hosts file: path: /home/devops/users.txt state: absent
Use o comando ansible-playbook --syntax-check remove_file.yml para verificar a sintaxe do playbook remove_file.yml
.
[student@workstation file-manage]$
ansible-playbook --syntax-check remove_file.yml
playbook: remove_file.yml
Execute o playbook:
[student@workstation file-manage]$
ansible-playbook remove_file.yml
PLAY [Use the file module to remove a file] ******************************* TASK [Gathering Facts] **************************************************** ok: [serverb.lab.example.com] ok: [servera.lab.example.com] TASK [Remove a file from managed hosts] *********************************** changed: [serverb.lab.example.com] changed: [servera.lab.example.com] PLAY RECAP **************************************************************** servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Use um comando ad hoc para executar o comando ls -l para confirmar se o arquivo users.txt
não existe mais nos hosts gerenciados.
[student@workstation file-manage]$
ansible all -m command -a 'ls -l'
serverb.lab.example.com | CHANGED | rc=0 >> total 0 servera.lab.example.com | CHANGED | rc=0 >> total 0
Isso conclui o exercício orientado.
Objetivos
Depois de concluir esta seção, os alunos deverão ser capazes de usar templates Jinja2 para implantar arquivos personalizados em hosts gerenciados. Transformação de arquivos em templates
O RedHat Ansible Engine tem vários módulos que podem ser usados para modificar os arquivos existentes. Eles incluem lineinfile e blockinfile, entre outros. No entanto, nem sempre são fáceis de usar de forma eficaz e correta.
Uma maneira muito mais poderosa de gerenciar arquivos é transformá-los em template. Com esse método, você pode gravar um template do arquivo de configuração, que é personalizado automaticamente para o host gerenciado quando o arquivo é implantado, usando variáveis e fatos Ansible. Esse método pode ser mais fácil de controlar e é menos propenso a erros. Introdução ao Jinja2
O Ansible usa o sistema de templates Jinja2 para arquivos de template. O Ansible também usa a sintaxe Jinja2 para fazer referência a variáveis nos playbooks, então você já sabe um pouco sobre como usá-la.
Uso de delimitadores
As variáveis e expressões lógicas são colocadas entre tags ou delimitadores. Por exemplo, os templates Jinja2 usam {%EXPR%} para expressões ou lógica (por exemplo, loops), enquanto {{EXPR}} são usados para a saída de resultados de uma expressão ou uma variável para o usuário final. A última tag, quando renderizada, é substituída por um valor ou por valores e é vista pelo usuário final. Use a sintaxe para incluir comentários que não devem aparecer no arquivo final.
No exemplo a seguir, a primeira linha inclui um comentário que não será incluído no arquivo final. As referências a variáveis na segunda linha são substituídas pelos valores dos fatos do sistema que estão sendo referenciados.
{# /etc/hosts line #} {{ ansible_facts['default_ipv4']['address'] }} {{ ansible_facts['hostname'] }}
Gerar um template Jinja2
Um template Jinja2 é composto de diversos elementos: dados, variáveis e expressões. Essas variáveis e expressões são substituídas por seus valores quando o template Jinja2 é renderizado. As variáveis usadas no template podem ser especificadas na seção vars do playbook. É possível usar fatos de hosts gerenciados como variáveis em um modelo.
Lembre-se de que os fatos associados a um host gerenciado podem ser obtidos com o comando ansible system_hostname -i inventory_file -m setup.
O exemplo a seguir mostrar como criar um template para /etc/ssh/sshd_config com variáveis e fatos recuperados de hosts gerenciados pelo Ansible. Quando o playbook associado for executado, os fatos serão substituídos por seus valores no host gerenciado que está sendo configurado.
Um arquivo que contém um template Jinja2 não precisa ter uma extensão de arquivo específica (por exemplo, .j2). No entanto, fornecer essa extensão pode facilitar a memorização de que se trata de um template de arquivo.
Port {{ ssh_port }} ListenAddress {{ ansible_facts['default_ipv4']['address'] }}
HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
PermitRootLogin {{ root_allowed }} AllowGroups {{ groups_allowed }}
AuthorizedKeysFile /etc/.rht_authorized_keys .ssh/authorized_keys
PasswordAuthentication {{ passwords_allowed }}
ChallengeResponseAuthentication no
GSSAPIAuthentication yes GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes UsePrivilegeSeparation sandbox
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE AcceptEnv XMODIFIERS
Subsystem sftp /usr/libexec/openssh/sftp-server
Implantação de templates Jinja2
Os templates Jinja2 são uma excelente ferramenta para personalizar arquivos de configuração que serão implantados em hosts gerenciados. Quando o template Jinja2 de um arquivo de configuração tiver sido criado, ele poderá ser implantado nos hosts gerenciados usando o módulo template, que permite a transferência de um arquivo local do nó de controle para os hosts gerenciados.
Para usar o módulo template, utilize a sintaxe a seguir. O valor associado à chave src especifica o template Jinja2 de origem, e o valor associado à chave dest especifica o arquivo a ser criado nos hosts de destino.
tasks:
O módulo template também permite que você especifique o proprietário (o usuário que é proprietário do arquivo), o grupo, as permissões e o contexto do SELinux do arquivo implantado, assim como o módulo file. Também é possível usar a opção validate para executar um comando arbitrário (como visudo -c) para verificar se a sintaxe de um arquivo está correta antes de copiá-lo.
Para obter mais detalhes, consulte ansible-doc template. Gerenciamento de arquivos transformados em templates
Para evitar que os administradores de sistema modifiquem os arquivos implantados pelo Ansible, é recomendável incluir um comentário na parte superior do template para indicar que o arquivo não deve ser editado manualmente.
Uma maneira de fazer isso é usar a string Ansible managed definida na diretiva ansible_managed. Ela não é uma variável normal, mas pode ser usada como uma em um template. A diretiva ansible_managed é definida no arquivo ansible.cfg:
ansible_managed = Ansible managed
Para incluir a variável ansible_managed em um template Jinja2, use a seguinte sintaxe:
{{ ansible_managed }}
Estruturas de controle
Você pode usar estruturas de controle do Jinja2 em templates de arquivos para reduzir a digitação repetitiva, inserir entradas para cada host em uma ação de forma dinâmica ou inserir um texto condicionalmente em um arquivo.
Uso de loops
O Jinja2 usa a instrução for para criar o recurso de looping. No exemplo a seguir, a variável user é substituída por todos os valores incluídos na variável users, sendo um valor por linha.
{% for user in users %} {{ user }} {% endfor %}
O exemplo de template a seguir usa a instrução for para executar todos os valores na variável users, substituindo myuser por cada valor, exceto quando o valor for root.
{# for statement #} {% for myuser in users if not myuser == "root" %} User number {{ loop.index }} - {{ myuser }} {% endfor %}
A variável loop.index vai até o número de índice em que o loop se encontra atualmente. Ele tem o valor 1 na primeira vez em que é executado e incrementa em 1 a cada nova iteração.
Em outro exemplo, este template também usa a instrução for e presume que a variável myhosts tenha sido definida no arquivo de inventário que está sendo utilizado. Essa variável deve conter uma lista dos hosts a serem gerenciados. Com a instrução for a seguir, todos os hosts do grupo myhosts do inventário serão listados no arquivo.
{% for myhost in groups['myhosts'] %} {{ myhost }} {% endfor %}
Para ver um exemplo mais prático, você pode usar isso para gerar um arquivo /etc/hosts a partir dos fatos do host de maneira dinâmica. Imagine que você tem este playbook:
O template templates/hosts.j2 de três linhas a seguir constrói o arquivo com todos os hosts do grupo all. (A linha do meio é extremamente longa no template devido ao comprimento dos nomes das variáveis). Ele itera em cada host do grupo para obter três fatos para o arquivo /etc/hosts.
{% for host in groups['all'] %} {{ hostvars['host']['ansible_facts']['default_ipv4']['address'] }} {{ hostvars['host']['ansible_facts']['fqdn'] }} {{ hostvars['host']['ansible_facts']['hostname'] }} {% endfor %}
Uso de condicionais
O Jinja2 usa a instrução if para proporcionar controle de condicionais. Isso permite que você coloque uma linha em um arquivo implantado se determinadas condições forem atendidas.
No exemplo a seguir, o valor da variável result será incluído no arquivo implantado somente se o valor da variável finished for True.
{% if finished %} {{ result }} {% endif %}
Você pode usar loops e condicionais do Jinja2 em templates do Ansible, mas não em playbooks do Ansible. Filtros de variáveis
O Jinja2 oferece filtros que alteram o formato de saída para expressões do template (por exemplo, para JSON). Existem filtros disponíveis para as linguagens, como YAML e JSON. O filtro to_json formata a saída da expressão usando JSON, e o filtro to_yaml formata a saída da expressão usando YAML.
{{ output | to_json }} {{ output | to_yaml }}
Filtros adicionais estão disponíveis, como os filtros to_nice_json e to_nice_yaml, que formatam a saída da expressão em formato legível tanto JSON quanto YAML.
{{ output | to_nice_json }} {{ output | to_nice_yaml }}
Os filtros from_json e from_yaml esperam strings em formato JSON ou YAML, respectivamente, para analisá-las.
{{ output | from_json }} {{ output | from_yaml }}
Testes de variáveis
As expressões usadas com cláusulas when nos playbooks do Ansible são expressões Jinja2. Os testes incorporados do Ansible usados para testar valores devolvidos incluem failed, changed, succeeded e skipped. A tarefa a seguir mostra como os testes podem ser usados dentro de expressões condicionais.
tasks: ...output omitted...
template - Templates a file out to a remote server — Ansible Documentation
Variables — Ansible Documentation
Filters — Ansible Documentation
Neste exercício, você criará um arquivo de template simples que seu playbook usará para instalar um arquivo personalizado da Mensagem do Dia em cada host gerenciado.
Resultados
Você deverá ser capaz de:
Gerar um arquivo de modelo.
Usar o arquivo de template em um playbook.
Faça login na workstation como student usando a senha student.
Na workstation, execute o comando lab file-template start. Esse script confirma se o Ansible está instalado na workstation, cria o diretório /home/student/file-template e faz o download do arquivo ansible.cfg nesse diretório.
[student@workstation ~]$ lab file-template start
Todos os arquivos usados durante este exercício estão disponíveis para referência na workstation no diretório /home/student/file-template/files.
Na workstation, navegue até o diretório de trabalho /home/student/file-template. Crie o arquivo inventory no diretório de trabalho atual. Esse arquivo configura dois grupos: webservers e workstations. Inclua o sistema servera.lab.example.com no grupo webservers e o sistema workstation.lab.example.com no grupo workstations.
[webservers]
servera.lab.example.com
[workstations]
workstation.lab.example.com
Crie um template para a Mensagem do Dia e a inclua no arquivo motd.j2 no diretório de trabalho atual. Inclua as seguintes variáveis e fatos no template:
ansible_facts['fqdn'], para inserir o FQDN do host gerenciado.
ansible_facts['distribution'] e ansible_facts['distribution_version'], para fornecer informações de distribuição.
system_owner, para o e-mail do proprietário do sistema. Essa variável precisa ser definida com um valor adequado na seção vars do template do playbook.
This is the system {{ ansible_facts['fqdn'] }}.
This is a {{ ansible_facts['distribution'] }} version {{ ansible_facts['distribution_version'] }} system.
Only use this system with permission.
You can request access from {{ system_owner }}.
Crie um arquivo de playbook chamado motd.yml no diretório de trabalho atual. Defina a variável system_owner na seção vars e inclua uma tarefa para o módulo template, que mapeia o template Jinja2 motd.j2 para o arquivo remoto /etc/motd nos hosts gerenciados. Defina o proprietário e o grupo como root e o modo como 0644.
---
- name: configure SOE
hosts: all
remote_user: devops
become: true
vars:
- system_owner: clyde@example.com
tasks:
- name: configure /etc/motd
template:
src: motd.j2
dest: /etc/motd
owner: root
group: root
mode: 0644
Antes de executar o playbook, use o comando ansible-playbook --syntax-check para verificar a sintaxe. Se ela relatar algum erro, corrija-o antes de ir para a próxima etapa. Você verá uma saída semelhante à seguinte:
[student@workstation file-template]$ ansible-playbook --syntax-check motd.yml
playbook: motd.yml
Execute o playbook motd.yml.
[student@workstation file-template]$ ansible-playbook motd.yml
PLAY [all] ******************************************************************
TASK [Gathering Facts] ******************************************************
ok: [servera.lab.example.com]
ok: [workstation.lab.example.com]
TASK [template] *************************************************************
changed: [servera.lab.example.com]
changed: [workstation.lab.example.com]
PLAY RECAP ******************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
workstation.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Faça login em servera.lab.example.com com o usuário devops para verificar se o MOTD é exibido corretamente após o login. Faça logout quando terminar.
[student@workstation file-template]$ ssh devops@servera.lab.example.com
This is the system servera.lab.example.com.
This is a RedHat version 8.0 system.
Only use this system with permission.
You can request access from clyde@example.com.
...output omitted...
[devops@servera ~]# exit
Connection to servera.lab.example.com closed.
Encerramento
Execute o comando lab file-template finish para limpar após o exercício.
[student@workstation ~]$ lab file-template finish
Isso conclui o exercício orientado.
Lista de verificação de desempenho
Neste laboratório, você executará um playbook para criar um arquivo personalizado em seus hosts gerenciados usando o template Jinja2.
Resultados
Você deverá ser capaz de:
Gerar um arquivo de modelo.
Usar o arquivo de template em um playbook.
Faça login na workstation como student usando a senha student.
Na workstation, execute o comando lab file-review start. Isso confirma se o Ansible está instalado na workstation, cria o diretório /home/student/file-review e faz o download do arquivo ansible.cfg nesse diretório. Ele também faz o download dos arquivos motd.yml, motd.j2, issue e inventory para o diretório /home/student/file-review/files.
[student@workstation ~]$ lab file-review start
Todos os arquivos usados neste exercício estão disponíveis na workstation no diretório /home/student/file-review/files.
Crie um arquivo de inventário chamado inventory no diretório /home/student/file-review. Esse arquivo de inventário define o grupo servers, que tem o host gerenciado serverb.lab.example.com associado a ele.
Em workstation, acesse o diretório /home/student/file-review.
[student@workstation ~]$ cd ~/file-review/
Crie o arquivo inventory no diretório atual. Esse arquivo configura um grupo chamado servers. Inclua o sistema serverb.lab.example.com no grupo servers.
[servers]
serverb.lab.example.com
Identifique os fatos do serverb.lab.example.com que mostram a quantidade total de memória do sistema e o número de processadores.
Use o módulo setup para obter uma lista de todos os fatos do host gerenciado serverb.lab.example.com. Os fatos ansible_processor_count e ansible_memtotal_mb apresentam informações sobre os limites de recursos do host gerenciado.
[student@workstation file-review]$ ansible serverb.lab.example.com -m setup serverb.lab.example.com | SUCCESS => { "ansible_facts": { ...output omitted... "ansible_processor_count": 1, ...output omitted... "ansible_memtotal_mb": 821, ...output omitted... }, "changed": false }
Crie um template para a Mensagem do Dia, chamado motd.j2, no diretório atual. Quando o usuário devops fizer login em serverb.lab.example.com, deverá ser exibida uma mensagem mostrando a memória total do sistema e a contagem dos processadores. Use os fatos ansible_facts['memtotal_mb'] e ansible_facts['processor_count'] para fornecer as informações de memória para a mensagem.
System total memory: {{ ansible_facts['memtotal_mb'] }} MiB. System processor count: {{ ansible_facts['processor_count'] }}
Crie um novo arquivo de playbook chamado motd.yml no diretório atual. Usando o módulo template, configure o arquivo de template do Jinja2 motd.j2 criado anteriormente para que seja mapeado para o arquivo /etc/motd nos hosts gerenciados. Esse arquivo tem o usuário root como proprietário e grupo, e suas permissões são 0644. Usando os módulos stat e debug, crie tarefas para verificar se /etc/motd existe nos hosts gerenciados e exibe as informações do arquivo para /etc/motd . Use o módulo copy para colocar files/issue no diretório /etc/ do host gerenciado e use a mesma propriedade e permissões do /etc/motd. Use o módulo file para garantir que /etc/issue.net é um link simbólico para /etc/issue no host gerenciado. Configure o playbook para que ele utilize o usuário devops e defina o parâmetro become como true.
name: Configure system hosts: all remote_user: devops become: true tasks:
name: Configure a custom /etc/motd template: src: motd.j2 dest: /etc/motd owner: root group: root mode: 0644
name: Check file exists stat: path: /etc/motd register: motd
name: Display stat results debug: var: motd
name: Copy custom /etc/issue file copy: src: files/issue dest: /etc/issue owner: root group: root mode: 0644
name: Ensure /etc/issue.net is a symlink to /etc/issue file: src: /etc/issue dest: /etc/issue.net state: link owner: root group: root force: yes
Execute o playbook incluído no arquivo motd.yml.
Antes de executar o playbook, use o comando ansible-playbook --syntax-check para verificar sua sintaxe. Se ela relatar algum erro, corrija-o antes de ir para a próxima etapa. Você verá uma saída semelhante à seguinte:
[student@workstation file-review]$ ansible-playbook --syntax-check motd.yml
playbook: motd.yml
Execute o playbook incluído no arquivo motd.yml.
[student@workstation file-review]$ ansible-playbook motd.yml
PLAY [Configure system] ****************************************************
TASK [Gathering Facts] *****************************************************
ok: [serverb.lab.example.com]
TASK [Configure a custom /etc/motd] ****************************************
changed: [serverb.lab.example.com]
TASK [Check file exists] ***************************************************
ok: [serverb.lab.example.com]
TASK [Display stat results] ************************************************
ok: [serverb.lab.example.com] => {
"motd": {
"changed": false,
"failed": false,
...output omitted...
TASK [Copy custom /etc/issue file] *****************************************
changed: [serverb.lab.example.com]
TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ********************
changed: [serverb.lab.example.com]
PLAY RECAP *****************************************************************
serverb.lab.example.com : ok=6 changed=3 unreachable=0 failed=0
Verifique se o playbook incluído no arquivo motd.yml foi executado corretamente.
Faça login em serverb.lab.example.com com o usuário devops e verifique se o conteúdo de /etc/motd e /etc/issue é exibido ao fazer login. Faça logout quando terminar.
[student@workstation file-review]$ ssh devops@serverb.lab.example.com ------------------------------- PRIVATE SYSTEM -----------------------------
Last login: Thu Apr 25 22:09:33 2019 from 172.25.250.9 [devops@serverb ~]$ logout
Avaliação
Na workstation, execute o script lab file-review grade para confirmar a conclusão com êxito deste exercício.
[student@workstation ~]$ lab file-review grade
Encerramento
Na workstation, execute o script lab file-review finish para limpar o laboratório.
[student@workstation ~]$ lab file-review finish
Isso conclui o exercício orientado.
Neste capítulo, você aprendeu que:
A biblioteca de módulos Files inclui módulos que permitem realizar a maioria das tarefas relacionadas ao gerenciamento de arquivos, como criar, copiar, editar e modificar permissões e outros atributos de arquivos.
Você pode usar templates Jinja2 para construir dinamicamente arquivos para implantação.
Geralmente, um template Jinja2 é composto por dois elementos: variáveis e expressões. Essas variáveis e expressões são substituídas por valores quando o template Jinja2 é renderizado.
Os filtros do Jinja2 transformam expressões do template de um tipo ou formato de dados para outro.
Objetivos
Depois de concluir esta seção, você deverá ser capaz de criar, instalar, editar e remover arquivos em hosts gerenciados, além de gerenciar permissões, propriedade, contexto do SELinux e outras características desses arquivos.
Descrição dos módulos de arquivos
O RedHat Ansible Engine é fornecido com uma grande coleção de módulos (a biblioteca de módulos) desenvolvidos como parte do projeto upstream do Ansible. Para facilitar a organização, a documentação e o gerenciamento, eles são organizados em grupos com base na função da documentação e em quando são instalados em um sistema.
A biblioteca de módulos
Files
inclui módulos que permitem realizar a maioria das tarefas relacionadas ao gerenciamento de arquivos do Linux, como criar, copiar, editar e modificar permissões e outros atributos de arquivos. A seguinte tabela fornece uma lista dos módulos de gerenciamento de arquivos usados com frequência:Exemplos de automação com módulos de arquivos
Criar, copiar, editar e remover arquivos em hosts gerenciados são tarefas comuns que você pode implementar usando módulos da biblioteca de módulos
Files
. Os exemplos a seguir mostram maneiras de usar esses módulos para automatizar tarefas comuns de gerenciamento de arquivos.Certificação de que um arquivo existe nos hosts gerenciados
Use o módulo
file
para usar o comando touch em um arquivo nos hosts gerenciados. Ele funciona da mesma forma que o comando touch: se o arquivo não existir, será criado um arquivo vazio; se ele já existir, seu horário de modificação será atualizado. Neste exemplo, além de fazer tocar no arquivo, o Ansible verifica se o usuário proprietário, o grupo e as permissões do arquivo estão definidos com valores específicos.Exemplo de resultado:
Modificação de atributos dos arquivos
Você pode usar o módulo
file
para garantir que um arquivo novo ou existente tenha as permissões corretas ou também o tipo SELinux.Por exemplo, o arquivo a seguir reteve o contexto do SELinux padrão relativo ao diretório pessoal de um usuário, que não é o contexto desejado.
A tarefa a seguir assegura que o atributo de tipo de contexto do SELinux do arquivo
samba_file
seja o tiposamba_share_t
desejado. Esse comportamento é semelhante ao do comando chcon do Linux.Exemplo de resultado:
Os parâmetros de atributos de arquivo estão disponíveis em vários módulos de gerenciamento de arquivos. Execute os comandos ansible-doc file e ansible-doc copy para obter informações adicionais.
Mudanças persistentes no contexto do SELinux de arquivos
O módulo
file
atua como chcon ao definir contextos de arquivos. As alterações feitas com esse módulo podem ser desfeitas inesperadamente executando restorecon. Depois de usarfile
para definir o contexto, você pode usarsefcontext
da coleção de módulosSystem
para atualizar a política do SELinux parasemanage fcontext.Exemplo de resultado:
O módulo
sefcontext
atualiza o contexto padrão para o destino na política do SELinux, mas não altera o contexto nos arquivos existentes.Cópia e edição de arquivos em hosts gerenciados
Neste exemplo, o módulo
copy
é usado para copiar um arquivo localizado no diretório de trabalho do Ansible nó de controle para hosts gerenciados selecionados.Por padrão, esse módulo presume que
force: yes
está definido. Esse comando forçará o módulo a substituir o arquivo remoto se ele existir e tiver conteúdo diferente do arquivo que está sendo copiado. Seforce: no
estiver definido, o comando copiará o arquivo para o host gerenciado apenas se ele ainda não existir.Para recuperar arquivos de hosts gerenciados, use o módulo
fetch
. Isso pode ser usado para recuperar um arquivo, como uma chave pública SSH, de um sistema de referência antes de distribuí-lo para outros hosts gerenciados.Para garantir que exista uma única linha de texto específica em um arquivo existente, use o módulo
lineinfile
:Para adicionar um bloco de texto a um arquivo existente, use o módulo
blockinfile
:Ao usar o módulo
blockinfile
, marcadores de bloco comentados são inseridos no início e no final do bloco para garantir a idempotência.Você pode usar o parâmetro
marker
no módulo para garantir que o texto ou o caractere de comentário correto esteja sendo usado para o arquivo em questão.Remoção de um arquivo dos hosts gerenciados
Um exemplo básico de como remover um arquivo dos hosts gerenciados é usar o módulo
file
com o parâmetrostate: absent
. O parâmetrostate
é opcional em muitos módulos. Você deve sempre deixar claro se querstate: present
oustate: absent
por várias razões. Alguns módulos também dão suporte a outras opções. É possível que o padrão mude em algum momento, mas talvez o mais importante seja facilitar a compreensão do estado em que o sistema deve estar com base em sua tarefa.Recuperação do status de um arquivo em hosts gerenciados
O módulo
stat
recupera fatos de um arquivo, semelhante ao comando stat do Linux. Os parâmetros fornecem a funcionalidade para recuperar atributos de arquivo, determinar a soma de verificação de um arquivo, entre outras ações.O módulo
stat
retorna um dicionário de hash de valores que contêm os dados de status do arquivo, permitindo que você se refira a partes individuais das informações usando variáveis separadas.O exemplo a seguir registra os resultados de um módulo
stat
e imprime a soma de verificação MD5 do arquivo que ele verificou. (O algoritmo SHA256 mais moderno também está disponível; o MD5 está sendo usado aqui para facilitar a legibilidade.)A saída será semelhante à seguinte:
As informações sobre os valores retornados pelo módulo
stat
são documentadas por ansible-doc, ou você pode registrar uma variável e exibir seu conteúdo para ver o que está disponível:Sincronização de arquivos entre o nó de controle e os hosts gerenciados
O módulo
synchronize
é um wrapper que envolve a ferramenta rsync, simplificando as tarefas comuns de gerenciamento de arquivos em seus playbooks. A ferramenta rsync deve ser instalada tanto no host local quanto no remoto. Por padrão, ao usar o módulosynchronize
, o local host é o host em que a tarefa de sincronização se origina (geralmente, o nó de controle), e o destination host é o host ao qual osynchronize
se conecta.O exemplo a seguir sincroniza um arquivo localizado no diretório de trabalho do Ansible com os hosts gerenciados:
Há muitas maneiras de usar o módulo
synchronize
e seus muitos parâmetros, inclusive sincronizar diretórios. Execute o comando ansible-doc synchronize para obter mais parâmetros e exemplos de playbooks.Páginas de manual ansible-doc(1), chmod(1), chown(1), rsync(1), stat(1) e touch(1)
Módulos de arquivos