britho / Ansible-HedHat

0 stars 0 forks source link

Aula-2 #2

Open britho opened 3 years ago

britho commented 3 years ago

Meta | Configurar o Ansible para gerenciar hosts e executar comandos ad hoc do Ansible. -- | -- Objetivos | Descrever os conceitos do inventário do Ansible e gerenciar um arquivo de inventário estático. Descrever onde os arquivos de configuração do Ansible estão localizados, como o Ansible seleciona esses arquivos e editá-los para aplicar alterações às configurações padrão. Executar uma só tarefa de automação do Ansible usando um comando ad hoc e explicar alguns casos de uso de comandos ad hoc. Seções | Criação de um inventário do Ansible (e exercício orientado) Gerenciamento de arquivos de configuração do Ansible (e exercício orientado) Execução de comandos ad hoc (e exercício orientado) Laboratório | Implantação do Ansible

Objetivos

Depois de concluir esta seção, você deverá ser capaz de descrever os conceitos do inventário do Ansible e gerenciar um arquivo de inventário estático.

Definição do inventário

O inventário define uma coleção de hosts que o Ansible gerenciará. Esses hosts também podem ser atribuídos a grupos, que podem ser gerenciados coletivamente. Os grupos podem conter grupos filhos e os hosts podem ser membros de múltiplos grupos. O inventário também pode definir variáveis que se aplicam aos hosts e aos grupos que ele definir.

Os inventários de hosts podem ser definidos de duas maneiras diferentes. Um inventário de hosts estático pode ser definido por um arquivo de texto. Um inventário de hosts dinâmico pode ser gerado por um script ou outro programa, conforme necessário, usando provedores de informações externos.

Especificação de hosts gerenciados com um inventário estático

Um arquivo de inventário estático é um arquivo de texto que especifica os hosts gerenciados aos quais o Ansible é direcionado. Você pode escrever esse arquivo usando vários formatos diferentes, incluindo formato do tipo INI ou YAML. O formato do tipo INI é muito comum e será usado na maioria dos exemplos deste curso.

Existem vários formatos de inventário estático suportados pelo Ansible. Nesta seção, estamos nos concentrando no mais comum, o formato do tipo INI.

Em sua forma mais simples, um inventário estático do tipo INI é uma lista de nomes de hosts ou endereços IP de hosts gerenciados, cada um em uma linha única:

web1.example.com
web2.example.com
db1.example.com
db2.example.com
192.0.2.42

Entretanto, normalmente, você organiza hosts gerenciados em grupos de hosts. Grupos de hosts permitem que você execute o Ansible de forma mais efetiva em uma coleção de sistemas. Nesse caso, cada seção inicia com um nome de grupo de hosts entre colchetes. ([]). Isso é seguido por um nome de host ou um endereço IP para cada host gerenciado no grupo, cada um em uma única linha.

No exemplo a seguir, o inventário de hosts define dois grupos de hosts: webservers e db-servers.

[webservers]
web1.example.com
web2.example.com
192.0.2.42
[db-servers]
db1.example.com
db2.example.com

Os hosts podem estar em vários grupos. Na verdade, é recomendável organizar seus hosts em vários grupos, possivelmente organizados de diferentes maneiras dependendo da função do host, sua localização física, se está em produção etc. Isso permite que você aplique as ações do Ansible a hosts específicos facilmente.

[webservers]
web1.example.com
web2.example.com
192.0.2.42
[db-servers]
db1.example.com
db2.example.com
[east-datacenter]
web1.example.com
db1.example.com
[west-datacenter]
web2.example.com
db2.example.com
[production]
web1.example.com
web2.example.com
db1.example.com
db2.example.com
[development]
192.0.2.42

Sempre há dois grupos de hosts:

  • O grupo de hosts all contém todos os hosts explicitamente listados no inventário.

  • O grupo de hosts ungrouped contém todos os hosts explicitamente listados no inventário e que não são membros de nenhum outro grupo.

Definição de grupos aninhados

Os inventários de hosts do Ansible podem incluir grupos de grupos de hosts. Isso pode ser feito criando um nome de grupo de hosts com o sufixo :children. O exemplo a seguir cria um novo grupo denominado north-america, que inclui todos os hosts dos grupos usa e canada.

[usa]
washington1.example.com
washington2.example.com
[canada]
ontario01.example.com
ontario02.example.com
[north-america:children]
canada
usa

Um grupo pode ter tanto hosts gerenciados quanto grupos filho como membros. Por exemplo, no inventário anterior, você pode adicionar uma seção [north-america] que tem sua própria lista de hosts gerenciados. Essa lista de hosts seria mesclada com os hosts adicionais que o grupo north-america herdar de seus grupos filho.

Simplificação das especificações de hosts com intervalos

Você pode especificar intervalos nos nomes de hosts ou endereços IP para simplificar os inventários de hosts do Ansible. Você pode especificar intervalos numéricos ou alfabéticos. Os intervalos têm a seguinte sintaxe:

[START:END]

Os intervalos correspondem a todos os valores de START até END, inclusive. Considere os seguintes exemplos:

  • 192.168.[4:7].[0:255] corresponde a todos os endereços IPv4 na rede 192.168.4.0/22 (de 192.168.4.0 até 192.168.7.255).

  • server[01:20].example.com corresponde a todos os hosts denominados server01.example.com até server20.example.com.

  • [a:c].dns.example.com corresponderá a todos os hosts denominados a.dns.example.com, b.dns.example.com e c.dns.example.com.

  • 2001:db8::[a:f] corresponde a todos os endereços IPv6 de 2001:db8::a até 2001:db8::f.

Caso zeros à esquerda sejam incluídos nos intervalos numéricos, eles serão usados no padrão. O segundo exemplo acima não corresponde a server1.example.com, mas corresponde a server07.example.com. Para ilustrar isso, o seguinte exemplo usa intervalos para simplificar as definições dos grupos [usa] e [canada] do exemplo anterior:

[usa]
washington[1:2].example.com
[canada]
ontario[01:02].example.com

Verificação do inventário

Em caso de dúvidas, use o comando ansible para verificar a presença da máquina no inventário:

[user@controlnode ~]$ ansible washington1.example.com --list-hosts
  hosts (1):
    washington1.example.com
[user@controlnode ~]$ ansible washington01.example.com --list-hosts
 [WARNING]: provided hosts list is empty, only localhost is available
  hosts (0):

Você pode executar o comando a seguir para listar todos os hosts em um grupo:

[user@controlnode ~]$ ansible canada --list-hosts
  hosts (2):
    ontario01.example.com
    ontario02.example.com

Se o inventário contém um host e um grupo de hosts com o mesmo nome, o comando ansible imprime um aviso e é direcionado ao host. O grupo de hosts é ignorado.

Há várias maneiras de lidar com essa situação, sendo a mais fácil delas garantir que os grupos de hosts não usem os mesmos nomes que os hosts no inventário.

Substituição da localização do inventário

O arquivo /etc/ansible/hosts é considerado o arquivo padrão de inventário estático do sistema. Contudo, a prática comum é não usar esse arquivo, mas definir uma localização diferente para os arquivos de inventário no arquivo de configuração do Ansible. Isso é abordado na próxima seção.

Os comandos ansible e ansible-playbook que você usará para executar os comandos ad hoc e os playbooks do Ansible posteriormente no curso também podem especificar a localização de um arquivo de inventário na linha de comando com a opção --inventory PATHNAME ou -i PATHNAME, em que PATHNAME é o caminho para o arquivo de inventário desejado.

Definição de variáveis no inventário

Os valores das variáveis usadas pelos playbooks podem ser especificados nos arquivos de inventário de host. Essas variáveis são aplicadas apenas a hosts específicos ou grupos de hosts. Normalmente, é melhor estabelecer as variáveis de inventário em diretórios especiais e não diretamente no arquivo de inventário. Esse tópico é discutido em mais profundidade em outro ponto do curso.

Descrição de um inventário dinâmico

As informações do inventário do Ansible também podem ser geradas dinamicamente, usando as informações fornecidas por bancos de dados externos. A comunidade de open source criou vários scripts de inventário dinâmico que estão disponíveis no projeto upstream do Ansible. Se esses scripts não atenderem às suas necessidades, você também poderá criar seu próprio script.

