Open britho opened 3 years ago
Neste exercício você configurará um novo repositório Yum e instalará pacotes dele nos seus hosts gerenciados.
Resultados
Você deverá ser capaz de:
Configurar um repositório yum usando o módulo yum_repository
.
Gerenciar chaves GPG do RPM usando o módulo rpm_key
.
Obter informações sobre os pacotes instalados em um host usando o módulo package_facts
.
Na workstation
, execute o
script de início do laboratório para confirmar se o ambiente está pronto
para que o laboratório comece. O script cria o diretório de
trabalho, chamado de system-software
, e o preenche com um arquivo de configuração do Ansible, um inventário de host e arquivos de laboratório.
[student@workstation ~]$
lab system-software start
Visão geral do cenário
Sua organização exige que todos os hosts tenham o pacote example-motd instalado. Esse pacote é fornecido por um repositório Yum interno mantido pela sua organização para hospedar pacotes de software desenvolvidos internamente.
Você está encarregado de escrever um playbook para garantir que o pacote example-motd está instalado no host remoto. O playbook deve garantir a configuração do repositório Yum interno.
O repositório está localizado em http://materials.example.com/yum/repository
.
Todos os pacotes do RPM são assinados com um par de chaves GPG
organizacional. A chave pública GPG está disponível em http://materials.example.com/yum/repository/RPM-GPG-KEY-example
.
Na workstation
, como o usuário student
, acesse o diretório de trabalho /home/student/system-software
.
[student@workstation ~]$
cd ~/system-software
[student@workstation system-software]$
Comece a escrever o playbook repo_playbook.yml
. Defina uma única ação no playbook que tenha como destino todos os hosts. Adicione uma cláusula vars
que defina uma única variável custom_pkg
com um valor de example-motd
. Adicione a cláusula tasks
ao playbook.
O playbook agora contém:
--- - name: Repository Configuration hosts: all vars: custom_pkg: example-motd tasks:
Adicione duas tarefas ao playbook.
Use o módulo package_facts
na primeira tarefa para reunir informações sobre os pacotes instalados no host remoto. Essa tarefa preenche o fato ansible_facts.packages
.
Use o módulo debug
na segunda tarefa para imprimir a versão instalada do pacote referenciado pela variável custom_pkg
. Só execute essa tarefa se o pacote personalizado for encontrado no fato ansible_facts.packages
.
Execute o playbook repo_playbook.yml
.
Adicione a primeira tarefa ao playbook. Configure a palavra-chave manager
do módulo package_facts
com um valor de auto
. A primeira tarefa contém o seguinte:
- name: Gather Package Facts package_facts: manager: auto
Adicione uma segunda tarefa ao playbook que usa o módulo debug
para exibir o valor da variável ansible_facts.packages[custom_pkg]
. Adicione uma cláusula when
à tarefa para verificar se o valor da variável custom_pkg
está contida na variável ansible_facts.packages
. A segunda tarefa contém o seguinte:
- name: Show Package Facts for the custom package debug: var: ansible_facts.packages[custom_pkg] when: custom_pkg in ansible_facts.packages
Execute o playbook:
[student@workstation system-software]$
ansible-playbook repo_playbook.yml
PLAY [Repository Configuration] ********************************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Gather Package Facts] ************************************************** ok: [servera.lab.example.com] TASK [Show Package Facts for the custom package] ***************************** skipping: [servera.lab.example.com] PLAY RECAP ******************************************************************* servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
A tarefa de depuração é ignorada porque o pacote example-motd não está instalado no host remoto.
Adicione uma terceira tarefa que usa o módulo yum_repository
para garantir a configuração do repositório yum interno no host remoto. Certifique-se de que:
A configuração do repositório está armazenada no arquivo /etc/yum.repos.d/example.repo
A ID do repositório é example-internal
O URL de base é http://materials.example.com/yum/repository
O repositório está configurado para verificar as assinaturas GPG do RPM
A descrição do repositório é Example Inc. Internal YUM repo
A terceira tarefa contém o seguinte:
- name: Ensure Example Repo exists yum_repository: name: example-internal description: Example Inc. Internal YUM repo file: example baseurl: http://materials.example.com/yum/repository/ gpgcheck: yes
Adicione uma quarta tarefa à ação que use o módulo rpm_key
para garantir que a chave pública do repositório esteja presente no
host remoto. O URL da chave pública do repositório é http://materials.example.com/yum/repository/RPM-GPG-KEY-example
.
A quarta tarefa aparece conforme segue:
- name: Ensure Repo RPM Key is Installed rpm_key: key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example state: present
Adicione uma quinta tarefa para garantir que o pacote referenciado pela variável custom_pkg
está instalado no host remoto.
A quinta tarefa aparece conforme segue:
- name: Install Example motd package yum: name: "{{ custom_pkg }}" state: present
O fato ansible_facts.packages
não é atualizado quando um novo pacote é instalado em um host remoto.
Copie a segunda tarefa e adicione-a como a sexta tarefa da ação. Execute o playbook e verifique se o fato ansible_facts.packages
não contém informações sobre o example-motd instalado no host remoto.
A sexta tarefa contém uma cópia da segunda tarefa:
- name: Show Package Facts for the custom package debug: var: ansible_facts.packages[custom_pkg] when: custom_pkg in ansible_facts.packages
Agora, todo o playbook aparecerá conforme segue:
--- - name: Repository Configuration hosts: all vars: custom_pkg: example-motd tasks: - name: Gather Package Facts package_facts: manager: auto - name: Show Package Facts for the custom package debug: var: ansible_facts.packages[custom_pkg] when: custom_pkg in ansible_facts.packages - name: Ensure Example Repo exists yum_repository: name: example-internal description: Example Inc. Internal YUM repo file: example baseurl: http://materials.example.com/yum/repository/ gpgcheck: yes - name: Ensure Repo RPM Key is Installed rpm_key: key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example state: present - name: Install Example motd package yum: name: "{{ custom_pkg }}" state: present - name: Show Package Facts for the custom package debug: var: ansible_facts.packages[custom_pkg] when: custom_pkg in ansible_facts.packages
Execute o playbook.
[student@workstation system-software]$
ansible-playbook repo_playbook.yml
PLAY [Repository Configuration] ********************************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Gather Package Facts] ************************************************** ok: [servera.lab.example.com]TASK [Show Package Facts for the custom package] ***************************** skipping: [servera.lab.example.com] TASK [Ensure Example Repo exists] ******************************************** changed: [servera.lab.example.com] TASK [Ensure Repo RPM Key is Installed] ************************************** changed: [servera.lab.example.com] TASK [Install Example motd package] ****************************************** changed: [servera.lab.example.com] TASK [Show Package Facts for the custom package] ***************************** skipping: [servera.lab.example.com]
PLAY RECAP ******************************************************************* servera.lab.example.com : ok=5 changed=3 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Insira uma tarefa imediatamente após a tarefa Install Example motd package
usando o módulo package_facts
para atualizar os fatos do pacote. Defina a palavra-chave do módulo manager
com um valor auto
.
O playbook completo é mostrado abaixo:
---
- name: Repository Configuration
hosts: all
vars:
custom_pkg: example-motd
tasks:
- name: Gather Package Facts
package_facts:
manager: auto
- name: Show Package Facts for the custom package
debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages
- name: Ensure Example Repo exists
yum_repository:
name: example-internal
description: Example Inc. Internal YUM repo
file: example
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes
- name: Ensure Repo RPM Key is Installed
rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present
- name: Install Example motd package
yum:
name: "{{ custom_pkg }}"
state: present
- name: Gather Package Facts
package_facts:
manager: auto
- name: Show Package Facts for the custom package
debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages
Use um comando ad hoc do Ansible para remover o pacote example-motd instalado durante a execução anterior do playbook. Execute o playbook com a tarefa package_facts
inserida e use a saída para verificar a instalação do pacote example-motd.
Para remover o pacote example-motd de todos os hosts, use o comando ansible all com as opções -m yum
e -a 'name=example-motd state=absent'
.
[student@workstation system-software]$
ansible all -m yum \
>
-a 'name=example-motd state=absent'
servera.lab.example.com | CHANGED => { ...output omitted... "changed": true, "msg": "", "rc": 0, "results": [ "Removed: example-motd-1.0-1.el7.x86_64" ] ...output omitted...
Execute o playbook.
[student@workstation system-software]$
ansible-playbook repo_playbook.yml
PLAY [Repository Configuration] ********************************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Gather Package Facts] ************************************************** ok: [servera.lab.example.com] TASK [Show Package Facts for the custom package] ***************************** skipping: [servera.lab.example.com]...output omitted... TASK [Install Example motd package] ****************************************** changed: [servera.lab.example.com]
TASK [Gather Package Facts] ************************************************** ok: [servera.lab.example.com]
TASK [Show Package Facts for example-motd] *********************************** ok: [servera.lab.example.com] => { "ansible_facts.packages[custom_pkg]": [
{ "arch": "x86_64", "epoch": null, "name": "example-motd", "release": "1.el7", "source": "rpm", "version": "1.0" } ] } PLAY RECAP ******************************************************************* servera.lab.example.com : ok=7 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Isso conclui o exercício orientado.
Depois de concluir esta seção, você deverá ser capaz de:
Provisionar várias contas de usuário em vários servidores.
Gerenciar usuários e grupos do Linux, configurar SSH e modificar a configuração do Sudo em hosts gerenciados.
O módulo user do Ansible permite gerenciar contas de usuário em um host remoto. Você pode gerenciar vários parâmetros, incluindo remoção de usuário, definição de diretório pessoal, definição da UID de contas do sistema, gerenciamento de senhas e agrupamentos associados. Para criar um usuário que possa fazer login na máquina, você precisa fornecer uma senha com hash para o parâmetro de senha. Consulte a seção de referência para obter um link para "How do I generate encrypted passwords for the user module?"
Exemplo do módulo user
- name: Add new user to the development machine and assign the appropriate groups. user: name: devops_usershell: /bin/bash
groups: sys_admins, developers
append: yes
Ao criar um usuário, você pode especificá-lo com generate_ssh_key
. Isso não
substituirá uma chave SSH existente.
Exemplo de geração de chave SSH pelo módulo user
- name: Create a SSH key for user1 user: name: user1 generate_ssh_key: yes ssh_key_bits: 2048 ssh_key_file: .ssh/id_my_rsa
O módulo user também oferece alguns valores de retorno. Os módulos do Ansible podem obter um valor de retorno e registrá-lo em uma variável. Saiba mais com o ansible-doc e no site de doc principal.
O módulo group
permite que você gerencie (adicione, exclua, modifique) grupos nos hosts gerenciados. Você precisa ter groupadd
, groupdel
ou groupmod
. Para destinos do Windows, use o módulo win_group
.
Exemplo do módulo group
- name: Verify that auditors group exists group: name: auditors state: present
Se você tiver um grande número de chaves de host para gerenciar, use o módulo known_hosts
. O módulo known_hosts
permite adicionar ou remover chaves de host do arquivo known_hosts no host gerenciado.
Exemplo de tarefas do known_host
- name: copy host keys to remote servers known_hosts: path: /etc/ssh/ssh_known_hosts name: user1 key: "{{ lookup('file', 'pubkeys/user1') }}"
O módulo authorized_key
permite adicionar ou remover chaves SSH autorizadas por contas de
usuário. Ao adicionar e subtrair usuários em um grande banco de
servidores, você precisa ser capaz de gerenciar chaves SSH.
Exemplo de tarefas do authorized_key
- name: Set authorized key authorized_key: user: user1 state: present key: "{{ lookup('file', '/home/user1/.ssh/id_rsa.pub') }}
Neste exercício, você criará vários usuários em seus hosts gerenciados e preencherá as chaves SSH autorizadas para eles.
Resultados
Você deverá ser capaz de:
Criar um novo grupo de usuários.
Gerenciar usuários com o módulo user.
Preencher as chaves SSH autorizadas usando o módulo authorized_key.
Modificar os arquivos sudoers e sshd_config usando o módulo lineinfile.
Na workstation, execute o script de início do laboratório para confirmar se o ambiente está pronto para que o laboratório comece. O script cria o diretório de trabalho, chamado de system-users, e o preenche com um arquivo de configuração do Ansible, um inventário de host e alguns arquivos de laboratório.
[student@workstation ~]$ lab system-users start
Visão geral do cenário
Sua organização exige que todos os hosts tenham os mesmos usuários locais disponíveis. Esses usuários devem pertencer ao grupo de usuários webadmin, que tem a capacidade de usar o comando sudo sem especificar uma senha. Além disso, as chaves públicas SSH dos usuários devem ser distribuídas no ambiente e o usuário root não deve ter permissão para fazer login usando SSH diretamente.
Você está encarregado de escrever um playbook para garantir que os usuários e o grupo de usuários estejam presentes no host remoto. O playbook deve garantir que os usuários possam fazer login usando a chave SSH autorizada, bem como usar sudo sem especificar uma senha, e que o usuário root não possa fazer login diretamente usando SSH.
Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-users.
[student@workstation ~]$ cd ~/system-users
[student@workstation system-users]$
Dê uma olhada no arquivo vars/users_vars.yml existente da variável.
[student@workstation system-users]$ cat vars/users_vars.yml
---
users:
- username: user1
groups: webadmin
- username: user2
groups: webadmin
- username: user3
groups: webadmin
- username: user4
groups: webadmin
- username: user5
groups: webadmin
Ele usa o nome da variável username para definir o nome de usuário correto e a variável groups para definir grupos adicionais aos quais o usuário deve pertencer.
Comece a escrever o users.yml playbook. Defina uma única ação no playbook que tenha como destino o grupo de hosts webservers. Adicione uma cláusula vars_files que defina a localização do nome de arquivo vars/users_vars.yml, que foi criado para você, e contém todos os nomes de usuário necessários para este exercício. Adicione a cláusula tasks ao playbook.
Use um editor de texto para criar o playbook users.yml. O playbook deve conter o seguinte:
---
- name: Create multiple local users
hosts: webservers
vars_files:
- vars/users_vars.yml
tasks:
Adicione duas tarefas ao playbook.
Use o módulo group na primeira tarefa para criar o grupo de usuários webadmin no host remoto. Esta tarefa cria o grupo webadmin.
Use o módulo user na segunda tarefa para criar os usuários do arquivo vars/users_vars.yml.
Execute o playbook users.yml.
Adicione a primeira tarefa ao playbook. A primeira tarefa contém o seguinte:
- name: Add webadmin group
group:
name: webadmin
state: present
Adicione uma segunda tarefa ao playbook que usa o módulo user para criar os usuários. Adicione uma cláusula loop: "{{ users }}" à tarefa para fazer loop no arquivo de variável para cada nome de usuário encontrado no arquivo vars/users_vars.yml. Como name: para os usuários, use item.username como o nome da variável. Isso permite que o arquivo de variável contenha informações adicionais que podem ser úteis para criar usuários, como os grupos aos quais eles devem pertencer. A segunda tarefa contém o seguinte:
- name: Create user accounts
user:
name: "{{ item.username }}"
groups: webadmin
loop: "{{ users }}"
Execute o playbook:
[student@workstation system-users]$ ansible-playbook users.yml
PLAY [Create multiple local users] *******************************************
TASK [Gathering Facts] *******************************************************
ok: [servera.lab.example.com]
TASK [Add webadmin group] ****************************************************
changed: [servera.lab.example.com]
TASK [Create user accounts] **************************************************
changed: [servera.lab.example.com] => (item={u'username': u'user1', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user2', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user3', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user4', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user5', u'groups': u'webadmin'})
PLAY RECAP *******************************************************************
servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0
Adicione uma terceira tarefa que use o módulo authorized_key para garantir que as chaves públicas SSH tenham sido adequadamente distribuídas no host remoto. No diretório files, cada um dos usuários tem um único arquivo de chave pública SSH. O módulo percorre a lista de usuários por loop, localiza a chave apropriada usando a variável username e envia a chave para o host remoto.
A terceira tarefa contém o seguinte:
- name: Add authorized keys
authorized_key:
user: "{{ item.username }}"
key: "{{ lookup('file', 'files/'+ item.username + '.key.pub') }}"
loop: "{{ users }}"
Adicione uma quarta tarefa à ação que usa o módulo copy para modificar o arquivo de configuração sudo e permitir que os membros do grupo webadmin usem sudo sem uma senha no host remoto.
A quarta tarefa aparece conforme segue:
- name: Modify sudo config to allow webadmin users sudo without a password
copy:
content: "%webadmin ALL=(ALL) NOPASSWD: ALL"
dest: /etc/sudoers.d/webadmin
mode: 0440
Adicione uma quinta tarefa para garantir que o usuário root não tenha permissão para fazer login usando SSH diretamente. Use notify: "Restart sshd" para acionar um manipulador para que reinicie o SSH.
A quinta tarefa aparece conforme segue:
- name: Disable root login via SSH
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
notify: Restart sshd
Na primeira linha após o local do arquivo da variável, inclua uma nova definição de manipulador. Dê a ele o nome Restart sshd.
O manipulador deverá ser definido assim:
...output omitted...
- vars/users_vars.yml
handlers:
- name: Restart sshd
service:
name: sshd
state: restarted
Agora, todo o playbook aparecerá conforme segue:
---
- name: Create multiple local users
hosts: webservers
vars_files:
- vars/users_vars.yml
handlers:
- name: Restart sshd
service:
name: sshd
state: restarted
tasks:
- name: Add webadmin group
group:
name: webadmin
state: present
- name: Create user accounts
user:
name: "{{ item.username }}"
groups: webadmin
loop: "{{ users }}"
- name: Add authorized keys
authorized_key:
user: "{{ item.username }}"
key: "{{ lookup('file', 'files/'+ item.username + '.key.pub') }}"
loop: "{{ users }}"
- name: Modify sudo config to allow webadmin users sudo without a password
copy:
content: "%webadmin ALL=(ALL) NOPASSWD: ALL"
dest: /etc/sudoers.d/webadmin
mode: 0440
- name: Disable root login via SSH
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
notify: "Restart sshd"
Execute o playbook.
[student@workstation system-users]$ ansible-playbook users.yml
PLAY [Create multiple local users] *******************************************
TASK [Gathering Facts] *******************************************************
ok: [servera.lab.example.com]
TASK [Add webadmin group] ****************************************************
ok: [servera.lab.example.com]
TASK [Create user accounts] **************************************************
ok: [servera.lab.example.com] => (item={u'username': u'user1', u'groups': u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user2', u'groups': u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user3', u'groups': u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user4', u'groups': u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user5', u'groups': u'webadmin'})
TASK [Add authorized keys] ***************************************************
changed: [servera.lab.example.com] => (item={u'username': u'user1', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user2', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user3', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user4', u'groups': u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user5', u'groups': u'webadmin'})
TASK [Modify sudo config to allow webadmin users sudo without a password] ***
changed: [servera.lab.example.com]
TASK [Disable root login via SSH] *******************************************
changed: [servera.lab.example.com]
RUNNING HANDLER [Restart sshd] **********************************************
changed: [servera.lab.example.com]
PLAY RECAP ******************************************************************
servera.lab.example.com : ok=7 changed=4 unreachable=0 failed=0
Como usuário user1, faça login no servidor servera usando SSH. Depois de conectado, use o comando sudo su - para alternar a identidade para o usuário root.
Use SSH como usuário user1 e faça login no servidor servera.
[student@workstation system-users]$ ssh user1@servera
Activate the web console with: systemctl enable --now cockpit.socket
[user1@servera ~]$
Alterne a identidade para o usuário root.
[user1@servera ~]$ sudo su -
Last login: Wed Dec 19 05:39:53 EST 2018 on pts/0
root@servera ~]#
Faça o logout do servidor servera.
[root@servera ~]$ exit
logout
[user1@servera ~]$ exit
logout
Connection to servera closed.
[student@workstation system-users]$
Tente fazer login no servidor servera como usuário root diretamente. Essa etapa deve apresentar falha, porque a configuração do SSH foi modificada para não permitir logins de usuário root diretos.
Em workstation, use SSH como root para fazer login no servidor servera.
[student@workstation system-users]$ ssh root@servera
root@servera's password: redhat
Permission denied, please try again.
root@servera's password:
Isso confirma que a configuração SSH negou acesso direto ao sistema para o usuário root.
Encerramento
Em workstation, execute o script lab system-users finish para limpar os recursos criados neste exercício.
[student@workstation ~]$ lab system-users finish
Isso conclui o exercício orientado.
Depois de concluir esta seção, você deverá ser capaz de gerenciar a inicialização de serviços, agendar processos com at, cron e systemd, reinicializar e controlar o destino de boot padrão em hosts gerenciados.
O agendamento rápido e único é feito com o módulo at
.
Você cria a tarefa para uma execução futura, e ela é retida até o
momento da execução. Existem seis parâmetros que acompanham esse módulo.
Eles são: command, count, script_file, state, unique e units.
Exemplo do módulo at:
- name: remove tempuser. at: command: userdel -r tempuser count: 20 units: minutes unique: yes
Ao definir uma tarefa agendada de trabalho, o módulo cron
é usado. O módulo cron anexará comandos diretamente no crontab do usuário designado.
Exemplo do módulo cron:
- cron: name: "Flush Bolt" user: "root" minute: 45 hour: 11 job: "php ./app/nut cache:clear"
Essa ação usa um comando cache:clear da empresa que imediatamente libera o cache Bolt, removendo arquivos e diretórios em cache, além de limpar o cache do servidor CMS todas as manhãs às 11:45.
O Ansible gravará a ação no crontab usando a sintaxe correta conforme a instrução do usuário.
Examinar o crontab verificará se ele foi anexado.
Alguns parâmetros comumente usados para o módulo cron são:
Para gerenciar serviços ou recarregar daemons, o Ansible tem os módulos systemd
e service. O service oferece um conjunto básico de opções para iniciar,
parar, reiniciar e ativar. O módulo systemd oferece mais opções de
configuração. O systemd permitirá que você faça um recarregamento de
daemons em casos em que o módulo service não o faz.
Exemplo do módulo service:
- name: start nginx service: name: nginx state: started"
O daemon init está sendo substituído pelo systemd. Então, em muitos casos, o systemd será a melhor opção.
Exemplo do módulo systemd:
- name: reload web server systemd: name: apache2 state: reload daemon-reload: yes
Outro módulo de sistemas do Ansible bastante usado é o reboot
. É considerado mais seguro do que usar o módulo shell para iniciar o
desligamento. Durante a execução de uma ação, o módulo reboot desligará o
host gerenciado e, em seguida, aguardará até que ele fique disponível
novamente antes de prosseguir com a ação.
Exemplo do módulo reboot:
- name: "Reboot after patching" reboot: reboot_timeout: 180 - name: force a quick reboot reboot:
Assim como os módulos service e systemd, o shell e o command podem trocar algumas tarefas. O módulo command é considerado mais seguro, mas algumas variáveis de ambiente não estão disponíveis. Além disso, os operadores de fluxo não funcionarão. Se você precisar transmitir seus comandos, o módulo shell fará isso.
Exemplo do módulo shell:
- name: Run a templated variable (always use quote filter to avoid injection) shell: cat {{ myfile|quote }}![]()
Exemplo do módulo command:
- name: This command only command: /usr/bin/scrape_logs.py arg1 arg2 args:chdir: scripts/ creates: /path/to/script
O módulo command é considerado mais seguro porque não é afetado pelo ambiente dos usuários.
A coleta de fatos no host gerenciado permitirá que você acesse as variáveis de ambiente. Há uma sublista ansible_env que contém todas as variáveis de ambiente.
--- - name: hosts: webservers vars: local_shell: "{{ ansible_env }}"tasks: - name: Printing all the environment variables in Ansible debug: msg: "{{ local_shell }}"
Neste exercício, você gerenciará o processo de inicialização, agendará tarefas recorrentes e reinicializará os hosts gerenciados.
Resultados
Você deverá ser capaz de usar um playbook para:
Agendar uma tarefa do cron.
Remover uma tarefa do cron específica de um arquivo crontab.
Agendar uma tarefa at.
Definir o destino de inicialização padrão em hosts gerenciados.
Reiniciar os hosts gerenciados.
Em workstation, execute o script lab system-process start para configurar o ambiente para o exercício. O script cria o diretório de trabalho system-process e faz o download dos arquivos de configuração e inventário de host do Ansible necessários para o exercício.
[student@workstation ~]$ lab system-process start
Em workstation, como usuário student, acesse o diretório de trabalho /home/student/system-process.
[student@workstation ~]$ cd ~/system-process
[student@workstation system-process]$
Crie um playbook, create_crontab_file.yml, no diretório de trabalho atual. Configure o playbook para usar o módulo cron para criar o arquivo crontab /etc/cron.d/add-date-time que agenda uma tarefa do cron recorrente. A tarefa deve ser executada como o usuário devops a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira. A tarefa deve anexar a data e a hora atuais ao arquivo /home/devops/my_datetime_cron_job
Crie um novo playbook, create_crontab_file.yml, e adicione as linhas necessárias para iniciar a ação. Ele deve ser direcionado ao hosts gerenciados no grupo webservers e ativar o escalonamento de privilégios.
---
- name: Recurring cron job
hosts: webservers
become: true
Defina uma tarefa que usa o módulo cron para agendar uma tarefa do cron recorrente.
O módulo cron fornece uma opção name para descrever exclusivamente a entrada do arquivo crontab e garantir os resultados esperados. A descrição é adicionada ao arquivo crontab. Por exemplo, a opção name é necessária se você estiver removendo uma entrada do crontab usando state=absent. Além disso, a opção name impede que uma nova entrada do crontab seja sempre criada quando o estado padrão, state=present, estiver definido.
tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file
Configure a tarefa para que seja executada a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira.
minute: "*/2"
hour: 9-16
weekday: 1-5
Use o parâmetro cron_file para usar o arquivo crontab /etc/cron.d/add-date-time em vez de usar o crontab de um usuário individual em /var/spool/cron/. Um caminho relativo colocará o arquivo no diretório /etc/cron.d. Se o parâmetro cron_file for usado, você também deverá especificar o parâmetro user.
user: devops
job: date >> /home/devops/my_date_time_cron_job
cron_file: add-date-time
state: present
Quando concluído, o playbook deverá ficar desta forma: Revise o playbook para garantir a precisão.
---
- name: Recurring cron job
hosts: webservers
become: true
tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file
minute: "*/2"
hour: 9-16
weekday: 1-5
user: devops
job: date >> /home/devops/my_date_time_cron_job
cron_file: add-date-time
state: present
Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check create_crontab_file.yml. Corrija os erros antes de passar para a próxima etapa.
[student@workstation system-process]$ ansible-playbook --syntax-check \
> create_crontab_file.yml
playbook: create_crontab_file.yml
Execute o playbook.
[student@workstation system-process]$ ansible-playbook create_crontab_file.yml
PLAY [Recurring cron job] *************************************************
TASK [Gathering Facts] ****************************************************
ok: [servera.lab.example.com]
TASK [Crontab file exists] ************************************************
changed: [servera.lab.example.com]
PLAY RECAP ****************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Execute um comando ad hoc para verificar se o arquivo cron /etc/cron.d/add-date-time existe e se o seu conteúdo está correto.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "cat /etc/cron.d/add-date-time"
servera.lab.example.com | CHANGED | rc=0 >>
#Ansible: Add date and time to a file
*/2 9-16 * * 1-5 devops date >> /home/devops/my_date_time_cron_job
Crie um playbook, remove_cron_job.yml, no diretório de trabalho atual. Configure o playbook para usar o módulo para remover a tarefa do cron Add date and time to a file do arquivo crontab /etc/cron.d/add-date-time
Crie um novo playbook, remove_cron_job.yml, e adicione as seguintes linhas:
---
- name: Remove scheduled cron job
hosts: webservers
become: true
tasks:
- name: Cron job removed
cron:
name: Add date and time to a file
user: devops
cron_file: add-date-time
state: absent
Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check remove_cron_job.yml. Corrija os erros antes de passar para a próxima etapa.
[student@workstation system-process]$ ansible-playbook --syntax-check \
> remove_cron_job.yml
playbook: remove_cron_job.yml
Execute o playbook.
[student@workstation system-process]$ ansible-playbook remove_cron_job.yml
PLAY [Remove scheduled cron job] ******************************************
TASK [Gathering Facts] ****************************************************
ok: [servera.lab.example.com]
TASK [Cron job removed] ***************************************************
changed: [servera.lab.example.com]
PLAY RECAP ****************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Execute um comando ad hoc para verificar se o arquivo cron /etc/cron.d/add-date-time continua existindo, mas se a tarefa do cron foi removida.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "cat /etc/cron.d/add-date-time"
servera.lab.example.com | CHANGED | rc=0 >>
Crie um playbook, schedule_at_task.yml, no diretório de trabalho atual. Configure o playbook para usar o módulo at para agendar uma tarefa que é executada um minuto no futuro. A tarefa deve executar o comando date e redirecionar sua saída para o arquivo /home/devops/my_at_date_time. Use a opção unique: yes para garantir que, se o comando já existir na fila at, uma nova tarefa não será adicionada.
Crie um novo playbook, schedule_at_task.yml, e adicione as seguintes linhas:
---
- name: Schedule at task
hosts: webservers
become: true
become_user: devops
tasks:
- name: Create date and time file
at:
command: "date > ~/my_at_date_time\n"
count: 1
units: minutes
unique: yes
state: present
Verifique a sintaxe do playbook executando o comando ansible-playbook -syntax-check schedule_at_task.yml. Corrija os erros antes de passar para a próxima etapa.
[student@workstation system-process]$ ansible-playbook --syntax-check \
> schedule_at_task.yml
playbook: schedule_at_task.yml
Execute o playbook.
[student@workstation system-process]$ ansible-playbook schedule_at_task.yml
PLAY [Schedule at task] ***************************************************
TASK [Gathering Facts] ****************************************************
ok: [servera.lab.example.com]
TASK [Create date and time file] ******************************************
changed: [servera.lab.example.com]
PLAY RECAP ****************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Depois de esperar um minuto para que o comandoat seja concluído, execute comandos ad hoc para verificar se o arquivo /home/devops/my_at_date_time existe e tem o conteúdo correto.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "ls -l my_at_date_time"
servera.lab.example.com | CHANGED | rc=0 >>
-rw-rw-r--. 1 devops devops 30 abr 17 06:15 my_at_date_time
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "cat my_at_date_time"
servera.lab.example.com | CHANGED | rc=0 >>
mié abr 17 06:15:00 EDT 2019
Crie um playbook, set_default_boot_target_graphical.yml, no diretório de trabalho atual. Configure o playbook para que use o módulo file para alterar o link simbólico em hosts gerenciados e fazer referência ao destino de inicialização graphical-target.
No módulo file a seguir, o link simbólico faz referência ao valor do parâmetro src. O valor do parâmetro dest é o link simbólico.
Crie um novo playbook, set_default_boot_target_graphical.yml, e adicione as seguintes linhas:
---
- name: Change default boot target
hosts: webservers
become: true
tasks:
- name: Default boot target is graphical
file:
src: /usr/lib/systemd/system/graphical.target
dest: /etc/systemd/system/default.target
state: link
Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check set_default_boot_target_graphical.yml. Corrija os erros antes de passar para a próxima etapa.
[student@workstation system-process]$ ansible-playbook --syntax-check \
> set_default_boot_target_graphical.yml
playbook: set_default_boot_target_graphical.yml
Antes de executar o playbook, execute um comando ad hoc para verificar se o destino de inicialização padrão atual é multi-user.target:
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
multi-user.target
Execute o playbook.
[student@workstation system-process]$ ansible-playbook \
> set_default_boot_target_graphical.yml
PLAY [Change default boot target] *****************************************
TASK [Gathering Facts] ****************************************************
ok: [servera.lab.example.com]
TASK [Default boot target is graphical] ***********************************
changed: [servera.lab.example.com]
PLAY RECAP ****************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Execute um comando ad hoc para verificar se o destino de inicialização padrão agora é graphical.target.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
graphical.target
Crie um playbook, reboot_hosts.yml, no diretório de trabalho atual que reinicialize os hosts gerenciados. Não é necessário reinicializar um servidor depois de alterar o destino padrão. No entanto, saber criar um playbook que reinicia os hosts gerenciados pode ser útil.
Crie um novo playbook, reboot_hosts.yml, e adicione as seguintes linhas:
---
- name: Reboot hosts
hosts: webservers
become: true
tasks:
- name: Hosts are rebooted
reboot:
Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check reboot_hosts.yml. Corrija os erros antes de passar para a próxima etapa.
[student@workstation system-process]$ ansible-playbook --syntax-check \
> reboot_hosts.yml
playbook: reboot_hosts.yml
Antes de executar o playbook, execute um comando ad hoc para determinar o carimbo de data/hora da última reinicialização do sistema.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "who -b"
servera.lab.example.com | CHANGED | rc=0 >>
system boot 2019-04-12 06:01
Execute o playbook.
[student@workstation system-process]$ ansible-playbook reboot_hosts.yml
PLAY [Reboot hosts] *******************************************************
TASK [Gathering Facts] ****************************************************
ok: [servera.lab.example.com]
TASK [Hosts are rebooted] *************************************************
changed: [servera.lab.example.com]
PLAY RECAP ****************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Execute um comando ad hoc para determinar o carimbo de data/hora da última reinicialização do sistema. O carimbo de data/hora exibido após a execução do playbook deve ser posterior.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "who -b"
servera.lab.example.com | CHANGED | rc=0 >>
system boot 2019-04-12 06:20
Execute um segundo comando ad hoc para determinar se a reinicialização de graphical.target sobreviveu à reinicialização.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
graphical.target
Para manter a consistência em todos os exercícios restantes, altere o destino de inicialização padrão para a configuração anterior, multi-user.target. Crie um playbook, set_default_boot_target_multi-user.yml, no diretório de trabalho atual. Configure o playbook para que use o módulo file para alterar o link simbólico em hosts gerenciados e fazer referência ao destino de inicialização multi-user.target.
Crie um novo playbook, set_default_boot_target_multi-user.yml, e adicione as seguintes linhas:
---
- name: Change default runlevel target
hosts: webservers
become: true
tasks:
- name: Default runlevel is multi-user target
file:
src: /usr/lib/systemd/system/multi-user.target
dest: /etc/systemd/system/default.target
state: link
Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check set_default_boot_target_multi-user.yml. Corrija os erros antes de passar para a próxima etapa.
[student@workstation system-process]$ ansible-playbook --syntax-check \
> set_default_boot_target_multi-user.yml
playbook: set_default_boot_target_multi-user.yml
Execute o playbook.
[student@workstation system-process]$ ansible-playbook \
> set_default_boot_target_multi-user.yml
PLAY [Change default runlevel target] *************************************
TASK [Gathering Facts] ****************************************************
ok: [servera.lab.example.com]
TASK [Default runlevel is multi-user target] ******************************
changed: [servera.lab.example.com]
PLAY RECAP ****************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Execute um comando ad hoc para verificar se o destino de boot padrão agora é multi-user.target.
[student@workstation system-process]$ ansible webservers -u devops -b \
> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
multi-user.target
Encerramento
Na workstation, execute o script lab system-process finish para limpar este exercício.
[student@workstation ~]$ lab system-process finish
Isso conclui o exercício orientado.
Depois de concluir esta seção, você deverá ser capaz de particionar dispositivos de armazenamento, configurar o LVM, formatar partições ou volumes lógicos, montar sistemas de arquivos e adicionar arquivos ou espaços de swap.
O RedHat Ansible Engine fornece uma coleção de módulos para configurar dispositivos de armazenamento em hosts gerenciados. Esses módulos são compatíveis com o particionamento de dispositivos, a criação de volumes lógicos e a criação e montagem de sistemas de arquivos.
O módulo parted
O módulo parted
dá suporte ao particionamento de dispositivos de bloco. Esse módulo inclui a funcionalidade do comando parted
e permite criar partições com um tamanho, sinalizador e alinhamento
específicos. A tabela a seguir lista alguns dos parâmetros para o
módulo parted
.
O exemplo a seguir cria uma nova partição de 10GB.
- name: New 10GB partition parted: device: /dev/vdbnumber: 1
state: present
part_end: 10GB
Os módulos lvg
e lvol
Os módulos lvg
e lvol
são compatíveis com a criação de volumes lógicos, incluindo a
configuração de volumes físicos, e grupos de volumes. O módulo lvg
toma como parâmetros os dispositivos de bloco para configurar como os
volumes físicos de back-end para o grupo de volumes. A tabela a
seguir lista alguns dos parâmetros do módulo lvg
.
A tarefa a seguir cria um grupo de volumes com um tamanho de extensão física específico usando um dispositivo de bloco como back-end.
- name: Creates a volume group lvg: vg: vg1pvs: /dev/vda1
pesize: 32
No exemplo a seguir, se o grupo de volumes vg1
já está disponível com /dev/vdb1
como um volume físico, o volume é aumentado ao adicionar um novo volume físico /dev/vdc1
.
- name: Resize a volume group lvg: vg: vg1 pvs: /dev/vdb1,/dev/vdc1
O módulo lvol
cria volumes lógicos e dá suporte ao redimensionamento e à diminuição
desses volumes e dos sistemas de arquivos acima deles. Esse módulo
também dá suporte à criação de snapshots dos volumes lógicos. A
tabela a seguir lista alguns dos parâmetros do módulo lvol
.
A tarefa a seguir cria um volume lógico de 2GB.
- name: Create a logical volume of 2GB lvol: vg: vg1lv: lv1
size: 2g
O módulo filesystem
O módulo filesystem
dá suporte à criação e ao redimensionamento de um sistema de arquivos.
Esse módulo é compatível com o redimensionamento do sistema de
arquivos para ext2
, ext3
, ext4
, ext4dev
, f2fs
, lvm
, xfs
e vfat
. A tabela a seguir lista alguns dos parâmetros do módulo filesystem
.
O exemplo a seguir cria um sistema de arquivos em uma partição.
- name: Create an XFS filesystem filesystem: fstype: xfsdev: /dev/vdb1
O módulo mount
O módulo mount
dá suporte à configuração de pontos de montagem em /etc/fstab
. A tabela a seguir lista alguns dos parâmetros do módulo mount
.
O exemplo a seguir monta um dispositivo com uma ID específica.
- name: Mount device with ID mount: path: /datasrc: UUID=a8063676-44dd-409a-b584-68be2c9f5570
fstype: xfs
state: present
O exemplo a seguir monta o compartilhamento NFS disponível em 172.25.250.100:/share
no diretório /nfsshare
no host gerenciado.
- name: Mount NFS share mount: name=/nfsshare src=172.25.250.100:/share fstype=nfs opts=defaults,nobootwait dump=0 passno=2 state=mounted
Configuração de swap com módulos
O
RedHat Ansible Engine atualmente não inclui módulos para gerenciar a
memória de swap. Para adicionar memória de swap a um sistema com o
Ansible com volumes lógicos, é necessário criar um novo grupo de
volumes e um volume lógico com os módulos lvg
e lvol
. Quando estiver pronto, é necessário formatar o novo volume lógico como swap usando o módulo command
com o comando mkswap
. Por fim, você precisa ativar o novo dispositivo de swap usando o módulo command
com o comando swapon
. O RedHat Ansible Engine tem a variável ansible_swaptotal_mb
que inclui a memória de swap total. Você pode usar essa variável
para acionar a configuração e a ativação de swap quando a memória de
swap estiver baixa. As tarefas a seguir criam um grupo de volumes e
um volume lógico para a memória de swap, formatam esse volume lógico
como swap e o ativam.
- name: Create new swap VG lvg: vg=vgswap pvs=/dev/vda1 state=present - name: Create new swap LV lvol: vg=vgswap lv=lvswap size=10g - name: Format swap LV command: mkswap /dev/vgswap/lvswap when: ansible_swaptotal_mb < 128 - name: Activate swap LV command: swapon /dev/vgswap/lvswap when: ansible_swaptotal_mb < 128
O Ansible usa fatos para recuperar informações para o nó de
controle sobre a configuração dos hosts gerenciados. Você pode usar o
módulo setup
do Ansible para recuperar todos os fatos do Ansible de um host gerenciado.
[user@controlnode ~]$
ansible webservers -m setup
host.lab.example.com | SUCCESS => { "ansible_facts": { ...output omitted... }
A opção filter
do módulo setup
é compatível com filtragem refinada baseada em curingas de estilo shell.
O elemento ansible_devices
inclui todos os dispositivos de armazenamento disponíveis no host
gerenciado. O elemento de cada dispositivo de armazenamento inclui
informações adicionais, como partições ou tamanho total. O exemplo a
seguir exibe o elemento ansible_devices
de um host gerenciado com três dispositivos de armazenamento: sr0
, vda
e vdb
.
[user@controlnode ~]$
ansible webservers -m setup -a 'filter=ansible_devices'
host.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_devices": { "sr0": { "holders": [], "host": "IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]", "links": { "ids": [ "ata-QEMU_DVD-ROM_QM00003" ], "labels": [], "masters": [], "uuids": [] }, "model": "QEMU DVD-ROM", "partitions": {}, "removable": "1", "rotational": "1", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "mq-deadline", "sectors": "2097151", "sectorsize": "512", "size": "1024.00 MB", "support_discard": "0", "vendor": "QEMU", "virtual": 1 }, "vda": { "holders": [], "host": "SCSI storage controller: Red Hat, Inc. Virtio block device", "links": { "ids": [], "labels": [], "masters": [], "uuids": [] }, "model": null, "partitions": { "vda1": { "holders": [], "links": { "ids": [], "labels": [], "masters": [], "uuids": [ "a8063676-44dd-409a-b584-68be2c9f5570" ] }, "sectors": "20969439", "sectorsize": 512, "size": "10.00 GB", "start": "2048", "uuid": "a8063676-44dd-409a-b584-68be2c9f5570" } }, "removable": "0", "rotational": "1", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "mq-deadline", "sectors": "20971520", "sectorsize": "512", "size": "10.00 GB", "support_discard": "0", "vendor": "0x1af4", "virtual": 1 }, "vdb": { "holders": [], "host": "SCSI storage controller: Red Hat, Inc. Virtio block device", "links": { "ids": [], "labels": [], "masters": [], "uuids": [] }, "model": null, "partitions": {}, "removable": "0", "rotational": "1", "sas_address": null, "sas_device_handle": null, "scheduler_mode": "mq-deadline", "sectors": "10485760", "sectorsize": "512", "size": "5.00 GB", "support_discard": "0", "vendor": "0x1af4", "virtual": 1 } } }, "changed": false }
O elemento ansible_device_links
inclui todos os links disponíveis para cada dispositivo de armazenamento. O exemplo a seguir exibe o elemento ansible_device_links
de um host gerenciado com dois dispositivos de armazenamento, sr0
e vda1
, que têm uma ID associada.
[user@controlnode ~]$
ansible webservers -m setup -a 'filter=ansible_device_links'
host.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_device_links": { "ids": { "sr0": [ "ata-QEMU_DVD-ROM_QM00003" ] }, "labels": {}, "masters": {}, "uuids": { "vda1": [ "a8063676-44dd-409a-b584-68be2c9f5570" ] } } }, "changed": false }
O elemento ansible_mounts
inclui informações sobre os dispositivos atuais montados no host
gerenciado, como o dispositivo montado, o ponto de montagem e as opções.
A saída a seguir exibe o elemento ansible_mounts
de um host gerenciado com uma montagem ativa, /dev/vda1
no diretório /
.
[user@controlnode ~]$
ansible webservers -m setup -a 'filter=ansible_mounts'
host.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_mounts": [ { "block_available": 2225732, "block_size": 4096, "block_total": 2618619, "block_used": 392887, "device": "/dev/vda1", "fstype": "xfs", "inode_available": 5196602, "inode_total": 5242304, "inode_used": 45702, "mount": "/", "options": "rw,seclabel,relatime,attr2,inode64,noquota", "size_available": 9116598272, "size_total": 10725863424, "uuid": "a8063676-44dd-409a-b584-68be2c9f5570" } ] }, "changed": false }
parted - Configure block device partitions — Ansible Documentation
lvg - Configure LVM volume groups — Ansible Documentation
lvol - Configure LVM logical volumes — Ansible Documentation
filesystem - Makes a filesystem — Ansible Documentation
mount - Control active and configured mount points — Ansible Documentation
Neste exercício, você particionará um novo disco, criará volumes lógicos e os formatará com os sistemas de arquivos XFS, montando-os imediata e automaticamente no momento da inicialização nos hosts gerenciados.
Resultados
Você deverá ser capaz de:
Usar o módulo parted
para configurar as partições de dispositivos de bloco.
Usar o módulo lvg
para gerenciar grupos de volume do LVM.
Usar o módulo lvol
para gerenciar volumes lógicos LVM.
Usar o módulo filesystem
para criar sistemas de arquivos.
Usar o módulo mount
para controlar e configurar pontos de montagem em /etc/fstab
.
Em workstation
, execute o script lab system-storage start para configurar o ambiente para o exercício. O script cria o diretório do projeto system-storage
e faz o download dos arquivos de configuração e inventário de host do Ansible necessários para o exercício.
[student@workstation ~]$
lab system-storage start
Visão geral do cenário
Você é responsável por gerenciar um conjunto de servidores da web. Uma prática recomendada para a configuração do servidor web é armazenar dados do servidor web em uma partição separada ou em um volume lógico.
Você escreverá um playbook para:
Gerenciar partições do dispositivo /dev/vdb
Gerenciar um grupo de volumes chamado apache-vg
para dados do servidor web
Criar dois volumes lógicos chamados content-lv
e logs-lv
, ambos apoiados pelo grupo de volumes apache-vg
Criar um sistema de arquivo XFS em ambos os volumes lógicos
Montar o volume lógico content-lv
em /var/www
Montar o volume lógico logs-lv
em /var/log/httpd
Se os requisitos de armazenamento para o servidor web forem alterados, atualize as variáveis apropriadas e execute o playbook novamente. O playbook deve ser idempotente.
Em workstation
, como usuário student
, acesse o diretório de trabalho /home/student/system-storage
.
[student@workstation ~]$
cd ~/system-storage
[student@workstation system-storage]$
Revise o arquivo storage.yml
do playbook do esqueleto e o arquivo storage_vars.yml
de variáveis associadas no diretório do projeto. Execute o playbook.
Revise o playbook storage.yml
.
--- - name: Ensure Apache Storage Configuration hosts: webservers vars_files: - storage_vars.yml tasks: - name: Correct partitions exist on /dev/vdb debug: msg: TODO loop: "{{ partitions }}" - name: Ensure Volume Groups Exist debug: msg: TODO loop: "{{ volume_groups }}" - name: Create each Logical Volume (LV) if needed debug: msg: TODO loop: "{{ logical_volumes }}" when: true - name: Ensure XFS Filesystem exists on each LV debug: msg: TODO loop: "{{ logical_volumes }}" - name: Ensure the correct capacity for each LV debug: msg: TODO loop: "{{ logical_volumes }}" - name: Each Logical Volume is mounted debug: msg: TODO loop: "{{ logical_volumes }}"
O nome de cada tarefa funciona como um esboço do procedimento pretendido a ser implementado. Em etapas posteriores, você atualizará e alterará essas seis tarefas.
Revise o arquivo de variáveis storage_vars.yml
.
--- partitions: - number: 1 start: 1MiB end: 257MiB volume_groups: - name: apache-vg devices: /dev/vdb1 logical_volumes: - name: content-lv size: 64M vgroup: apache-vg mount_path: /var/www - name: logs-lv size: 128M vgroup: apache-vg mount_path: /var/log/httpd
Esse arquivo
descreve a estrutura pretendida de partições, grupos de volumes e
volumes lógicos em cada servidor web. A primeira partição
começa com um deslocamento de 1 MiB desde o início do dispositivo /dev/vdb
e termina em um deslocamento de 257 MiB, com um tamanho total de 256 MiB.
Cada servidor web tem um grupo de volumes, denominado apache-vg
, que contém a primeira partição do dispositivo /dev/vdb
.
Cada servidor web tem dois volumes lógicos. O primeiro volume lógico é denominado content-lv
, com um tamanho de 64 MiB, anexado ao grupo de volumes apache-vg
e montado em /var/www
. O segundo volume lógico é denominado content-lv
, com um tamanho de 128 MiB, anexado ao grupo de volumes apache-vg
e montado em /var/log/httpd
.
O grupo de volumes apache-vg
tem uma capacidade de 256 MiB porque é apoiado pela partição /dev/vdb1
. Ele oferece capacidade suficiente para ambos os volumes lógicos.
Execute o playbook storage.yml
.
[student@workstation system-storage]$
ansible-playbook storage.yml
PLAY [Ensure Apache Storage Configuration] *********************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Correct partitions exist on /dev/vdb] ********************************** ok: [servera.lab.example.com] => (item={u'start': u'1MiB', u'end': u'257MiB', u'number': 1}) => { "msg": "TODO" } ...output omitted... TASK [Each Logical Volume is mounted] **************************************** ok: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'64M', u'mount_path': u'/var/www', u'name': u'content-lv'}) => { "msg": "TODO" } ok: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'}) => { "msg": "TODO" } PLAY RECAP ******************************************************************* servera.lab.example.com : ok=7 changed=0 unreachable=0 failed=0
Altere a primeira tarefa para usar o módulo parted
para configurar uma partição para cada item de loop. Cada item descreve uma partição pretendida do dispositivo /dev/vdb
em cada servidor web:
O número da partição. Use isso como o valor da palavra-chave number
para o módulo parted
.
O início da partição, como um deslocamento desde o
início do dispositivo de bloco. Use isso como o valor da
palavra-chave part_start
para o módulo parted
.
O final da partição, como um deslocamento desde o
início do dispositivo de bloco. Use isso como o valor da
palavra-chave part_end
para o módulo parted
.
O conteúdo da primeira tarefa deve ser:
- name: Correct partitions exist on /dev/vdb parted: device: /dev/vdb state: present number: "{{ item.number }}" part_start: "{{ item.start }}" part_end: "{{ item.end }}" loop: "{{ partitions }}"
Altere a segunda tarefa da ação para que use o módulo lvg
para configurar um grupo de volumes para cada item de loop. Cada item da variável volume_groups
descreve um grupo de volumes que deve existir em cada servidor web:
O nome do grupo de volumes. Use isso como o valor da palavra-chave vg
para o módulo lvg
.
Uma lista de dispositivos ou partições separados por
vírgulas que formam o grupo de volumes. Use isso como o
valor da palavra-chave pvs
para o módulo lvg
.
O conteúdo da segunda tarefa deve ser:
- name: Ensure Volume Groups Exist lvg: vg: "{{ item.name }}" pvs: "{{ item.devices }}" loop: "{{ volume_groups }}"
Altere a terceira tarefa da ação para que use o módulo lvol
para criar um volume lógico para cada item. Use as palavras-chave do item para criar o novo volume lógico:
O nome do volume lógico. Use isso como o valor da palavra-chave lv
para o módulo lvol
.
O nome do grupo de volumes que fornece armazenamento para o volume lógico.
O tamanho do volume lógico. O valor
dessa palavra-chave é qualquer valor aceitável para a opção -L
do comando lvcreate.
Apenas execute a tarefa se um volume lógico ainda não existir. Atualize a instrução when
para verificar se não há um volume lógico com um nome que corresponda ao valor da palavra-chave do item name
.
Altere a terceira tarefa para que use o módulo lvol
.
Defina o nome do grupo de volumes, o nome do volume
lógico e o tamanho do volume lógico usando as palavras-chave de cada
item. O conteúdo da terceira tarefa agora é:
- name: Create each Logical Volume (LV) if needed lvol: vg: "{{ item.vgroup }}" lv: "{{ item.name }}" size: "{{ item.size }}" loop: "{{ logical_volumes }}" when: true
O fato ansible_lvm
do Ansible contém informações sobre objetos do gerenciamento de volume
lógico em cada host. Use um comando ad hoc para ver o
conjunto atual de volumes lógicos no host remoto:
[student@workstation system-storage]$
ansible all -m setup -a \
>
"filter=ansible_lvm"
servera.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_lvm": { "lvs": {}, "pvs": {}, "vgs": {} }, "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false }
O valor da palavra-chave lvs
indica que não há volumes lógicos no host remoto.
Execute o playbook para criar os volumes lógicos no host remoto.
[student@workstation system-storage]$
ansible-playbook storage.yml
PLAY [Ensure Apache Storage Configuration] *********************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Correct partitions exist on /dev/vdb] ********************************** changed: [servera.lab.example.com] => (item={...output omitted...}) TASK [Ensure Volume Groups Exist] ******************************************** changed: [servera.lab.example.com] => (item={...output omitted...}) TASK [Create each Logical Volume (LV) if needed] ***************************** changed: [servera.lab.example.com] => (item={...output omitted...}) changed: [servera.lab.example.com] => (item={...output omitted...}) TASK [Ensure XFS Filesystem exists on each LV] ******************************* ok: [servera.lab.example.com] => (item={...output omitted...}) => { "msg": "TODO" } ...output omitted... PLAY RECAP ******************************************************************* servera.lab.example.com : ok=7 changed=3 unreachable=0 failed=0
Execute outro comando ad hoc para ver a estrutura da variável ansible_lvm
quando existem volumes lógicos no host remoto.
[student@workstation system-storage]$
ansible all -m setup -a \
>
"filter=ansible_lvm"
servera.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_lvm": { "lvs":{ "content-lv": { "size_g": "0.06", "vg": "apache-vg" }, "logs-lv": { "size_g": "0.12", "vg": "apache-vg" } }, "pvs":
{ "/dev/vdb1": { "free_g": "0.06", "size_g": "0.25", "vg": "apache-vg" } }, "vgs":
{ "apache-vg": { "free_g": "0.06", "num_lvs": "2", "num_pvs": "1", "size_g": "0.25" } } } }, "changed": false }
Atualize a instrução when
para verificar se não há um volume lógico com um nome que corresponda ao valor da palavra-chave do item name
. O conteúdo da terceira tarefa agora é:
- name: Create each Logical Volume (LV) if needed
lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop: "{{ logical_volumes }}"
when: item.name not in ansible_lvm["lvs"]
Altere a quarta tarefa para que use o módulo filesystem
.
Configure a tarefa para garantir que cada volume lógico seja
formatado como um sistema de arquivos XFS. Lembre-se de que um
volume lógico está associado ao dispositivo lógico /dev/
. <volume group name>
/<logical volume name>
O conteúdo da quarta tarefa deve ser:
- name: Ensure XFS Filesystem exists on each LV filesystem: dev: "/dev/{{ item.vgroup }}/{{ item.name }}" fstype: xfs loop: "{{ logical_volumes }}"
Configure a quinta tarefa para garantir que cada volume lógico tenha a capacidade de armazenamento correta. Se o volume lógico aumentar em capacidade, certifique-se de forçar a expansão do sistema de arquivos do volume.
Se um volume lógico precisar ter sua capacidade diminuída, essa tarefa apresentará falha porque um sistema de arquivos XFS não é compatível com a capacidade de diminuição.
O conteúdo da quinta tarefa deve ser:
- name: Ensure the correct capacity for each LV lvol: vg: "{{ item.vgroup }}" lv: "{{ item.name }}" size: "{{ item.size }}" resizefs: yes force: yes loop: "{{ logical_volumes }}"
Use o módulo mount
na sexta tarefa para garantir que cada volume lógico seja montado no
caminho de montagem correspondente e persista após uma reinicialização.
O conteúdo da sexta tarefa deve ser:
- name: Each Logical Volume is mounted mount: path: "{{ item.mount_path }}" src: "/dev/{{ item.vgroup }}/{{ item.name }}" fstype: xfs opts: noatime state: mounted loop: "{{ logical_volumes }}"
Revise o playbook storage.yml
concluído. Execute o playbook e verifique se cada volume lógico está montado.
Revise o playbook:
--- - name: Ensure Apache Storage Configuration hosts: webservers vars_files: - storage_vars.yml tasks: - name: Correct partitions exist on /dev/vdb parted: device: /dev/vdb state: present number: "{{ item.number }}" part_start: "{{ item.start }}" part_end: "{{ item.end }}" loop: "{{ partitions }}" - name: Ensure Volume Groups Exist lvg: vg: "{{ item.name }}" pvs: "{{ item.devices }}" loop: "{{ volume_groups }}" - name: Create each Logical Volume (LV) if needed lvol: vg: "{{ item.vgroup }}" lv: "{{ item.name }}" size: "{{ item.size }}" loop: "{{ logical_volumes }}" when: item.name not in ansible_lvm["lvs"] - name: Ensure XFS Filesystem exists on each LV filesystem: dev: "/dev/{{ item.vgroup }}/{{ item.name }}" fstype: xfs loop: "{{ logical_volumes }}" - name: Ensure the correct capacity for each LV lvol: vg: "{{ item.vgroup }}" lv: "{{ item.name }}" size: "{{ item.size }}" resizefs: yes force: yes loop: "{{ logical_volumes }}" - name: Each Logical Volume is mounted mount: path: "{{ item.mount_path }}" src: "/dev/{{ item.vgroup }}/{{ item.name }}" fstype: xfs opts: noatime state: mounted loop: "{{ logical_volumes }}"
Execute o playbook.
[student@workstation system-storage]$
ansible-playbook storage.yml
PLAY [Ensure Apache Storage Configuration] *********************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Correct partitions exist on /dev/vdb] ********************************** ok: [servera.lab.example.com] => (item={...output omitted...}) TASK [Ensure Volume Groups Exist] ******************************************** ok: [servera.lab.example.com] => (item={...output omitted...}) ...output omitted... TASK [Create each Logical Volume (LV) if needed] ***************************** skipping: [servera.lab.example.com] => (item={...output omitted...}) skipping: [servera.lab.example.com] => (item={...output omitted...}) TASK [Ensure XFS Filesystem exists on each LV] ******************************* changed: [servera.lab.example.com] => (item={...output omitted...}) changed: [servera.lab.example.com] => (item={...output omitted...}) TASK [Ensure the correct capacity for each LV] ******************************* ok: [servera.lab.example.com] => (item={...output omitted...}) ok: [servera.lab.example.com] => (item={...output omitted...}) TASK [Each Logical Volume is mounted] **************************************** changed: [servera.lab.example.com] => (item={...output omitted...}) changed: [servera.lab.example.com] => (item={...output omitted...}) PLAY RECAP ******************************************************************* servera.lab.example.com : ok=6 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Uma tarefa é ignorada durante a execução porque o playbook foi executado anteriormente com os mesmos valores de variáveis. Os volumes lógicos não precisaram ser criados.
Use um comando ad hoc do Ansible para executar o comando lsblk no host remoto. A saída indica os pontos de montagem para os volumes lógicos.
[student@workstation system-storage]$
ansible all -a lsblk
servera.lab.example.com | CHANGED | rc=0 >> NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 1024M 0 rom vda 252:0 0 10G 0 disk └─vda1 252:1 0 10G 0 part / vdb 252:16 0 1G 0 disk └─vdb1 252:17 0 256M 0 part ├─apache--vg-content--lv
253:0 064M
0 lvm/var/www
└─apache--vg-logs--lv
253:1 0128M
0 lvm/var/log/httpd
Aumente a capacidade do volume lógico content-lv
para 128 MiB e do volume lógico logs-lv
para 256 MiB. Isso exige um aumento na capacidade do grupo de volumes apache-vg
.
Crie uma nova partição com uma capacidade de 256 MiB e adicione-a ao grupo de volumes apache-vg
.
Edite a definição da variável partitions
no arquivo storage_vars.yml
para adicionar uma segunda partição ao dispositivo /dev/vdb
. O conteúdo da variável partitions
deve ser:
partitions:
- number: 1
start: 1MiB
end: 257MiB
- number: 2
start: 257MiB
end: 513MiB
Edite a definição da variável volume_groups
no arquivo storage_vars.yml
.
Adicione a segunda partição à lista de dispositivos que
suportam o grupo de volumes. O conteúdo da variável volume_groups
deve ser:
volume_groups:
- name: apache-vg
devices: /dev/vdb1,/dev/vdb2
Dobre a capacidade de cada volume lógico definido no arquivo storage_vars.yml
. O conteúdo da variável logical_volumes
deve ser:
logical_volumes: - name: content-lv size:128M
vgroup: apache-vg mount_path: /var/www - name: logs-lv size:256M
vgroup: apache-vg mount_path: /var/log/httpd
Execute o playbook. Verifique a nova capacidade de cada volume lógico.
[student@workstation system-storage]$
ansible-playbook storage.yml
PLAY [Ensure Apache Storage Configuration] *********************************** TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [Correct partitions exist on /dev/vdb] ********************************** ok: [servera.lab.example.com] => (item={...output omitted...}) changed: [servera.lab.example.com] => (item={u'start': u'257MiB', u'end': u'513MiB', u'number': 2}) TASK [Ensure Volume Groups Exist] ******************************************** changed: [servera.lab.example.com] => (item={u'name': u'apache-vg', u'devices': u'/dev/vdb1,/dev/vdb2'}) ...output omitted... TASK [Create each Logical Volume (LV) if needed] ***************************** skipping: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M', u'mount_path': u'/var/www', u'name': u'content-lv'}) skipping: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'256M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'}) TASK [Ensure XFS Filesystem exists on each LV] ******************************* ok: [servera.lab.example.com] => (item={...output omitted...}) ok: [servera.lab.example.com] => (item={...output omitted...}) TASK [Ensure the correct capacity for each LV] ******************************* changed: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M', u'mount_path': u'/var/www', u'name': u'content-lv'}) changed: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'256M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'}) TASK [Each Logical Volume is mounted] **************************************** ok: [servera.lab.example.com] => (item={...output omitted...}) ok: [servera.lab.example.com] => (item={...output omitted...}) PLAY RECAP ******************************************************************* servera.lab.example.com : ok=6 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
A saída indica mudanças nas partições e no grupo de volumes no host remoto e que ambos os volumes lógicos foram redimensionados.
Use um comando ad hoc do Ansible para executar o comando lsblk no host remoto.
[student@workstation system-storage]$
ansible all -a lsblk
servera.lab.example.com | CHANGED | rc=0 >> NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 1024M 0 rom vda 252:0 0 10G 0 disk └─vda1 252:1 0 10G 0 part / vdb 252:16 0 1G 0 disk ├─vdb1 252:17 0 256M 0 part │ ├─apache--vg-content--lv
253:0 0128M
0 lvm /var/www │ └─apache--vg-logs--lv
253:1 0256M
0 lvm /var/log/httpd └─vdb2 252:18 0 256M 0 part ├─apache--vg-content--lv
253:0 0128M
0 lvm /var/www └─apache--vg-logs--lv
253:1 0256M
0 lvm /var/log/httpd
A saída indica que cada volume lógico tem o tamanho
correto e está montado no diretório correto. Há duas
entradas para cada volume lógico porque os arquivos armazenados no
volume lógico podem estar fisicamente localizados em qualquer partição (/dev/vdb1
ou /dev/vdb2
).
Isso conclui o exercício orientado.
Depois de concluir esta seção, você deverá ser capaz de definir as configurações de rede e a resolução de nomes em hosts gerenciados, bem como coletar fatos do Ansible relacionados à rede.
O Red Hat Enterprise Linux 8 inclui uma coleção de funções Ansible do sistema para configurar sistemas baseados no RHEL. O pacote rhel-system-roles instala essas funções do sistema que, por exemplo, dão suporte para a configuração de sincronização de horário ou rede. Você pode listar as funções do sistema atualmente instaladas com o comando ansible-galaxy list.
[user@controlnode ~]$
ansible-galaxy list
- linux-system-roles.kdump, (unknown version) - linux-system-roles.network, (unknown version) - linux-system-roles.postfix, (unknown version) - linux-system-roles.selinux, (unknown version) - linux-system-roles.timesync, (unknown version) - rhel-system-roles.kdump, (unknown version) - rhel-system-roles.network, (unknown version) - rhel-system-roles.postfix, (unknown version) - rhel-system-roles.selinux, (unknown version) - rhel-system-roles.timesync, (unknown version)
As funções estão localizadas no diretório /usr/share/ansible/roles
. Uma função que comece com linux-system-roles
é um symlink para a função rhel-system-roles
correspondente.
A
função de sistema de rede dá suporte à configuração de rede em hosts
gerenciados. Essa função dá suporte para a configuração de interfaces
ethernet, interfaces bridge, interfaces vinculadas, interfaces VLAN,
interfaces MacVLAN e interfaces Infiniband. A função de rede é
configurada com duas variáveis, network_provider
e network_connections
.
--- network_provider: nm network_connections: - name: ens4 type: ethernet ip: address: - 172.25.250.30/24
A variável network_provider
configura o provedor de back-end, que é nm
(NetworkManager) ou initscripts
. No Red Hat Enterprise Linux 8, a função de rede usa nm
(NetworkManager) como provedor de rede padrão. O provedor initscripts
provedor é usado para sistemas RHEL 6 e requer que o serviço network
esteja disponível. A variável network_connections
configura as diferentes conexões, especificadas como uma lista de
dicionários, usando o nome da interface como o nome da conexão.
A tabela a seguir lista as opções da variável network_connections
.
O seguinte exemplo usa algumas das opções anteriores:
network_connections: - name: eth0persistent_state: present
type: ethernet
autoconnect: yes
mac: 00:00:5e:00:53:5d
ip: address: - 172.25.250.40/24
zone: external
Para usar a função de sistema de rede, é necessário especificar o nome da função na cláusula roles
do seu playbook da seguinte forma:
- name: NIC Configuration hosts: webservers vars: network_connections: - name: ens4 type: ethernet ip: address: - 172.25.250.30/24 roles: - rhel-system-roles.network
Você pode especificar variáveis para a função de rede com a cláusula vars
, como no exemplo anterior, ou criar um arquivo YAML com essas variáveis nos diretórios group_vars
ou host_vars
, dependendo do seu caso de uso.
Como alternativa à função de sistema network
, o Red Hat Ansible Engine inclui uma coleção de módulos que dão suporte à configuração de rede em um sistema. O módulo nmcli
dá suporte ao gerenciamento de conexões de rede e dispositivos. Esse
módulo dá suporte à configuração de agrupamento e vinculação para
interfaces de rede, bem como endereçamento IPv4 e IPv6.
A tabela a seguir lista alguns dos parâmetros do módulo nmcli
.
O exemplo a seguir define uma configuração de IP estático para uma conexão de rede e um dispositivo.
- name: NIC configuration nmcli: conn_name: ens4-connifname: ens4
type: ethernet
ip4: 172.25.250.30/24
gw4: 172.25.250.1
state: present
O módulo hostname
define o nome do host de um host gerenciado sem modificar o arquivo /etc/hosts
. Esse módulo usa o parâmetro name
para especificar o novo nome do host, como na tarefa mostrada abaixo:
- name: Change hostname hostname: name: managedhost1
O módulo firewalld
dá suporte ao gerenciamento de FirewallD em hosts gerenciados. Esse
módulo dá suporte à configuração de regras do FirewallD para serviços e
portas. Ele também dá suporte ao gerenciamento de zona, incluindo a
associação ou as interfaces de rede e as regras de uma zona específica.
A tarefa a seguir mostra como criar uma regra do FirewallD para o serviço http
na zona padrão (public
). A tarefa configura a regra como permanente e garante que esteja ativa.
- name: Enabling http rule firewalld: service: http permanent: yes state: enabled
Essa tarefa configura eth0
na zona external
do FirewallD.
- name: Moving eth0 to external firewalld: zone: external interface: eth0 permanent: yes state: enabled
A tabela a seguir lista alguns dos parâmetros do módulo firewalld
.
O
Ansible usa fatos para recuperar informações para o nó de controle
sobre a configuração dos hosts gerenciados. Você pode usar o módulo setup
do Ansible para recuperar todos os fatos do Ansible de um host gerenciado.
[user@controlnode ~]$
ansible webservers -m setup
host.lab.example.com | SUCCESS => { "ansible_facts": { ...output omitted... }
Todas as interfaces de rede de um host gerenciado estão disponíveis sob o elemento ansible_interfaces
. Você pode usar o parâmetro gather_subset=network
para o módulo setup
a fim de restringir os fatos aos incluídos no subconjunto network
. A opção filter
do módulo setup
é compatível com filtragem refinada baseada em curingas de estilo shell.
[user@controlnode ~]$
ansible webservers -m setup \
>
-a 'gather_subset=network filter=ansible_interfaces'
host.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_interfaces": [ "ens4", "lo", "ens3" ] }, "changed": false }
O comando anterior mostra que três interfaces de rede estão disponíveis no host gerenciado, host.lab.example.com
: lo
, ens3
e ens4
.
Você pode recuperar informações adicionais sobre a configuração de uma interface de rede com o filtro ansible_
do módulo NIC_name
setup
. Por exemplo, para recuperar a configuração da interface de rede ens4
, use o filtro ansible_ens4
.
[user@controlnode ~]$
ansible webservers -m setup \
>
-a 'gather_subset=network filter=ansible_ens4'
host.lab.example.com | SUCCESS => { "ansible_facts": { "ansible_ens4": { "active": true, "device": "ens4", "features": { }, "hw_timestamp_filters": [], "ipv4": { "address": "172.25.250.30", "broadcast": "172.25.250.255", "netmask": "255.255.255.0", "network": "172.25.250.0" }, "ipv6": [ { "address": "fe80::5b42:8c94:1fc7:40ae", "prefix": "64", "scope": "link" } ], "macaddress": "52:54:00:01:fa:0a", "module": "virtio_net", "mtu": 1500, "pciid": "virtio1", "promisc": false, "speed": -1, "timestamping": [ "tx_software", "rx_software", "software" ], "type": "ether" } }, "changed": false }
O comando anterior exibe detalhes adicionais de configuração, como a configuração do endereço IP de IPv4 e IPv6, o dispositivo associado e o tipo.
A tabela a seguir lista alguns dos fatos disponíveis para o subconjunto network
.
O Ansible também fornece a variável inventory_hostname
, que inclui o nome do host conforme configurado no arquivo de inventário do Ansible.
Neste exercício, você ajustará a configuração de rede de um host gerenciado e coletará informações sobre ela em um arquivo criado por um template.
Resultados
Você deverá ser capaz de definir as configurações de rede e a resolução de nomes em hosts gerenciados, bem como coletar fatos do Ansible relacionados à rede.
Na workstation, execute o script lab system-network start para configurar o ambiente para o exercício. O script cria o diretório de trabalho system-network e faz o download dos arquivos de configuração e inventário de host do Ansible necessários para o exercício.
[student@workstation ~]$ lab system-network start
Revise o arquivo de inventário no diretório /home/student/system-network.
Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-network.
[student@workstation ~]$ cd ~/system-network
[student@workstation system-network]$
Verifique se servera.lab.example.com faz parte do grupo de hosts webservers. Esse servidor tem uma interface de rede sobressalente.
[student@workstation system-network]$ cat inventory
[webservers]
servera.lab.example.com
Use o comando ansible-galaxy para verificar se as funções do sistema estão disponíveis. Se nenhuma função estiver disponível, você precisará instalar o rhel-system-roles pacote.
[student@workstation system-network]$ ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.
Crie um playbook que use a função linux-system-roles.network para configurar a interface de rede sobressalente ens4 no servera.lab.example.com com o endereço IP 172.25.250.30.
Crie um playbook, playbook.yml, com uma ação que tenha como destino o grupo de hosts webservers. Inclua a função rhel-system-roles.network na seção roles da ação.
---
- name: NIC Configuration
hosts: webservers
roles:
- rhel-system-roles.network
Revise a seção Role Variables do arquivo README.md para a função rhel-system-roles.network. Determine as variáveis da função para configurar a interface de rede ens4 com o endereço IP 172.25.250.30.
[student@workstation system-network]$ cat \
> /usr/share/doc/rhel-system-roles/network/README.md
...output omitted...
Setting the IP configuration:
...output omitted...
Crie o subdiretório group_vars/webservers.
[student@workstation system-network]$ mkdir -pv group_vars/webservers
mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/webservers'
Crie um novo arquivo network.yml para definir variáveis da função. Como esses valores de variável se aplicam aos hosts no grupo de hosts webservers, você precisa criar esse arquivo no diretório group_vars/webservers. Adicione definições de variável para dar suporte à configuração da interface de rede ens4. O arquivo agora contém:
---
network_connections:
- name: ens4
type: ethernet
ip:
address:
- 172.25.250.30/24
Execute o playbook para configurar a interface de rede secundária em servera.
[student@workstation system-network]$ ansible-playbook playbook.yml
PLAY [NIC Configuration] *******************************************************
TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]
TASK [rhel-system-roles.network : Check which services are running] ************
ok: [servera.lab.example.com]
TASK [rhel-system-roles.network : Check which packages are installed] **********
ok: [servera.lab.example.com]
TASK [rhel-system-roles.network : Print network provider] **********************
ok: [servera.lab.example.com] => {
"msg": "Using network provider: nm"
}
TASK [rhel-system-roles.network : Install packages] ****************************
skipping: [servera.lab.example.com]
TASK [rhel-system-roles.network : Enable network service] **********************
ok: [servera.lab.example.com]
TASK [rhel-system-roles.network : Configure networking connection profiles] ****
...output omitted...
changed: [servera.lab.example.com]
TASK [rhel-system-roles.network : Re-test connectivity] ************************
ok: [servera.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=7 changed=1 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0
Use o módulo setup do Ansible em um comando adhoc do Ansible para verificar se a configuração da interface de rede ens4 em servera está correta.
Use o módulo servera do Ansible para listar todos os fatos do Ansible disponíveis para servera. Filtre os resultados para a interface de rede ens4 com a opção -a 'filter=filter_string'. Verifique se a interface de rede ens4 usa o endereço IP 172.25.250.30. A configuração do endereço IP pode levar até um minuto.
[student@workstation system-network]$ ansible webservers -m setup \
> -a 'filter=ansible_ens4'
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_ens4": {
...output omitted...
"ipv4": {
"address": "172.25.250.30",
"broadcast": "172.25.250.255",
"netmask": "255.255.255.0",
"network": "172.25.250.0"
},
...output omitted...
Encerramento
Em workstation, execute o script lab system-network finish para limpar os recursos criados neste exercício.
[student@workstation ~]$ lab system-network finish
Isso conclui o exercício orientado.
Lista de verificação de desempenho
Neste laboratório, você configurará e realizará tarefas administrativas em hosts gerenciados usando um playbook.
Resultados
Você deverá ser capaz de criar playbooks para configurar em um host gerenciado um repositório de software, usuários e grupos, volumes lógicos, tarefas do cron e interfaces de rede adicionais.
Na workstation, execute o script de início do laboratório para confirmar se o ambiente está pronto para que o laboratório comece. O script cria o diretório de trabalho, chamado de system-review, e o preenche com um arquivo de configuração do Ansible, um inventário de host e arquivos de laboratório.
[student@workstation ~]$ lab system-review start
Crie e execute no grupo de hosts webservers um playbook que configure o repositório interno Yum localizado em http://materials.example.com/yum/repository e instale o pacote example-motd disponível nesse repositório. Todos os pacotes RPM são assinados com um par de chaves GPG organizacional. A chave pública GPG está disponível em http://materials.example.com/yum/repository/RPM-GPG-KEY-example.
Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-review.
[student@workstation ~]$ cd ~/system-review
[student@workstation system-review]$
Crie o playbook repo_playbook.yml, que é executado nos hosts gerenciados no grupo de hosts webservers. Adicione uma tarefa que use o módulo yum_repository para garantir a configuração do repositório yum interno no host remoto. Certifique-se de que:
A configuração do repositório está armazenada no arquivo /etc/yum.repos.d/example.repo
A ID do repositório é example-internal
O URL de base é http://materials.example.com/yum/repository
O repositório está configurado para verificar as assinaturas GPG do RPM
A descrição do repositório é Example Inc. Internal YUM repo
O playbook contém o seguinte:
---
- name: Repository Configuration
hosts: webservers
tasks:
- name: Ensure Example Repo exists
yum_repository:
name: example-internal
description: Example Inc. Internal YUM repo
file: example
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes
Adicione uma segunda tarefa à ação que use o módulo rpm_key para garantir que a chave pública do repositório esteja presente no host remoto. A URL da chave pública do repositório é http://materials.example.com/yum/repository/RPM-GPG-KEY-example.
A segunda tarefa aparece conforme segue:
- name: Ensure Repo RPM Key is Installed
rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present
Adicione uma terceira tarefa para instalar o pacote example-motd disponível no repositório interno Yum.
A terceira tarefa aparece conforme segue:
- name: Install Example motd package
yum:
name: example-motd
state: present
Execute o playbook:
[student@workstation system-review]$ ansible-playbook repo_playbook.yml
PLAY [Repository Configuration] ************************************************
TASK [Gathering Facts] *********************************************************
ok: [serverb.lab.example.com]
TASK [Ensure Example Repo exists] **********************************************
changed: [serverb.lab.example.com]
TASK [Ensure Repo RPM Key is Installed] ****************************************
changed: [serverb.lab.example.com]
TASK [Install Example motd package] ********************************************
changed: [serverb.lab.example.com]
PLAY RECAP *********************************************************************
serverb.lab.example.com : ok=4 changed=3 unreachable=0 failed=0
Crie e execute no grupo de hosts webservers um playbook que crie o grupo de usuários webadmin e adicione dois usuários a esse grupo, ops1 e ops2.
Crie um arquivo de variável vars/users_vars.yml definindo dois usuários, ops1 e ops2, que pertencem ao grupo de usuários webadmin. Poderá ser necessário criar o subdiretório vars.
[student@workstation system-review]$ mkdir vars
[student@workstation system-review]$ vi vars/users_vars.yml
---
users:
- username: ops1
groups: webadmin
- username: ops2
groups: webadmin
Crie o playbook users.yml. Defina uma única ação no playbook que tenha como destino o grupo de hosts webservers. Adicione uma cláusula vars_files que define o local do nome do arquivo vars/users_vars.yml. Adicione uma tarefa que use o módulo group para criar o grupo de usuários webadmin no host remoto.
---
- name: Create multiple local users
hosts: webservers
vars_files:
- vars/users_vars.yml
tasks:
- name: Add webadmin group
group:
name: webadmin
state: present
Adicione uma segunda tarefa ao playbook que usa o módulo user para criar os usuários. Adicione uma cláusula loop: "{{ users }}" à tarefa para fazer loop no arquivo da variável para cada nome de usuário encontrado no arquivo vars/users_vars.yml. Como name: para os usuários, use o nome da variável item.username. Assim, o arquivo da variável pode conter informações adicionais que podem ser úteis para criar usuários, como os grupos aos quais os eles devem pertencer. A segunda tarefa contém o seguinte:
- name: Create user accounts
user:
name: "{{ item.username }}"
groups: webadmin
loop: "{{ users }}"
Execute o playbook:
[student@workstation system-review]$ ansible-playbook users.yml
PLAY [Create multiple local users] ****************************************************
TASK [Gathering Facts] ****************************************************************
ok: [serverb.lab.example.com]
TASK [Add webadmin group] *************************************************************
changed: [serverb.lab.example.com]
TASK [Create user accounts] ***********************************************************
changed: [serverb.lab.example.com] => (item={'username': 'ops1', 'groups': 'webadmin'})
changed: [serverb.lab.example.com] => (item={'username': 'ops2', 'groups': 'webadmin'})
PLAY RECAP ****************************************************************************
serverb.lab.example.com : ok=3 changed=2 unreachable=0 failed=0
Crie e execute no grupo de hosts webservers um playbook que use o dispositivo /dev/vdb para criar um grupo de volumes chamado apache-vg. Esse playbook também cria dois volumes lógicos, chamados content-lv e logs-lv, ambos apoiados pelo grupo de volumes apache-vg. Por fim, crie um sistema de arquivos XFS em cada volume lógico e monte o volume lógico content-lv em /var/www e o volume lógico logs-lv em /var/log/httpd. O script de laboratório preenche dois arquivos em ~/system-review: storage.yml, que fornece um esqueleto inicial para o playbook, e storage_vars.xml, que fornece valores para todas as variáveis necessárias para os diferentes módulos.
Revise o arquivo de variável storage_vars.yml.
[student@workstation system-review]$ cat storage_vars.yml
---
partitions:
- number: 1
start: 1MiB
end: 257MiB
volume_groups:
- name: apache-vg
devices: /dev/vdb1
logical_volumes:
- name: content-lv
size: 64M
vgroup: apache-vg
mount_path: /var/www
- name: logs-lv
size: 128M
vgroup: apache-vg
mount_path: /var/log/httpd
Esse arquivo descreve a estrutura pretendida de partições, grupos de volumes e volumes lógicos em cada servidor web. A primeira partição começa com um deslocamento de 1MiB desde o início do dispositivo /dev/vdb e termina em um deslocamento de 257MiB, em um tamanho total de 256MiB.
Cada servidor web tem um grupo de volumes, denominado apache-vg, que contém a primeira partição do dispositivo /dev/vdb.
Cada servidor web tem dois volumes lógicos. O primeiro volume lógico é denominado content-lv, com um tamanho de 64MiB, anexado ao grupo de volumes apache-vg e montado em /var/www. O segundo volume lógico é denominado content-lv, com um tamanho de 128MiB, anexado ao grupo de volumes apache-vg e montado em /var/log/httpd.
O grupo de volumes apache-vg tem uma capacidade de 256MiB porque é apoiado pela partição /dev/vdb1. Ele oferece capacidade suficiente para ambos os volumes lógicos.
Altere a primeira tarefa no playbook storage.yml para usar o módulo parted para configurar uma partição para cada item de loop. Cada item descreve uma partição pretendida do dispositivo /dev/vdb em cada servidor web:
number
O número da partição. Use isso como o valor da palavra-chave number para o módulo parted.
start
O início da partição, como um deslocamento desde o início do dispositivo de bloco. Use isso como o valor da palavra-chave part_start para o módulo parted.
end
O final da partição, como um deslocamento desde o início do dispositivo de bloco. Use isso como o valor da palavra-chave part_end para o módulo parted.
O conteúdo da primeira tarefa deve ser:
- name: Correct partitions exist on /dev/vdb
parted:
device: /dev/vdb
state: present
number: "{{ item.number }}"
part_start: "{{ item.start }}"
part_end: "{{ item.end }}"
loop: "{{ partitions }}"
Altere a segunda tarefa da ação para que use o módulo lvg para configurar um grupo de volumes para cada item de loop. Cada item da variável volume_groups descreve um grupo de volumes que deve existir em cada servidor web:
name
O nome do grupo de volumes. Use isso como o valor da palavra-chave vg para o módulo lvg.
devices
Uma lista de dispositivos ou partições separados por vírgulas que formam o grupo de volumes. Use isso como o valor da palavra-chave pvs para o módulo lvg.
O conteúdo da segunda tarefa deve ser:
- name: Ensure Volume Groups Exist
lvg:
vg: "{{ item.name }}"
pvs: "{{ item.devices }}"
loop: "{{ volume_groups }}"
Altere a terceira tarefa para que use o módulo lvol. Defina o nome do grupo de volumes, o nome do volume lógico e o tamanho do volume lógico usando as palavras-chave de cada item. O conteúdo da terceira tarefa agora é:
- name: Create each Logical Volume (LV) if needed
lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop: "{{ logical_volumes }}"
Altere a quarta tarefa para que use o módulo filesystem. Configure a tarefa para garantir que cada volume lógico seja formatado como um sistema de arquivos XFS. Lembre-se de que um volume lógico está associado ao dispositivo lógico /dev/<volume group name>/<logical volume name>.
O conteúdo da quarta tarefa deve ser:
- name: Ensure XFS Filesystem exists on each LV
filesystem:
dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
loop: "{{ logical_volumes }}"
Configure a quinta tarefa para garantir que cada volume lógico tenha a capacidade de armazenamento correta. Se o volume lógico aumentar em capacidade, certifique-se de forçar a expansão do sistema de arquivos do volume.
Se um volume lógico precisar ter sua capacidade diminuída, essa tarefa apresentará falha porque um sistema de arquivos XFS não é compatível com a capacidade de diminuição.
O conteúdo da quinta tarefa deve ser:
- name: Ensure the correct capacity for each LV
lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
resizefs: yes
force: yes
loop: "{{ logical_volumes }}"
Use o módulo mount na sexta tarefa para garantir que cada volume lógico seja montado no caminho de montagem correspondente e persista após uma reinicialização.
O conteúdo da sexta tarefa deve ser:
- name: Each Logical Volume is mounted
mount:
path: "{{ item.mount_path }}"
src: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
state: mounted
loop: "{{ logical_volumes }}"
Execute o playbook para criar os volumes lógicos no host remoto.
[student@workstation system-review]$ ansible-playbook storage.yml
PLAY [Ensure Apache Storage Configuration] *************************************************
TASK [Gathering Facts] *********************************************************************
ok: [serverb.lab.example.com]
TASK [Correct partitions exist on /dev/vdb] ************************************************
changed: [serverb.lab.example.com] => (item={'number': 1, 'start': '1MiB', 'end': '257MiB'})
TASK [Ensure Volume Groups Exist] **********************************************************
changed: [serverb.lab.example.com] => (item={'name': 'apache-vg', 'devices': '/dev/vdb1'})
...output omitted...
TASK [Create each Logical Volume (LV) if needed] *******************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})
TASK [Ensure XFS Filesystem exists on each LV] *********************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})
TASK [Ensure the correct capacity for each LV] *********************************************
ok: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
ok: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})
TASK [Each Logical Volume is mounted] ******************************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})
PLAY RECAP *********************************************************************************
serverb.lab.example.com : ok=7 changed=5 unreachable=0 failed=0
Crie e execute no grupo de hosts webservers um playbook que use o módulo cron para criar o arquivo crontab /etc/cron.d/disk_usage, que agenda uma tarefa do cron recorrente. A tarefa deve ser executada com o usuário devops a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira. A tarefa deve anexar a utilização atual do disco ao arquivo /home/devops/disk_usage.
Crie um novo playbook, create_crontab_file.yml, e adicione as linhas necessárias para iniciar a ação. Ele deve ser direcionado ao hosts gerenciados no grupo webservers e ativar o escalonamento de privilégios.
---
- name: Recurring cron job
hosts: webservers
become: true
Defina uma tarefa que usa o módulo cron para agendar uma tarefa do cron recorrente.
O módulo cron fornece uma opção name para descrever exclusivamente a entrada do arquivo crontab e garantir os resultados esperados. A descrição é adicionada ao arquivo crontab. Por exemplo, a opção name é necessária se você estiver removendo uma entrada crontab usando state=absent. Além disso, quando o estado padrão state=present é definido, a opção name impede que uma nova entrada crontab seja sempre criada, independentemente das existentes.
tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file
Configure a tarefa para que seja executada a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira.
minute: "*/2"
hour: 9-16
weekday: 1-5
Use o parâmetro cron_file para usar o arquivo crontab /etc/cron.d/disk_usage em vez de usar o crontab de um usuário individual em /var/spool/cron/. Um caminho relativo colocará o arquivo no diretório /etc/cron.d. Se o parâmetro cron_file for usado, você também deverá especificar o parâmetro user.
user: devops
job: df >> /home/devops/disk_usage
cron_file: disk_usage
state: present
Quando concluído, o playbook deverá ficar desta forma: Revise o playbook para garantir a precisão.
---
- name: Recurring cron job
hosts: webservers
become: true
tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file
minute: "*/2"
hour: 9-16
weekday: 1-5
user: devops
job: df >> /home/devops/disk_usage
cron_file: disk_usage
state: present
Execute o playbook.
[student@workstation system-review]$ ansible-playbook create_crontab_file.yml
PLAY [Recurring cron job] *********************************************************************
TASK [Gathering Facts] ************************************************************************
ok: [serverb.lab.example.com]
TASK [Crontab file exists] ********************************************************************
changed: [serverb.lab.example.com]
PLAY RECAP ************************************************************************************
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
Crie e execute no grupo de hosts webservers um playbook que use a função linux-system-roles.network para configurar com o endereço IP 172.25.250.40/24 a interface de rede sobressalente, ens4.
Use ansible-galaxy para verificar se as funções do sistema estão disponíveis. Caso contrário, você precisa instalar o pacote rhel-system-roles.
[student@workstation system-review]$ ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.
Crie um playbook, network_playbook.yml, com uma ação que tenha como destino o grupo de hosts webservers. Inclua a função rhel-system-roles.network na seção roles da ação.
---
- name: NIC Configuration
hosts: webservers
roles:
- rhel-system-roles.network
Crie o subdiretório group_vars/webservers.
[student@workstation system-review]$ mkdir -pv group_vars/webservers
mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/webservers'
Crie um novo arquivo network.yml para definir variáveis da função. Como esses valores de variável se aplicam aos hosts no grupo de hosts webservers, você precisa criar esse arquivo no diretório group_vars/webservers. Adicione definições de variável para dar suporte à configuração da interface de rede ens4. O arquivo agora contém:
[student@workstation system-review]$ vi group_vars/webservers/network.yml
---
network_connections:
- name: ens4
type: ethernet
ip:
address:
- 172.25.250.40/24
Execute o playbook para configurar a interface de rede secundária.
[student@workstation system-review]$ ansible-playbook network_playbook.yml
PLAY [NIC Configuration] *******************************************************************
TASK [Gathering Facts] *********************************************************************
ok: [serverb.lab.example.com]
TASK [rhel-system-roles.network : Check which services are running] ************************
ok: [serverb.lab.example.com]
TASK [rhel-system-roles.network : Check which packages are installed] **********************
ok: [serverb.lab.example.com]
TASK [rhel-system-roles.network : Print network provider] **********************************
ok: [serverb.lab.example.com] => {
"msg": "Using network provider: nm"
}
TASK [rhel-system-roles.network : Install packages] ****************************************
skipping: [serverb.lab.example.com]
TASK [rhel-system-roles.network : Enable network service] **********************************
ok: [serverb.lab.example.com]
TASK [rhel-system-roles.network : Configure networking connection profiles] ****************
[WARNING]: [002] <info> #0, state:None persistent_state:present, 'ens4': add connection
ens4, 38d63afd-e610-4929-ba1b-1d38413219fb
changed: [serverb.lab.example.com]
TASK [rhel-system-roles.network : Re-test connectivity] ************************************
ok: [serverb.lab.example.com]
PLAY RECAP *********************************************************************************
serverb.lab.example.com : ok=7 changed=1 unreachable=0 failed=0
Verifique se a interface de rede ens4 usa o endereço IP 172.25.250.40. A configuração do endereço IP pode levar até um minuto.
[student@workstation system-review]$ ansible webservers -m setup \
> -a 'filter=ansible_ens4'
serverb.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_ens4": {
...output omitted...
"ipv4": {
"address": "172.25.250.40",
"broadcast": "172.25.250.255",
"netmask": "255.255.255.0",
"network": "172.25.250.0"
},
...output omitted...
Execute lab system-review grade na workstation para classificar seu trabalho.
[student@workstation ~]$ lab system-review grade
Encerramento
Na workstation, execute o script lab system-review finish para limpar os recursos criados neste laboratório.
[student@workstation ~]$ lab system-review finish
Isso conclui o laboratório. Red Hat logo
Privac
Neste capítulo, você aprendeu que:
O módulo yum_repository configura um repositório Yum em um host gerenciado. Para repositórios que usam chaves públicas, é possível verificar se a chave está disponível com o módulo rpm_key.
Os módulos user e group criam usuários e grupos, respectivamente, em um host gerenciado. Você pode configurar chaves autorizadas para um usuário com o módulo authorized_key.
Tarefas do cron podem ser configuradas em hosts gerenciados com o módulo cron.
O Ansible dá suporte à configuração de volumes lógicos com os módulos lvg e lvol. Os módulos parted e filesystem dão suporte, respectivamente, ao particionamento de dispositivos e à criação de sistemas de arquivos.
O RedHat Enterprise Linux8 inclui a função de sistema de rede que dá suporte à configuração de interfaces de rede em hosts gerenciados.
Objetivos
Depois de concluir esta seção, você deverá ser capaz de subscrever sistemas, configurar canais e repositórios de software e gerenciar pacotes RPM em hosts gerenciados.
Gerenciamento de pacotes com o Ansible
O módulo
yum
do Ansible usa o Yum Package Manager nos hosts gerenciados para processar as operações de pacote. O exemplo a seguir é um playbook que instala o pacote httpd no host gerenciadoservera.lab.example.com
.A tabela a seguir compara o uso do módulo
yum
do Ansible com o comando yum equivalente.Execute o comando ansible-doc yum para obter mais parâmetros e exemplos de playbooks.
Otimização da instalação de vários pacotes
Para operar em vários pacotes, a palavra-chave
name
aceita uma lista. O exemplo a seguir mostra um playbook que instala três pacotes emservera.lab.example.com
.Com essa sintaxe, o Ansible instala os pacotes em uma única transação do Yum. Isso é equivalente a executar o comando yum install httpd mod_ssl httpd-tools.
Uma versão comumente vista, mas menos eficiente e mais lenta, dessa tarefa é usar um loop.
Evite usar esse método, pois ele exige que o módulo realize três transações individuais, uma para cada pacote.
Coleta de fatos sobre os pacotes instalados
O módulo
package_facts
do Ansible coleta os detalhes dos pacotes instalados em hosts gerenciados. Ele define a variávelansible_facts.packages
com os detalhes do pacote.O playbook a seguir chama o módulo
package_facts
, o módulodebug
para exibir o conteúdo da variávelansible_facts.packages
e o módulodebug
novamente para visualizar a versão do pacote NetworkManager instalado.Quando executado, o playbook exibe a lista de pacotes e a versão do pacote NetworkManager:
Revisão de módulos alternativos para gerenciar pacotes
O módulo
yum
do Ansible funciona em hosts gerenciados que estão usando o Yum Package Manager. Para outros gerenciadores de pacotes, o Ansible geralmente fornece um módulo dedicado. Por exemplo, o módulodnf
gerencia pacotes em sistemas operacionais como o Fedora usando o gerenciador de pacotes DNF. O móduloapt
usa a ferramenta de pacotes APT disponível no Debian ou no Ubuntu. O módulowin_package
pode instalar software em sistemas Microsoft Windows.O playbook a seguir usa condicionais para selecionar o módulo apropriado em um ambiente composto por sistemas Red Hat Enterprise Linux e Fedora.
Como alternativa, o módulo genérico
package
detecta automaticamente e usa o gerenciador de pacotes disponível nos hosts gerenciados. Com o módulopackage
, você pode reescrever o playbook anterior da forma a seguir.No entanto, observe que o módulo
package
não é compatível com todos os recursos que os módulos mais especializados oferecem. Além disso, os sistemas operacionais geralmente têm nomes diferentes para os pacotes que eles fornecem. Por exemplo, o pacote que instala o Apache HTTP Server é httpd no Red Hat Enterprise Linux e apache2 no Ubuntu. Nessa situação, você ainda precisa de uma condicional para selecionar o nome do pacote correto, dependendo do sistema operacional do host gerenciado.Registro e gerenciamento de sistemas com o Red Hat Subscription Management
Para habilitar seus novos sistemas Red Hat Enterprise Linux para subscrições de produtos, o Ansible fornece os módulos
redhat_subscription
erhsm_repository
. Esses módulos interagem com a ferramenta do Red Hat Subscription Manager nos hosts gerenciados.Registro e subscrição de novos sistemas
As duas primeiras tarefas que você normalmente executa com a ferramenta do Red Hat Subscription Management é registrar o novo sistema e anexar uma subscrição disponível.
Sem o Ansible, essas tarefas são realizadas com o comando subscription-manager:
Lembre-se de que você lista os pools disponíveis em sua conta com o comando subscription-manager list --available.
O módulo
redhat_subscription
do Ansible realiza o registro e a subscrição em uma tarefa.Uma palavra-chave
state
definida comopresent
indica que o sistema deve ser registrado e subscrito. Quando estiver definida comoabsent
, o módulo cancelará o registro do sistema.Ativação dos repositórios de software da Red Hat
A próxima tarefa após a subscrição é ativar os repositórios de software da Red Hat no novo sistema.
Sem o Ansible, você normalmente executa o comando subscription-manager para essa finalidade:
Lembre-se de que você pode listar os repositórios disponíveis com o comando subscription-manager repos --list.
Com o Ansible, use o módulo
rhsm_repository
:Configuração de um repositório yum
Para ativar o suporte para um repositório de terceiros em um host gerenciado, o Ansible fornece o módulo
yum_repository
.Declaração de um repositório yum
Quando executado, o playbook a seguir declara um novo repositório em
servera.lab.example.com
.O arquivo
/etc/yum.repos.d/example.repo
resultante emservera.lab.example.com
é o seguinte.O módulo
yum_repository
expõe a maioria dos parâmetros de configuração do repositório Yum como palavras-chave. Execute o comando ansible-doc yum_repository para obter mais parâmetros e exemplos de playbooks.Alguns repositórios de terceiros fornecem o arquivo de configuração e a chave pública GPG como parte de um pacote RPM, que pode ser baixado e instalado usando o comando yum install. Por exemplo, o projeto Extra Packages for Enterprise Linux (EPEL) fornece o pacote https://dl.fedoraproject.org/pub/epel/epel-release-latest-
VER
.noarch.rpm que implanta o arquivo de configuração/etc/yum.repos.d/epel.repo
. Para esse repositório, use o móduloyum
do Ansible para instalar o pacote EPEL em vez do móduloyum_repository
.Importação de uma chave GPG do RPM
Quando a palavra-chave
gpgcheck
está definida comoyes
no móduloyum_repository
, você também precisa instalar a chave GPG no host gerenciado. O módulorpm_key
no exemplo a seguir implanta emservera.lab.example.com
a chave pública GPG hospedada em um servidor web remoto.Páginas do man yum(8),
yum.conf
(5) e subscription-manager(8)yum — Manages packages with the yum package manager — Ansible Documentation
package_facts — package information as facts — Ansible Documentation
redhat_subscription — Manage registration and subscriptions to RHSM using the subscription-manager command — Ansible Documentation
rhsm_repository — Manage RHSM repositories using the subscription-manager command — Ansible Documentation
yum_repository — Add or remove YUM repositories — Ansible Documentation
rpm_key — Adds or removes a gpg key from the rpm db — Ansible Documentation