Foreman: ENC para o Puppet

No artigo passado vimos a instalação do Foreman. Neste vamos ver algumas de suas funcionalidades como classificador externo (ENC) para o Puppet.

Há muita documentação sobre Puppet relacionada à boas práticas em organização de módulos, roles, profiles, dados, parâmetros etc e o objetivo aqui não é falar deste assunto. Vamos apenas exemplificar, de forma objetiva, um cenário hipotético demonstrando alguns recursos do Foreman para classificação no Puppet.

Os módulos, roles e profiles foram organizados para este exemplo de uso do Foreman. Na vida real, você pode administrar usuários de forma completamente diferente, organizar suas classes em um único módulo sendo pinçadas pelos seus profiles etc… como disse, há muita documentação sobre boas práticas, aqui é apenas um exemplo de uso da ferramenta Foreman.

Módulos Puppet

Os módulos foram organizados da seguinte forma:

  • Mybaselines: tudo que diz respeito à padronização dos sistemas em si como tunnings, regras de segurança etc, mas nada que diga respeito à aplicações. Também não significa que todas as baselines serão aplicadas à todos os servidores, mas todas as baselines aplicadas à qualquer grupo de servidores estarão aqui justamente para compor sets de baselines.
  • Myapps: módulo contendo as classes para implementar as aplicações da empresa. Os manifestos foram divididos em subdiretórios de acordo com a aplicação, no caso, chat e webmail.
  • Myusers: um módulo exclusivo para gerenciar os usuários da empresa no qual suas classes ficam divididas em subdiretorios de acordo com seus setores. Ex.: infra/joao, infra/jose, dev/joana, dev/maria etc. Porque não gerenciar todos os usuários em uma única classe ? Ora mancebo, para que possamos pinçá-los individualmente e mesclá-los em grupos ! Há exemplo mais adiante.
  • Myrepos: módulo para gerenciar repositórios de pacotes tanto externos quanto internos. Assim como os usuários, há quem prefira gerenciar isso em subdiretórios de um módulo de baselines. Nada contra nem à favor, muito pelo contrário.

No Foreman essas classes e módulos aparecem da seguinte forma:

screenshot-2016-12-17-12-25-50

Claro que atachar classes diretamente em hosts é uma péssima idéia, e não escala. Por isso há o conceito de roles e profiles.


Roles & Profiles

Leia sobre roles e profiles no Puppet.

No Foreman, basicamente as Roles são os Hostgroups e os Profiles são os Config Groups.

Você atacha classes em Config Groups e atacha Config Groups em Host Groups. Os hosts pertencem a apenas um Hostgroup (que define sua Role), mas uma “funcionalidade” extra é que Hostgroups são hierárquicos.

Vamos brincar com o que temos.

Config Groups (profiles)

Vamos criar grupos de usuários. O pessoal de infra tem usuários em todos os servidores, o pessoal de dev terá de acordo com o servidor, e há devs que são apenas front ou backend e há devs que são os dois.

Vamos organizá-los.

Criando um Config Group para os usuários de Infra selecionando as classes deles no módulo myusers:

screenshot-2016-12-17-12-39-38

Ficando assim:

screenshot-2016-12-17-12-40-18

Fazer o mesmo para os devs frondend e backend:

screenshot-2016-12-17-12-41-27

screenshot-2016-12-17-12-42-15

Agora vamos criar nosso set de baselines comuns à TODOS os servidores. Vamos deixar de fora as classes que são baselines apenas para um grupo de servidores, pois pra elas uma baseline específica deve ser criada.

screenshot-2016-12-17-12-48-20

Note que também foram incluídas as classes do repositório do Zabbix e EPEL nesse Config Group. Isso faz sentido porque, embora as classes de repo estejam organizadas em seu próprio módulo, a baseline geral deve incluí-las já que todos os servidores utilizarão esses repositórios.

Ainda sobre repositórios, a empresa tem dois repositórios internos: um para os RPMs de suas aplicações e outro com RPMs baixados da Internet que são dependências de suas aplicações. Preferiram fazer desta forma do que depender de repos externos para instalá-las. Como toda aplicação precisará dos dois repos, vamos criar um Config Group pra eles:

screenshot-2016-12-17-12-51-44

Notou que o repo do newrelic ainda não foi usado ? Pois é, não é toda aplicação que utiliza o newrelic.

Ele será atachado junto das classes para formar o Config Group da aplicação Chat, veja:

screenshot-2016-12-17-12-53-43

E Por fim, a aplicação de Webmail (que não usa newrelic):

screenshot-2016-12-17-12-54-52

Ficamos com os seguintes Config Groups:

screenshot-2016-12-17-13-13-12

(ignorem o Foreman Server)

Hostgroups (Roles)

Ok, agora já temos as classes em seus devidos Config Groups (profiles) e só precisamos criar nossos Hostgroups (Roles) para colocar os hosts dentro.

Lembra que os Hostgroups são hierárquicos ? Então vamos começar pelo que todo servidor Linux (no caso) deve ter. Vamos criar um Hostgroup “Linux” com o Config Group das baselines:

screenshot-2016-12-17-13-00-23

Na criação/edição do Hostgroup você seleciona quais Config Groups deseja incluir. No Hostgroup Linux  incluimos apenas as baselines e os usuário de infra.

Já no Hostgroup de Chat Servers, vamos incluir os repositórios internos, a aplicação de Chat e os desenvolvedores backend, e pra ele herdar as baselines e os usuários de infra, basta colocá-lo como filho do hostgroup Linux:

screenshot-2016-12-17-13-04-40

screenshot-2016-12-17-13-04-54

Note que, por terem sido herdadas pelo hostgroup Linux, não dá pra remover o config group de baselines e usuário de infra. Essa é a idéia da herança.

Da mesma forma, no hostgroup webmail vamos incluir a aplicação, os repos e os devs frontend, também herdando os config groups do hostgroup Linux:

screenshot-2016-12-17-13-07-47

Vamos criar um hostgroup NTP Servers tambem para demonstrar uma funcionalidade depois. Eles não terão nada a mais que as baselines, então não vamos adicionar nenhum config group à ele:

screenshot-2016-12-17-13-11-53

Ok, chega de Hostgroups:

screenshot-2016-12-17-13-12-46


Classes parametrizadas

Digamos que você queira fazer XPTOABC num host e XPTOABD em outro. Para que você não tenha que reescrever código e possa aproveitar as mesmas classes para fazer coisas semelhantes, com diferenças de acordo com environment/host/fact etc, você pode fazer com que sua classe aceite parâmetros. Há também o Hiera, mas é mais apropriado à dados.

Nós temos 3 classes nas baselines que suportam parâmetros:

  • mybaselines::ntp que suporta ntp_role sendo client ou server, e ntp_servers com um array dos servidores que o host vai utilizar. O default é ser um ntp client apontando para os servidores internos ntp01 e ntp02.
  • mybaselines::sudoers que configura o sudo do host para permitir que membros do array recebido se tornem root. Por default apenas o pessoal de infra pode se tornar root em todos os servidores.
  • mybaselines::timezone que configura o timezone dos hosts. Por default, UTC.

Visão dos parâmetros no Hostgroup Linux:

screenshot-2016-12-17-13-31-19

Agora lembra do Hostgroup de NTP Servers ? Pois é… podemos fazer os hosts virarem servidores NTP em vez de apenas clientes, só mudando o valor do parâmetro no Hostgroup NTP Servers. Por padrão, ele herda os defaults do Hostgroup Linux, mas podemos setar um valor para os parâmetros no Hostgroup especificamente:

screenshot-2016-12-17-13-36-39

Os hosts colocados neste hostgroup automaticamente servirão NTP, pois a classe os configurará diferente por ter recebido ‘server’ em vez de ‘client’.

Os servidores de Webmail possuem necessidade especial já que embora usemos UTC em todos os servidores, os usuários se sentiriam desconfortáveis de ver uma interface web de email com UTC… eles preferem America/Sao_Paulo. Toma-lhe parâmetro…

screenshot-2016-12-17-13-42-44

Já nas máquinas do Chat, os devs backend além de terem usuários lá (pelo Config Group), precisam poder virar root (wtf?!). Aproveitando a mesma classe do sudoers mas acrescentando o grupo dos devs backend no array:

screenshot-2016-12-17-13-44-20


Conclusão

O Foreman permite agrupar classes em Config Groups e atachar Config Groups em Host Groups, que são hierárquicos. É uma forma de utilizar a organização de roles e profiles no Foreman.

Além disso, utilizando parâmetros e a hierarquia de Hostgroups do Foreman é possível reaproveitar bem suas classes especificando comportamentos diferentes por grupos ou até por servidor específico.

Em breve falarei do Foreman sendo utilizado para provisionamento de hosts físicos, virtuais ou cloud (vmware, aos, azure etc).

5 comentários em “Foreman: ENC para o Puppet

  1. class role::basic {

    include profile::accounts::sysadmin
    include profile::base::basic
    include profile::zabbix::agent
    include profile::logstash::filebeat
    include profile::accounts::ldap

    # e por ai vai

    }

    Curtir

  2. Parabéns pelo artigo, muito legal.

    Tentei utilizar de forma parecida a questão de roles e profiles utilizando o foreman, mas tive um alguns problemas em relação a order de execução dos modulos.

    No exemplo abaixo, primeiramente executado a class role::basic, e só depois a profile::zabbix::proxy.

    class role::zabbix::proxy {

    include role::basic
    include profile::zabbix::proxy

    Class[‘role::basic’] ->
    Class[‘profile::zabbix::proxy’]

    }

    Encontro em algum lugar onde podemos definir a order de execução utilizando o foreman ?

    Att,

    Curtir

    1. Olá Eduardo !
      Realmente o Foreman em si não possui uma forma de utilizar este recurso do Puppet mas você pode resolver isso de algumas formas.

      Pelo que parece, sua role “role::basic” sugere ser um set de baselines comum a todos os servicos, seria isso ?
      Se for, como sugiro que faça no Foreman:
      – Crie uma classe usando este recurso do puppet para especificar a ordem das classes como vc fez acima.
      – Crie um config group “zabbix proxy” e coloque as classes relacionadas nele (incluindo a classe que apenas especifica a ordem).
      – Crie um config group “basic” e coloque as classes relacionadas nele.
      – Crie um Hostgroup “baselines” e atache o config group “basic”.
      – Crie um Hostgroup “zabbix proxy” filho do “baselines” e atache o config group “zabbix proxy”.
      – Ponha o host neste hostgroup.

      Uma consideração: se a “role::basic” for mesmo um set de baselines, fica mais organizado se tratar isso como profile e não como role, pois role deve ser uma coisa única que define o host.

      Curtir

      1. Vou testar a forma que você sugeriu.

        Na verdade o role::basic, é um conjunto de profiles basics.

        Fiz assim para não ter que repetir nas roles muitas vezes uma seria de profiles.

        Curtir

Os comentários estão encerrados.