Por exemplo, um programa de inventário dinâmico poderia contatar seu servidor RedHat Satellite ou sua conta do Amazon EC2 e usar as informações armazenadas lá para construir um inventário do Ansible. Como o programa faz isso quando você executa o Ansible, ele pode preencher o inventário com informações atualizadas oferecidas pelo serviço à medida que novos hosts são adicionados e hosts antigos são removidos.

Esse tópico será discutido detalhadamente mais tarde neste curso.

britho commented 3 years ago

Neste exercício, você criará um novo inventário estático contendo hosts e grupos.

Resultados

Você deverá ser capaz de criar inventários estáticos padrão e personalizados.

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab deploy-inventory start. Esse script de inicialização garante que os hosts gerenciados, servera, serverb, serverc e serverd, estejam visíveis na rede.

[student@workstation ~]$ lab deploy-inventory start
  1. Altere /etc/ansible/hosts para incluir servera.lab.example.com como um host gerenciado.

    1. Adicione servera.lab.example.com ao final do arquivo de inventário padrão, /etc/ansible/hosts.

      [student@workstation ~]$ sudo vim /etc/ansible/hosts
      ...output omitted...
      ## db-[99:101]-node.example.com
      servera.lab.example.com
    2. Continue editando o arquivo de inventário /etc/ansible/hosts adicionando um grupo [webservers] à parte inferior do arquivo com o servidor serverb.lab.example.com como membro do grupo.

      [student@workstation ~]$ sudo vim /etc/ansible/hosts
      ...output omitted...
      ## db-[99:101]-node.example.com
      servera.lab.example.com
      [webservers]
      serverb.lab.example.com
  2. Verifique os hosts gerenciados no arquivo de inventário /etc/ansible/hosts.

    1. Use o comando ansible all --list-hosts para listar todos os hosts gerenciados no arquivo de inventário padrão.

      [student@workstation ~]$ ansible all --list-hosts
        hosts (2):
          servera.lab.example.com
          serverb.lab.example.com
    2. Use o comando ansible ungrouped --list-hosts para listar apenas os hosts gerenciados que não pertencem a um grupo.

      [student@workstation ~]$ ansible ungrouped --list-hosts
        hosts (1):
          servera.lab.example.com
    3. Use o comando ansible webservers --list-hosts para listar apenas os hosts gerenciados que pertencem ao grupo webservers.

      [student@workstation ~]$ ansible webservers --list-hosts
        hosts (1):
          serverb.lab.example.com
  3. Crie um arquivo de inventário estático personalizado chamado inventory no diretório de trabalho /home/student/deploy-inventory.

    As informações sobre seus quatro hosts gerenciados estão listadas na tabela a seguir. Você atribuirá cada host a vários grupos para fins de gerenciamento com base na finalidade do host, na cidade em que está localizado e no ambiente de implantação ao qual ele pertence.

    Além disso, os grupos de cidades dos EUA (Raleigh e Mountain View) devem ser configurados como filhos do grupo us de modo que os hosts nos Estados Unidos possam ser gerenciados como um grupo.

    Nome do host | Finalidade | Local | Ambiente -- | -- | -- | -- servera.lab.example.com | Servidor web | Raleigh | Development serverb.lab.example.com | Servidor web | Raleigh | Testing serverc.lab.example.com | Servidor web | Mountain View | Production serverd.lab.example.com | Servidor web | Londres | Production

    1. Crie o diretório de trabalho /home/student/deploy-inventory.

      [student@workstation ~]$ mkdir ~/deploy-inventory
    2. Cria o arquivo inventory no diretório de trabalho /home/student/deploy-inventory. Use a tabela Especificações de inventários de servidor como guia. Edite o arquivo inventory e adicione o seguinte conteúdo:

      [student@workstation ~]$ cd ~/deploy-inventory
      [student@workstation deploy-inventory]$ vim inventory
      [webservers]
      server[a:d].lab.example.com
      [raleigh]
      servera.lab.example.com
      serverb.lab.example.com
      [mountainview]
      serverc.lab.example.com
      [london]
      serverd.lab.example.com
      [development]
      servera.lab.example.com
      [testing]
      serverb.lab.example.com
      [production]
      serverc.lab.example.com
      serverd.lab.example.com
      [us:children]
      raleigh
      mountainview
  4. Use variações do comando ansible host-or-group -i inventory --list-hosts para verificar os hosts gerenciados e grupos no arquivo de inventário /home/student/deploy-inventory/inventory personalizado.

    Seu comando ansible deve incluir a opção -i inventory. Assim, ansible usará seu arquivo inventory no diretório de trabalho atual em vez do arquivo de inventário /etc/ansible/hosts do sistema.

    1. Use o comando ansible all -i inventory --list-hosts para listar todos os hosts gerenciados.

      [student@workstation deploy-inventory]$ ansible all -i inventory --list-hosts
        hosts (4):
          servera.lab.example.com
          serverb.lab.example.com
          serverc.lab.example.com
          serverd.lab.example.com
    2. Use o comando ansible ungrouped -i inventory --list-hosts para listar todos os hosts gerenciados listados no arquivo de inventário, mas que não fazem parte de um grupo. Não há hosts gerenciados sem grupo nesse arquivo de inventário.

      [student@workstation deploy-inventory]$ ansible ungrouped -i inventory \
      > --list-hosts
       [WARNING]: No hosts matched, nothing to do
        hosts (0):
    3. Use o comando ansible development -i inventory --list-hosts para listar todos os hosts gerenciados incluídos no grupo development.

      [student@workstation deploy-inventory]$ ansible development -i inventory \
      > --list-hosts
        hosts (1):
          servera.lab.example.com
    4. Use o comando ansible testing -i inventory --list-hosts para listar todos os hosts gerenciados incluídos no grupo testing.

      [student@workstation deploy-inventory]$ ansible testing -i inventory \
      > --list-hosts
        hosts (1):
          serverb.lab.example.com
    5. Use o comando ansible production -i inventory --list-hosts para listar todos os hosts gerenciados incluídos no grupo production.

      [student@workstation deploy-inventory]$ ansible production -i inventory \
      > --list-hosts
        hosts (2):
          serverc.lab.example.com
          serverd.lab.example.com
    6. Use o comando ansible us -i inventory --list-hosts para listar todos os hosts gerenciados incluídos no grupo us.

      [student@workstation deploy-inventory]$ ansible us -i inventory --list-hosts
        hosts (3):
          servera.lab.example.com
          serverb.lab.example.com
          serverc.lab.example.com
    7. É recomendável experimentar outras variações para confirmar as entradas de hosts gerenciados no arquivo de inventário personalizado.

Encerramento

Na workstation, execute o script lab deploy-inventory finish para limpar este exercício.

[student@workstation ~]$ lab deploy-inventory finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, você deverá ser capaz de descrever onde os arquivos de configuração do Ansible estão localizados, dizer como eles são selecionados pelo Ansible e saber editá-los para aplicar alterações às configurações padrão.

Configuração do Ansible

O comportamento de uma instalação do Ansible pode ser personalizado com a modificação das definições do arquivo de configuração do Ansible. O Ansible seleciona seu arquivo de configuração de uma das várias localizações possíveis no nó de controle.

Uso do /etc/ansible/ansible.cfg

O pacote ansible oferece um arquivo de configuração de base localizado em /etc/ansible/ansible.cfg. Esse arquivo é utilizado caso nenhum outro arquivo de configuração seja encontrado.

Uso do ~/.ansible.cfg

O Ansible procura por um arquivo .ansible.cfg no diretório pessoal do usuário. Essa configuração será usada no lugar de /etc/ansible/ansible.cfg se ele existir e se não houver nenhum arquivo ansible.cfg no diretório de trabalho atual.

Uso do ./ansible.cfg

Se existir um arquivo ansible.cfg no diretório no qual o comando ansible for executado, ele será usado em vez do arquivo global ou do arquivo pessoal do usuário. Isso permite que os administradores criem uma estrutura de diretórios em que diferentes ambientes ou projetos são armazenados em diretórios separados, em que cada diretório contém um arquivo de configuração criado com um conjunto exclusivo de configurações.

A prática recomendada é criar um arquivo ansible.cfg em um diretório a partir do qual você possa executar comandos do Ansible. Esse diretório também deve conter qualquer arquivo usado por seu projeto do Ansible, como um inventário e um playbook. Essa é a localização mais comumente utilizada para o arquivo de configuração do Ansible. Não é comum usar um arquivo ~/.ansible.cfg ou /etc/ansible/ansible.cfg na prática.

Uso da variável de ambiente ANSIBLE_CONFIG

Você pode utilizar diferentes arquivos de configuração colocando-os em diretórios distintos e posteriormente executando comandos do Ansible a partir do diretório apropriado, mas esse método pode ser restritivo e difícil de gerenciar conforme o número de arquivos de configuração aumenta. Uma opção mais flexível é definir a localização do arquivo de configuração com a variável de ambiente ANSIBLE_CONFIG. Quando a variável é definida, o Ansible utiliza o arquivo de configuração especificado pela variável em vez de qualquer outro arquivo de configuração mencionado anteriormente.

Precedência do arquivo de configuração

A ordem de pesquisa por um arquivo de configuração é o inverso da lista anterior. O Ansible seleciona o primeiro arquivo localizado na ordem de pesquisa. O Ansible só usa as definições de configuração do primeiro arquivo que encontra.

Qualquer arquivo especificado pela variável de ambiente ANSIBLE_CONFIG substitui todos os outros arquivos de configuração. Se essa variável não for definida, será verificado se há um arquivo ansible.cfg no diretório no qual o comando ansible foi executado. Se tal arquivo não estiver presente, será verificado se há um arquivo .ansible.cfg no diretório pessoal do usuário. O arquivo /etc/ansible/ansible.cfg global só é utilizado caso nenhum outro arquivo de configuração seja encontrado. Se o arquivo de configuração /etc/ansible/ansible.cfg não estiver presente, o Ansible contém padrões que ele usa.

Devido às múltiplas localizações em que os arquivos de configuração do Ansible podem ser colocados, talvez seja confuso saber qual arquivo de configuração está sendo usado pelo Ansible. Você pode executar o comando ansible --version para identificar claramente qual versão do Ansible está instalada e qual arquivo de configuração está sendo usado.

[user@controlnode ~]$ ansible --version
ansible 2.8.0
  config file = /etc/ansible/ansible.cfg
...output omitted...

Outra forma de exibir o arquivo de configuração ativo do Ansible é usar a opção -v ao executar comandos do Ansible na linha de comando.

[user@controlnode ~]$ ansible servers --list-hosts -v
Using /etc/ansible/ansible.cfg as config file
...output omitted...

O Ansible só usa as definições do arquivo de configuração de maior precedência. Mesmo que existam outros arquivos com menor precedência, suas definições são ignoradas e não são combinadas com as do arquivo de configuração selecionado. Portanto, se você escolher criar seu próprio arquivo de configuração a favor do arquivo de configuração global /etc/ansible/ansible.cfg, você precisará duplicar todas as definições desejadas desse arquivo no arquivo de configuração de nível de usuário. As configurações não definidas no arquivo de configuração de nível de usuário permanecerão definidas conforme os padrões integrados, mesmo que estejam definidas com outro valor no arquivo de configuração global.

Gerenciamento de definições no arquivo de configuração

O arquivo de configuração do Ansible consiste em várias seções, e cada uma contém configurações definidas como pares de chave-valor. Os títulos de seções estão entre colchetes. Para a operação básica, use estas duas seções:

  • [defaults] define padrões para as operações do Ansible.

  • [privilege_escalation] configura como o Ansible realiza o escalonamento de privilégios nos hosts gerenciados.

Por exemplo, este é um arquivo ansible.cfg típico:

[defaults]
inventory = ./inventory
remote_user = user
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

As diretivas do arquivo são explicadas na seguinte tabela:

Diretiva | Descrição -- | -- inventory | Especifica o caminho para o arquivo de inventário. remote_user | O nome do usuário a ser usado para fazer login nos hosts gerenciados. Se não for especificado, o nome do usuário atual será usado. ask_pass | Se uma senha SSH será solicitada ou não. Pode ser false se for usada a autenticação de chave pública SSH. become | Se o usuário será alternado automaticamente no host gerenciado (geralmente, para root) depois de se conectar. Isso também pode ser especificado por uma ação. become_method | Como a troca de usuário será feita (geralmente sudo, que é o padrão, mas su é uma opção). become_user | O usuário para o qual será alternado no host gerenciado (geralmente, root, que é o padrão). become_ask_pass | Se uma senha será solicitada para seu become_method. O padrão é false.

Configuração de conexões

O Ansible precisa saber como se comunicar com seus hosts gerenciados. Uma das razões mais comuns para alterar o arquivo de configuração é controlar quais métodos e usuários o Ansible utiliza para administrar os hosts gerenciados. Algumas das informações necessárias incluem:

  • O local onde está o inventário que lista os hosts gerenciados e os grupos de hosts.

  • Qual protocolo de conexão será usado para se comunicar com os hosts gerenciados (por padrão, SSH) e se uma porta de rede não padrão será necessária para se conectar com o servidor.

  • Qual usuário remoto usar nos hosts gerenciados; este poderia ser root ou poderia ser um usuário sem privilégios

  • Se o usuário remoto não tiver privilégios suficientes, o Ansible precisa saber se ele deve tentar escalonar privilégios para root e como fazê-lo (por exemplo, usando o sudo).

  • Se ele deve ou não solicitar uma senha SSH ou uma senha do sudo para fazer login ou obter privilégios

Localização do inventário

Na seção [defaults], a diretiva inventory pode apontar diretamente para um arquivo de inventário estático ou para um diretório contendo vários arquivos de inventário estático e scripts de inventário dinâmico.

[defaults]
inventory = ./inventory

Configurações de conexão

Por padrão, o Ansible se conecta aos hosts gerenciados usando o protocolo SSH. Os parâmetros mais importantes que controlam como o Ansible se conecta aos hosts gerenciados estão definidos na seção [defaults].

Por padrão, o Ansible tenta se conectar ao host gerenciado usando o mesmo nome de usuário que o usuário local executando os comandos do Ansible. Para especificar um usuário remoto diferente, defina o parâmetro remote_user com esse nome de usuário.

Se o usuário local que está executando o Ansible tiver chaves SSH configuradas que permitam que ele faça a autenticação como usuário remoto nos hosts gerenciados, o Ansible fará o login automaticamente. Se esse não for o caso, você poderá configurar o Ansible para solicitar a senha do usuário local usada pelo usuário remoto definindo a diretiva ask_pass = true.

[defaults]
inventory = ./inventory
remote_user = root
ask_pass = true

Presumindo que você esteja usando o nó de controle do Linux e o OpenSSH em seus hosts gerenciados, se você puder fazer login como usuário remoto com uma senha, você provavelmente poderá configurar a autenticação SSH baseada em chave, que permitirá que você defina ask_pass = false.

A primeira etapa é certificar-se de que o usuário no nó de controle tem um par de chaves SSH configurado em ~/.ssh. Você pode executar o comando ssh-keygen para fazer isso.

Para um único host gerenciado existente, você pode instalar sua chave pública no host gerenciado e usar o comando ssh-copy-id para preencher o arquivo ~/.ssh/known_hosts local com sua chave do host da seguinte forma:

[user@controlnode ~]$ ssh-copy-id root@web1.example.com
The authenticity of host 'web1.example.com (192.168.122.181)' can't be established.
ECDSA key fingerprint is 70:9c:03:cd:de:ba:2f:11:98:fa:a0:b3:7c:40:86:4b.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@web1.example.com's password:
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'root@web1.example.com'"
and check to make sure that only the key(s) you wanted were added.

Você também pode utilizar um playbook do Ansible para implantar sua chave pública na conta remote_user em todos os hosts gerenciados usando o módulo authorized_key.

Este curso ainda não abordou os playbooks do Ansible em detalhes. Uma ação que garante que sua chave pública seja implantada nas contas root dos hosts gerenciados pode aparecer desta forma:

- name: Public key is deployed to managed hosts for Ansible
  hosts: all
  tasks:
    - name: Ensure key is in root's ~/.ssh/authorized_hosts
      authorized_key:
        user: root
        state: present
        key: '{{ item }}'
      with_file:
        - ~/.ssh/id_rsa.pub

Como o host gerenciado ainda não teria a autenticação SSH baseada em chave configurada, você precisa executar o playbook usando o comando ansible-playbook com a opção --ask-pass para que o comando seja autenticado como usuário remoto.

Escalonamento de privilégios

Por razões de segurança, talvez o Ansible precise se conectar a hosts remotos como usuário sem privilégios antes de escalonar privilégios para obter acesso administrativo como root. Isso pode ser configurado na seção [privilege_escalation] do arquivo de configuração do Ansible.

Para habilitar o escalonamento de privilégios por padrão, defina a diretiva become = true no arquivo de configuração. Mesmo se estiver definido por padrão, há várias maneiras de substituí-lo executando comandos ad hoc ou playbooks do Ansible. (Por exemplo, pode haver momentos em que você queira executar uma tarefa ou ação que não escalona privilégios.)

A diretiva become_method especifica como escalonar privilégios. Há várias opções disponíveis, mas o padrão é usar sudo. Do mesmo modo, a diretiva become_user especifica a qual usuário escalonar, mas o padrão é root.

Se o mecanismo become_method escolhido precisar que o usuário insira uma senha para escalonar privilégios, você pode definir a diretiva become_ask_pass = true no arquivo de configuração.

No RedHat Enterprise Linux7, a configuração padrão de /etc/sudoers concede a todos os usuários do grupo wheel a capacidade de usar o sudo para se tornar root depois de inserir a senha.

Uma maneira de permitir que um usuário (someuser no exemplo a seguir) use o sudo para se tornar root sem uma senha é instalar um arquivo com as diretivas apropriadas no diretório /etc/sudoers.d (de propriedade do root com permissões octais 0400):

## password-less sudo for Ansible user
someuser ALL=(ALL) NOPASSWD:ALL

Pense bem sobre as implicações de segurança de qualquer abordagem que você escolha para fazer escalonamento de privilégios. Diferentes organizações e implantações podem ter contrapartidas a serem consideradas.

O arquivo ansible.cfg de exemplo abaixo presume que você pode se conectar aos hosts gerenciados como someuser usando autenticação SSH baseada em chaves e que o someuser pode usar sudo para executar comandos como root sem inserir uma senha:

[defaults]
inventory = ./inventory
remote_user = someuser
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

Conexões não SSH

O protocolo usado pelo Ansible para se conectar com hosts gerenciados é definido por padrão como smart, o que determina a maneira mais eficiente de usar o SSH. Isso pode ser definido como outros valores de várias maneiras.

Por exemplo, há uma exceção à regra que o SSH é usado por padrão. Se você não tiver localhost em seu inventário, o Ansible definirá uma entrada de host local implícito para permitir a execução de comandos ad hoc e playbooks direcionados a localhost. Essa entrada especial de inventário não é incluída nos grupos de hosts all ou ungrouped. Além disso, em vez de usar o tipo de conexão SSH smart, o Ansible se conecta a ele usando o tipo de conexão especial local por padrão.

[user@controlnode ~]$ ansible localhost --list-hosts
[WARNING]: provided hosts list is empty, only localhost is available
  hosts (1):
    localhost

O tipo de conexão local ignora a definição remote_user e executa comandos diretamente no sistema local. Se o escalonamento de privilégios estiver sendo usado, ele executa o sudo da conta de usuário que executou o comando do Ansible, não o remote_user. Isso pode gerar confusão se os dois usuários tiverem privilégios sudo diferentes.

Se você quiser garantir que você se conecta ao localhost usando o SSH como outros hosts gerenciados, uma abordagem é listá-lo em seu inventário. Mas isso o inclui nos grupos all e ungrouped, o que talvez não seja recomendável.

Outra abordagem é alterar o protocolo usado para se conectar ao localhost. A melhor maneira de fazer isso é definir a ansible_connection variável de host como localhost. Para fazer isso, no diretório no qual você executa comandos do Ansible, crie um subdiretório host_vars. Nesse subdiretório, crie um arquivo denominado localhost, contendo a linha ansible_connection: smart. Isso garante que o protocolo de conexão (SSH) smart seja usado em vez do local para localhost.

Você também pode usar essa abordagem ao contrário. Se você tiver 127.0.0.1 listado em seu inventário, por padrão, você se conectará a ele usando smart. Você também pode criar um arquivo host_vars/127.0.0.1 contendo a linha ansible_connection: local, e ele usará, em vez disso, local.

As variáveis de host serão abordadas em mais detalhes posteriormente neste curso.

Também é possível usar variáveis de grupo para alterar o tipo de conexão de todo um grupo de hosts. Isso pode ser feito colocando arquivos com o mesmo nome que o grupo em um diretório group_vars e garantindo que tais arquivos contenham as configurações para as variáveis de conexão.

Por exemplo, é recomendável que todos os seus hosts gerenciados pelo Microsoft Windows usem o protocolo winrm e a porta 5986 para as conexões. Para configurar isso, você precisa colocar todos esses hosts gerenciados no grupo windows e, depois, criar um arquivo denominado group_vars/windows contendo as seguintes linhas:

ansible_connection: winrm
ansible_port: 5986

Comentários de arquivos de configuração

Há dois caracteres de comentário permitidos pelos arquivos de configuração do Ansible: a cerquilha, ou jogo da velha (#), e o ponto-e-vírgula (;).

O caractere de jogo da velha no início de uma linha faz com que toda a linha seja interpretada como um comentário. Ele não deve estar na mesma linha que uma diretiva.

O caractere de ponto-e-vírgula faz com que tudo que esteja à direita dele na linha seja interpretado como comentário. Ele pode estar na mesma linha que uma diretiva, desde que essa diretiva esteja à sua esquerda.

Páginas do man ansible(1), ansible-config(1), ssh-keygen(1) e ssh-copy-id(1)

Configuration file: Ansible Documentation

britho commented 3 years ago

Neste exercício, você personalizará o ambiente do Ansible editando o arquivo de configuração do Ansible.

Resultados

Você deverá ser capaz de criar um arquivo de configuração para definir o ambiente do Ansible com configurações personalizadas persistentes.

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab deploy-manage start. Esse script garante que o host gerenciado, servera, seja acessível na rede.

[student@workstation ~]$ lab deploy-manage start

Crie o diretório /home/student/deploy-manage, que conterá os arquivos deste exercício. Altere-o para esse diretório criado recentemente.

[student@workstation ~]$ mkdir ~/deploy-manage
[student@workstation ~]$ cd ~/deploy-manage

No diretório /home/student/deploy-manage, use um editor de texto para começar a editar um novo arquivo, ansible.cfg.

Crie uma seção [defaults] nesse arquivo. Nessa seção, adicione uma linha que usa a diretiva inventory para especificar o arquivo ./inventory como o inventário padrão.

[defaults]
inventory = ./inventory

Salve seu trabalho e feche o editor de texto.

No diretório /home/student/deploy-manage, use um editor de texto para começar a editar o novo arquivo de inventário estático, inventory.

O inventário estático deverá conter quatro grupos de host:

    O [myself] deverá conter o host localhost.

    O [intranetweb] deverá conter o host servera.lab.example.com.

    O [internetweb] deverá conter o host serverb.lab.example.com.

    O [web] deverá conter os grupos de host intranetweb e internetweb. 

    Em /home/student/deploy-manage/inventory, crie o grupo de hosts myself adicionando as seguintes linhas:

    [myself]
    localhost

    Em /home/student/deploy-manage/inventory, crie o grupo de host intranetweb adicionando as seguintes linhas:

    [intranetweb]
    servera.lab.example.com

    Em /home/student/deploy-manage/inventory, crie o grupo de host internetweb adicionando as seguintes linhas:

    [internetweb]
    serverb.lab.example.com

    Em /home/student/deploy-manage/inventory, crie o grupo de host web adicionando as seguintes linhas:

    [web:children]
    intranetweb
    internetweb

    Confirme se o seu arquivo final inventory é semelhante ao seguinte:

    [myself]
    localhost

    [intranetweb]
    servera.lab.example.com

    [internetweb]
    serverb.lab.example.com

    [web:children]
    intranetweb
    internetweb

    Salve seu trabalho e feche o editor de texto. 

Use o comando ansible com a opção --list-hosts para testar a configuração dos grupos de hosts de seu arquivo de inventário. Na verdade, isso não faz a conexão com esses hosts.

[student@workstation deploy-manage]$ ansible myself --list-hosts
  hosts (1):
    localhost
[student@workstation deploy-manage]$ ansible intranetweb --list-hosts
  hosts (1):
    servera.lab.example.com
[student@workstation deploy-manage]$ ansible internetweb --list-hosts
  hosts (1):
    serverb.lab.example.com
[student@workstation deploy-manage]$ ansible web --list-hosts
  hosts (2):
    servera.lab.example.com
    serverb.lab.example.com
[student@workstation deploy-manage]$ ansible all --list-hosts
  hosts (3):
    localhost
    servera.lab.example.com
    serverb.lab.example.com

Abra o arquivo /home/student/deploy-manage/ansible.cfg em um editor de texto. Adicione uma seção [privilege_escalation] para configurar o Ansible para usar automaticamente o comando sudo para alternar de student para root ao executar tarefas nos hosts gerenciados. O Ansible também deverá ser configurado para solicitar a senha que o student usa para o comando sudo.

    Crie a seção [privilege_escalation] no arquivo de configuração /home/student/deploy-manage/ansible.cfg adicionando a seguinte entrada:

    [privilege_escalation]

    Ative o escalonamento de privilégios definindo a diretiva become como true.

    become = true

    Configure o escalonamento de privilégios para que use o comando sudo definindo a diretiva become_method como sudo.

    become_method = sudo

    Configure o usuário do escalonamento de privilégios definindo a diretiva become_user como root.

    become_user = root

    Ative a solicitação da senha de escalonamento de privilégios definindo a diretiva become_ask_pass como true.

    become_ask_pass = true

    Confirme se o arquivo ansible.cfg completo é semelhante ao seguinte:

    [defaults]
    inventory = ./inventory

    [privilege_escalation]
    become = true
    become_method = sudo
    become_user = root
    become_ask_pass = true

    Salve seu trabalho e feche o editor de texto. 

Execute o comando ansible --list-hosts novamente e verifique se agora a senha sudo será solicitada.

Quando solicitado pela senha do sudo, digite student, mesmo que o usuário não seja usado para esta simulação.

[student@workstation deploy-manage]$ ansible intranetweb --list-hosts
BECOME password: student
  hosts (1):
    servera.lab.example.com

Encerramento

Na workstation, execute o script lab deploy-manage finish para limpar este exercício.

[student@workstation ~]$ lab deploy-manage finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, você deverá ser capaz de executar uma só tarefa de automação do Ansible usando um comando ad hoc e explicar alguns casos de uso de comandos ad hoc.

Execução de comandos ad hoc com o Ansible

Um comando ad hoc é uma maneira de executar rapidamente uma única tarefa do Ansible que você não precisa salvar para que seja executada novamente depois. Consiste em operações simples e on-line que podem ser executadas sem escrever um playbook.

Os comandos ad hoc são úteis para testes e alterações rápidas. Por exemplo, você pode usar um comando ad hoc para garantir que uma determinada linha exista no arquivo /etc/hosts em um grupo de servidores. Você pode usar outro comando ad hoc para reiniciar de forma eficiente um serviço em muitas máquinas diferentes ou para garantir que um pacote de software específico esteja atualizado.

Comandos ad hoc são muito úteis para realizar rapidamente tarefas simples com o Ansible. Eles têm limitações e, em geral, é recomendável usar os playbooks do Ansible para aproveitar todo o seu potencial. No entanto, em muitas situações, os comandos ad hoc são exatamente a ferramenta de que você precisa para realizar tarefas simples com rapidez.

Execução de comandos ad hoc

Use o comando ansible para executar comandos ad hoc:

ansible host-pattern -m module [-a 'module arguments'] [-i inventory]

O argumento host-pattern é usado para especificar os hosts gerenciados nos quais o comando ad hoc deve ser executado. Pode ser um host gerenciado ou grupo de hosts específico no inventário. Você já viu esse argumento sendo usado em conjunto com a opção --list-hosts, que mostra quais hosts são correspondidos por um padrão de host em particular. Você também já viu que pode usar a opção -i para especificar uma localização de inventário a ser usada diferente da localização padrão no arquivo de configuração atual do Ansible.

A opção -m usa como argumento o nome do módulo que o Ansible deve executar nos hosts de destino. Os módulos são pequenos programas que são executados para implementar sua tarefa. Alguns módulos não precisam de informações adicionais, mas outros precisam de argumentos adicionais para especificar os detalhes de suas operações. A opção -a recebe uma lista desses argumentos como uma string entre aspas.

Um dos comandos ad hoc mais simples usa o módulo ping. Esse módulo não executa um ping ICMP, mas verifica se você pode executar os módulos baseados em Python nos hosts gerenciados. Por exemplo, o seguinte comando ad hoc determina se todos os hosts gerenciados no inventário podem executar módulos padrão:

[user@controlnode ~]$ ansible all -m ping
servera.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

Realização de tarefas com módulos usando comandos ad hoc

Os módulos são ferramentas que os comandos ad hoc usam para realizar tarefas. O Ansible oferece centenas de módulos que fazem diferentes coisas. Você normalmente pode encontrar um módulo de propósito especial testado que faz o que você precisa como parte da instalação padrão.

O comando ansible-doc -l lista todos os módulos que estão instalados no sistema. Você pode usar ansible-doc para visualizar a documentação de módulos em particular por nome e encontrar informações sobre quais argumentos os módulos recebem como opções. Por exemplo, o seguinte comando exibe a documentação do módulo ping:

[user@controlnode ~]$ ansible-doc ping
> PING    (/usr/lib/python3.6/site-packages/ansible/modules/system/ping.py)
        A trivial test module, this module always returns `pong' on successful contact. It does not make sense in playbooks, but it is useful from `/usr/bin/ansible' to
        verify the ability to login and that a usable Python is configured. This is NOT ICMP ping, this is just a trivial test module that requires Python on the
        remote-node. For Windows targets, use the [win_ping] module instead. For Network targets, use the [net_ping] module instead.
  * This module is maintained by The Ansible Core Team
OPTIONS (= is mandatory):
- data
        Data to return for the `ping' return value.
        If this parameter is set to `crash', the module will cause an exception.
        [Default: pong]
        type: str
SEE ALSO:
      * Module net_ping
           The official documentation on the net_ping module.
           https://docs.ansible.com/ansible/latest/modules/net_ping_module.html
      * Module win_ping
           The official documentation on the win_ping module.
           https://docs.ansible.com/ansible/latest/modules/win_ping_module.html
AUTHOR: Ansible Core Team, Michael DeHaan
        METADATA:
          status:
          - stableinterface
          supported_by: core
EXAMPLES:
# Test we can logon to 'webservers' and execute python with json lib.
# ansible webservers -m ping
# Example from an Ansible Playbook
- ping:
# Induce an exception to see what happens
- ping:
    data: crash
RETURN VALUES:
ping:
    description: value provided with the data parameter
    returned: success
    type: str
    sample: pong

Para saber mais sobre módulos, acesse a documentação on-line do Ansible em http://docs.ansible.com/ansible/latest/modules/modules_by_category.html.

A tabela a seguir lista vários módulos úteis como exemplos. Existem muitos outros.

Categoria dos módulos | Módulos -- | -- Módulos de arquivos | copy: copiar um arquivo local para o host gerenciado. file: definir permissões e outras propriedades dos arquivos. lineinfile: garantir que uma linha específica esteja ou não em um arquivo. synchronize: sincronizar o conteúdo usando rsync. Módulos de pacote de software | package: gerenciar pacotes usando o gerenciador de pacotes detectado automaticamente e nativo do sistema operacional. yum: gerenciar pacotes usando o gerenciador de pacotes YUM. apt: gerenciar pacotes usando o gerenciador de pacotes APT. dnf: gerenciar pacotes usando o gerenciador de pacotes DNF. gem: gerenciar gems do Ruby pip: gerenciar pacotes do Python a partir de PyPI. Módulos do sistema | firewalld: gerenciar portas e serviços arbitrários usando firewalld. reboot: reinicializar uma máquina service: gerenciar serviços user: adicionar, remover e gerenciar contas de usuários Módulos Net-tools | get_url: fazer o download de arquivos via HTTP, HTTPS ou FTP nmcli: gerenciar redes uri: interagir com os serviços Web

A maioria dos módulos recebe argumentos. A lista de argumentos disponíveis para um módulo pode ser encontrada na documentação do módulo. Comandos ad hoc passam argumentos para módulos usando a opção -a. Quando não forem necessários argumentos, omita a opção -a do comando ad hoc. Se vários argumentos precisarem ser especificados, forneça-os como uma lista com aspas separada por espaços.

Por exemplo, o seguinte comando ad hoc usa o módulo user para garantir que o usuário newbie exista e tenha a UID 4000 no servera.lab.example.com:

[user@controlnode ~]$ ansible -m user -a 'name=newbie uid=4000 state=present' \
> servera.lab.example.com
servera.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "comment": "",
    "createhome": true,
    "group": 4000,
    "home": "/home/newbie",
    "name": "newbie",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 4000
}

A maioria dos módulos é idempotente, o que significa que eles podem ser executados de forma segura várias vezes e, se o sistema já estiver no estado correto, eles não fazem nada. Por exemplo, se você executar o comando ad hoc anterior novamente, ele não relatará alterações:

[user@controlnode ~]$ ansible -m user -a 'name=newbie uid=4000 state=present' \
> servera.lab.example.com
servera.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "append": false,
    "changed": false
    "comment": "",
    "group": 4000,
    "home": "/home/newbie",
    "move_home": false,
    "name": "newbie",
    "shell": "/bin/bash",
    "state": "present",
    "uid": 4000
}

Execução de comandos arbitrários em hosts gerenciados

O módulo command permite que os administradores executem comandos arbitrários na linha de comando de hosts gerenciados. O comando a ser executado é especificado como um argumento no módulo usando a opção -a. Por exemplo, o comando a seguir executa o comando hostname nos hosts gerenciados referenciados pelo padrão de host mymanagedhosts.

[user@controlnode ~]$ ansible mymanagedhosts -m command -a /usr/bin/hostname
host1.lab.example.com | CHANGED | rc=0 >>
host1.lab.example.com
host2.lab.example.com | CHANGED | rc=0 >>
host2.lab.example.com

O exemplo de comando ad hoc anterior retornou duas linhas de saída para cada host gerenciado. A primeira linha é um relatório de status, mostrando o nome do host gerenciado no qual a operação ad hoc foi realizada, assim como o resultado da operação. A segunda linha é a saída do comando executado remotamente usando o módulo command do Ansible.

Para melhor legibilidade e análise da saída do comando ad hoc, os administradores poderão achar útil ter uma única linha de saída para cada operação realizada em um host gerenciado. Use a opção -o para exibir a saída dos comandos ad hoc do Ansible no formato de linha única.

[user@controlnode ~]$ ansible mymanagedhosts -m command -a /usr/bin/hostname -o
host1.lab.example.com | CHANGED | rc=0 >> (stdout) host1.lab.example.com
host2.lab.example.com | CHANGED | rc=0 >> (stdout) host2.lab.example.com

O módulo command permite que os administradores executem rapidamente comandos remotos em hosts gerenciados. Esses comandos não são processados pelo shell nos hosts gerenciados. Desse modo, eles não podem acessar as variáveis do ambiente de shell nem realizar operações de shell, como redirecionamento e pipes.

Se um comando ad hoc não especificar qual módulo usar com a opção -m, o RedHat Ansible Engine usa o módulo command por padrão.

Para situações nas quais os comandos requerem processamento de shell, os administradores podem usar o módulo de shell. Da mesma forma que o módulo command, você transmite os comandos para que sejam executados como argumentos do módulo no comando ad hoc. Então, o Ansible executa o comando remotamente nos hosts gerenciados. Diferentemente do módulo command, os comandos são processados por meio de um shell nos hosts gerenciados. Portanto, as variáveis do ambiente de shell estão disponíveis, e as operações de shell, como redirecionamento e pipes, também estão disponíveis para uso.

O exemplo a seguir ilustra a diferença entre os módulos command e shell. Se você tentar executar o comando bash incorporado set com esses dois módulos, ele terá êxito apenas com o módulo shell.

[user@controlnode ~]$ ansible localhost -m command -a set
localhost | FAILED | rc=2 >>
[Errno 2] No such file or directory
[user@controlnode ~]$ ansible localhost -m shell -a set
localhost | CHANGED | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interact
ive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
...output omitted...

Os módulos command e shell precisam ter uma instalação do Python em funcionamento no host gerenciado. Um terceiro módulo, raw, pode executar comandos diretamente no shell remoto, ignorando o subsistema do módulo. Isso é útil ao gerenciar sistemas que não podem ter o Python instalado (por exemplo, um roteador de rede). Também pode ser usado para instalar o Python em um host.

Na maioria das circunstâncias, é recomendável que você evite os módulos "run command" command, shell e raw.

A maioria dos outros módulos são idempotentes e podem realizar rastreamento de alterações automaticamente. Eles podem testar o estado dos sistemas e não fazer nada se esses sistemas já se encontrarem no estado correto. Por outro lado, é muito mais complicado usar módulos "run command" de uma forma que seja idempotente. Depender deles torna difícil garantir que uma nova execução de um comando ad hoc ou playbook não provocará uma falha inesperada. Quando um módulo shell ou command é executado, ele geralmente informa o status CHANGED se detectar que afetou o estado da máquina.

Há momentos em que os módulos "run command" são ferramentas valiosas e uma boa solução para um problema. Se você precisar usá-los, provavelmente será melhor tentar usar o módulo command primeiro, recorrendo aos módulos shell ou raw somente se precisar dos seus recursos especiais.

Configuração de conexões de comandos ad hoc

As diretivas de conexões com hosts gerenciados e de escalonamento de privilégios podem ser definidas no arquivo de configuração do Ansible ou usando opções dos comandos ad hoc. Quando definidas usando opções dos comandos ad hoc, elas têm precedência sobre a diretiva estabelecida no arquivo de configuração do Ansible. A tabela a seguir mostra as opções de linha de comando análogas para cada diretiva do arquivo de configuração.

Diretivas do arquivo de configuração | Opção de linha de comando -- | -- inventory | -i remote_user | -u become | --become, -b become_method | --become-method become_user | --become-user become_ask_pass | --ask-become-pass, -K

Antes de definir essas diretivas usando opções de linha de comando, os valores definidos atualmente podem ser determinados por meio da consulta da saída de ansible --help.

[user@controlnode ~]$ ansible --help
...output omitted...
  -b, --become          run operations with become (nopasswd implied)
  --become-method=BECOME_METHOD
                        privilege escalation method to use (default=sudo),
                        valid choices: [ sudo | su | pbrun | pfexec | runas |
                        doas ]
  --become-user=BECOME_USER
...output omitted...
  -u REMOTE_USER, --user=REMOTE_USER
                        connect as this user (default=None)
britho commented 3 years ago

Neste exercício, você executará comandos ad hoc em vários hosts gerenciados.

Resultados

Você deverá ser capaz de executar comandos em hosts gerenciados de maneira ad hoc usando o escalonamento de privilégios.

Você executará comandos ad hoc na workstation e no servera usando a conta de usuário devops. Essa conta tem a mesma configuração sudo tanto na workstation quanto no servera.

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab deploy-adhoc start. Esse script garante que o host gerenciado servera seja acessível na rede. Ele também cria e preenche o diretório de trabalho /home/student/deploy-adhoc com o material utilizado neste exercício.

[student@workstation ~]$ lab deploy-adhoc start

Determine a configuração sudo para a conta devops na workstation e no servera.

    Determine a configuração sudo da conta devops que foi configurada quando a workstation foi criada. Digite student se for solicitada a senha da conta student.

    [student@workstation ~]$ sudo cat /etc/sudoers.d/devops
    [sudo] password for student: student
    devops ALL=(ALL) NOPASSWD: ALL

    Observe que o usuário tem privilégios sudo completos, mas não requer autenticação de senha.

    Determine a configuração sudo da conta devops que foi configurada quando servera foi criado.

    [student@workstation ~]$ ssh devops@servera.lab.example.com
    [devops@servera ~]$ sudo cat /etc/sudoers.d/devops
    devops ALL=(ALL) NOPASSWD: ALL
    [devops@servera ~]$ exit

    Observe que o usuário tem privilégios sudo completos, mas não requer autenticação de senha. 

Altere o diretório para /home/student/deploy-adhoc e examine o conteúdo dos arquivos ansible.cfg e inventory.

[student@workstation ~]$ cd ~/deploy-adhoc
[student@workstation deploy-adhoc]$ cat ansible.cfg
[defaults]
inventory=inventory
[student@workstation deploy-adhoc]$ cat inventory
[control_node]
localhost

[intranetweb]
servera.lab.example.com

O arquivo de configuração usa o arquivo inventory do diretório como o inventário do Ansible. Observe que o Ansible ainda não está configurado para usar escalonamento de privilégios.

Usando o grupo de hosts all e o módulo ping, execute um comando ad hoc para garantir que todos os hosts gerenciados possam executar módulos do Ansible usando Python.

[student@workstation deploy-adhoc]$ ansible all -m ping
servera.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
localhost | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

Usando o módulo command, execute um comando ad hoc na workstation para identificar a conta de usuário que o Ansible usa para realizar operações em hosts gerenciados. Use o padrão do host localhost para se conectar à workstation e executar o comando ad hoc. Como você está se conectando localmente, a workstation funciona como nó de controle e host gerenciado.

[student@workstation deploy-adhoc]$ ansible localhost -m command -a 'id'
localhost | CHANGED | rc=0 >>
uid=1000(student) gid=1000(student) groups=1000(student),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Observe que o comando ad hoc foi executado no host gerenciado com o usuário student.

Execute o comando ad hoc anterior na workstation, mas se conecte e realize a operação com a conta de usuário devops usando a opção -u.

[student@workstation deploy-adhoc]$ ansible localhost -m command -a 'id' -u devops
localhost | CHANGED | rc=0 >>
uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Observe que o comando ad hoc foi executado no host gerenciado como o usuário devops.

Usando o módulo copy, execute um comando ad hoc na workstation para alterar o conteúdo do arquivo /etc/motd para que ele tenha a string "Managed by Ansible" seguida por uma nova linha. Execute o comando usando a conta devops, mas não use a opção --become para alternar para root. Deverá ocorrer uma falha no comando ad hoc devido à ausência de permissões.

[student@workstation deploy-adhoc]$ ansible localhost -m copy \
> -a 'content="Managed by Ansible\n" dest=/etc/motd' -u devops
localhost | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "msg": "Destination /etc not writable"
}

A falha ocorre no comando ad hoc porque o usuário devops não tem permissão para gravar no arquivo.

Execute o comando novamente usando o escalonamento de privilégios. Você pode corrigir as configurações no arquivo ansible.cfg, mas, neste exemplo, use apenas as opções de linha de comando apropriadas do comando ansible.

Usando o módulo copy, execute o comando anterior na workstation para alterar o conteúdo do arquivo /etc/motd para que ele tenha a string "Managed by Ansible" seguida por uma nova linha. Utilize o usuário devops para se conectar ao host gerenciado, mas realize a operação como usuário root utilizando a opção --become. É suficiente usar a opção --become porque o valor padrão da diretiva become_user está definido como root no arquivo /etc/ansible/ansible.cfg.

[student@workstation deploy-adhoc]$ ansible localhost -m copy \
> -a 'content="Managed by Ansible\n" dest=/etc/motd' -u devops --become
localhost | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "dest": "/etc/motd",
    "gid": 0,
    "group": "root",
    "md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
    "mode": "0644",
    "owner": "root",
    "secontext": "system_u:object_r:etc_t:s0",
    "size": 19,
    "src": "/home/devops/.ansible/tmp/ansible-tmp-1558954193.0260043-131348380629718/source",
    "state": "file",
    "uid": 0
}

Observe que o comando foi bem-sucedido desta vez porque o comando ad hoc foi executado com escalonamento de privilégios.

Execute o comando ad hoc anterior novamente em todos os hosts usando o grupo de hosts all. Isso garante que /etc/motd na workstation e no servera contenha o texto Managed by Ansible.

[student@workstation deploy-adhoc]$ ansible all -m copy \
> -a 'content="Managed by Ansible\n" dest=/etc/motd' -u devops --become
servera.lab.example.com | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "dest": "/etc/motd",
    "gid": 0,
    "group": "root",
    "md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
    "mode": "0644",
    "owner": "root",
    "secontext": "system_u:object_r:etc_t:s0",
    "size": 19,
    "src": "/home/devops/.ansible/tmp/ansible-tmp-1558954250.7893758-136255396678462/source",
    "state": "file",
    "uid": 0
}
localhost | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "dest": "/etc/motd",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "path": "/etc/motd",
    "secontext": "system_u:object_r:etc_t:s0",
    "size": 19,
    "state": "file",
    "uid": 0
}

Você deverá ver SUCCESS para localhost e CHANGED para servera. Entretanto, localhost deverá relatar "changed": false, pois o arquivo já se encontra no estado correto. Inversamente, servera deve relatar "changed": true, porque o comando ad hoc atualizou o arquivo para o estado correto.

Usando o módulo command, execute um comando ad hoc para executar cat /etc/motd a fim de verificar se o conteúdo do arquivo foi modificado corretamente tanto na workstation quanto no servera. Use o grupo de hosts all e o usuário devops para especificar e fazer a conexão com os hosts gerenciados. Você não precisa de escalonamento de privilégios para que este comando funcione.

[student@workstation deploy-adhoc]$ ansible all -m command \
> -a 'cat /etc/motd' -u devops
servera.lab.example.com | CHANGED | rc=0 >>
Managed by Ansible

localhost | CHANGED | rc=0 >>
Managed by Ansible

Encerramento

Na workstation, execute o script lab deploy-adhoc finish para limpar este exercício.

[student@workstation ~]$ lab deploy-adhoc finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Lista de verificação de desempenho

Neste laboratório, você configurará um nó de controle do Ansible para conexões com hosts de inventário e utilizará comandos ad hoc para realizar ações em hosts gerenciados.

Resultados

Você deverá ser capaz de configurar um nó de controle para executar comandos ad hoc em hosts gerenciados.

Você usará o Ansible para gerenciar vários hosts de workstation.lab.example.com como usuário student. Você configurará um diretório de projeto contendo um arquivo ansible.cfg com alguns padrões específicos e um diretório inventory contendo um arquivo de inventário.

Você usará comandos ad hoc para garantir que o arquivo /etc/motd de todos os hosts gerenciados tenha um conteúdo específico.

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab deploy-review start. Esse script garante que os hosts gerenciados sejam acessíveis na rede.

[student@workstation ~]$ lab deploy-review start

Verifique se o pacote ansible está instalado no nó de controle e execute o comando ansible --version.

    Verifique se o pacote ansible está instalado.

    [student@workstation ~]$ yum list installed ansible
    Installed Packages
    ansible.noarch    2.8.0-1.el8ae     @rhel-8-server-ansible-2.8-rpms

    Execute o comando ansible --version para confirmar a versão do Ansible que está instalada.

    [student@workstation ~]$ ansible --version
    ansible 2.8.0
      config file = /etc/ansible/ansible.cfg
      configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
      ansible python module location = /usr/lib/python3.6/site-packages/ansible
      executable location = /usr/bin/ansible
      python version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

No diretório pessoal do usuário student na workstation, /home/student, crie um novo diretório denominado deploy-review. Mude para esse diretório.

[student@workstation ~]$ mkdir ~/deploy-review [student@workstation ~]$ cd ~/deploy-review

Crie um arquivo ansible.cfg no diretório deploy-review, que você usará para definir os seguintes padrões do Ansible:

Conecte-se a hosts gerenciados como o usuário devops.

Use o subdiretório inventory para incluir o arquivo de inventário.

Desabilite o escalonamento de privilégios por padrão. Se o escalonamento de privilégios for habilitado na linha de comando, configure as definições padrão para fazer com que o Ansible use o método sudo para mudar para a conta de usuário root. O Ansible não deve solicitar a senha de login do devops nem a senha do sudo. 

Os hosts gerenciados foram configurados com um usuário devops que pode fazer login usando autenticação SSH baseada em chave e pode executar qualquer comando como root usando o comando sudo sem uma senha.

Use um editor de texto para criar o arquivo /home/student/deploy-review/ansible.cfg. Crie uma seção [defaults]. Adicione uma diretiva remote_user para fazer com que o Ansible utilize o usuário devops ao se conectar a hosts gerenciados. Adicione uma diretiva inventory para configurar o Ansible para usar o diretório /home/student/deploy-review/inventory como local padrão do arquivo de inventário.

[defaults]
remote_user = devops
inventory = inventory

No arquivo /home/student/deploy-review/ansible.cfg, crie a seção [privilege_escalation] e adicione as entradas a seguir para desabilitar o escalonamento de privilégios. Defina o método de escalonamento de privilégios para usar a conta root com o sudo, sem autenticação de senha.

[privilege_escalation]
become = False
become_method = sudo
become_user = root
become_ask_pass = False

O arquivo ansible.cfg concluído deverá ficar assim:

[defaults]
remote_user = devops
inventory = inventory

[privilege_escalation]
become = False
become_method = sudo
become_user = root
become_ask_pass = False

Salve seu trabalho e feche o editor. 

Crie o diretório /home/student/deploy-review/inventory.

Baixe o arquivo http://materials.example.com/labs/deploy-review/inventory e salve-o como um arquivo de inventário estático denominado /home/student/deploy-review/inventory/inventory.

Crie o diretório /home/student/deploy-review/inventory.

[student@workstation deploy-review]$ mkdir inventory

Baixe o arquivo http://materials.example.com/labs/deploy-review/inventory no diretório /home/student/deploy-review/inventory.

[student@workstation deploy-review]$ wget -O inventory/inventory \
> http://materials.example.com/labs/deploy-review/inventory

Inspecione o conteúdo do arquivo /home/student/deploy-review/inventory/inventory.

[student@workstation deploy-review]$ cat inventory/inventory
[internetweb]
serverb.lab.example.com

[intranetweb]
servera.lab.example.com
serverc.lab.example.com
serverd.lab.example.com

Execute o comando id como um comando ad hoc direcionado ao grupo de hosts all para verificar se devops é o usuário remoto e se o escalonamento de privilégios está desativado por padrão.

[student@workstation deploy-review]$ ansible all -m command -a 'id' serverb.lab.example.com | CHANGED | rc=0 >> uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u: unconfined_r:unconfined_t:s0-s0:c0.c1023

serverc.lab.example.com | CHANGED | rc=0 >> uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u: unconfined_r:unconfined_t:s0-s0:c0.c1023

servera.lab.example.com | CHANGED | rc=0 >> uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u: unconfined_r:unconfined_t:s0-s0:c0.c1023

serverd.lab.example.com | CHANGED | rc=0 >> uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u: unconfined_r:unconfined_t:s0-s0:c0.c1023

Seus resultados podem ser retornados em uma ordem diferente.

Execute um comando ad hoc, direcionado para o grupo de hosts all, que usa o módulo copy para modificar o conteúdo do arquivo /etc/motd em todos os hosts.

Use a opção content do módulo copy para garantir que o arquivo /etc/motd seja composto pela string This server is managed by Ansible.\n como uma única linha. (O \n usado com a opção content faz com que o módulo coloque uma nova linha no final da string.)

Você deve solicitar o escalonamento de privilégios na linha de comando para fazer isso funcionar com seus padrões atuais do ansible.cfg.

[student@workstation deploy-review]$ ansible all -m copy \

-a 'content="This server is managed by Ansible.\n" dest=/etc/motd' --become serverd.lab.example.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "md5sum": "af74293c7b2a783c4f87064374e9417a", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "src": "/home/devops/.ansible/tmp/ansible-tmp-1558954517.7426903-24998924904061/source", "state": "file", "uid": 0 } servera.lab.example.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "md5sum": "af74293c7b2a783c4f87064374e9417a", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "src": "/home/devops/.ansible/tmp/ansible-tmp-1558954517.7165847-103324013882266/source", "state": "file", "uid": 0 } serverc.lab.example.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "md5sum": "af74293c7b2a783c4f87064374e9417a", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "src": "/home/devops/.ansible/tmp/ansible-tmp-1558954517.75727-94151722302122/source", "state": "file", "uid": 0 } serverb.lab.example.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "md5sum": "af74293c7b2a783c4f87064374e9417a", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "src": "/home/devops/.ansible/tmp/ansible-tmp-1558954517.6649802-53313238077104/source", "state": "file", "uid": 0 }

Se você executar o mesmo comando ad hoc novamente, verá que o módulo copy detecta que os arquivos já estão corretos e, por isso, eles não são alterados. Procure pelo comando ad hoc para relatar SUCCESS e pela linha "changed": false para cada host gerenciado.

[student@workstation deploy-review]$ ansible all -m copy \

-a 'content="This server is managed by Ansible.\n" dest=/etc/motd' --become serverb.lab.example.com | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/etc/motd", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "state": "file", "uid": 0 } serverc.lab.example.com | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/etc/motd", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "state": "file", "uid": 0 } serverd.lab.example.com | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/etc/motd", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "state": "file", "uid": 0 } servera.lab.example.com | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "checksum": "93d304488245bb2769752b95e0180607effc69ad", "dest": "/etc/motd", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/etc/motd", "secontext": "system_u:object_r:etc_t:s0", "size": 35, "state": "file", "uid": 0 }

Para confirmar isso de outra maneira, execute um comando ad hoc que seja direcionado ao grupo de hosts all usando o módulo command para executar o comando cat /etc/motd. A saída do comando ansible deve exibir a string This server is managed by Ansible. para todos os hosts. Você não precisa de escalonamento de privilégios para esse comando ad hoc.

[student@workstation deploy-review]$ ansible all -m command -a 'cat /etc/motd' serverb.lab.example.com | CHANGED | rc=0 >> This server is managed by Ansible.

servera.lab.example.com | CHANGED | rc=0 >> This server is managed by Ansible.

serverd.lab.example.com | CHANGED | rc=0 >> This server is managed by Ansible.

serverc.lab.example.com | CHANGED | rc=0 >> This server is managed by Ansible.

Execute lab deploy-review grade na workstation para verificar seu trabalho.

[student@workstation deploy-review]$ lab deploy-review grade

Encerramento

Na workstation, execute o script lab deploy-review finish para limpar os recursos criados neste laboratório.

[student@workstation ~]$ lab deploy-review finish

britho commented 3 years ago

Neste capítulo, você aprendeu que:

Qualquer sistema no qual o Ansible esteja instalado e que tenha acesso aos arquivos de configuração e playbooks necessários para gerenciar sistemas remotos (hosts gerenciados) é chamado de nó de controle.

Os hosts gerenciados são definidos no inventário. Os padrões de hosts são usados para referenciar hosts gerenciados definidos em um inventário.

Os inventários podem ser arquivos estáticos ou gerados dinamicamente por um programa de uma fonte externa, como um serviço de diretório ou um sistema de gerenciamento em nuvem.

O Ansible procura seu arquivo de configuração em uma série de lugares em ordem de precedência. O primeiro arquivo de configuração encontrado é utilizado; todos os demais são ignorados.

O comando ansible é usado para executar comandos ad hoc em hosts gerenciados.

Os comandos ad hoc determinam a operação a ser realizada usando módulos e seus argumentos, e podem usar os recursos de escalonamento de privilégios do Ansible.