Puppet: Como usar um conjunto de pacotes comuns, mas permitir exceções?

Puppet: Como usar um conjunto de pacotes comuns, mas permitir exceções?

Tenho cerca de 200 VMs Linux mais ou menos idênticas. Existe uma classe para todas as configurações comuns:

class my_packages {

    class { "::ntp":
        servers     => [ "de.pool.ntp.org" ],
    }
    ....
}

que incluo em cada nó no site.pp.

Agora quero executar meu próprio servidor de horário local, o que é trivial usando o pacote puppetlabs/ntp. Eu simplesmente tenho que substituir a entrada de servidores em my_packages pelo endereço IP da nova VM do servidor de horário, e essa VM agora tem a mesma entrada de classe ntp que foi usada anteriormente em my_packages.

node 'mytime' {

#    include my_packages

    class { '::ntp':
        servers => [
            'de.pool.ntp.org',
            'ptbtime1.ptb.de',
            'ptbtime2.ptb.de',
            'ptbtime3.ptb.de',
        ],
    }
    ...
}

No entanto, como a entrada da classe "::ntp" agora está definida no nó, não posso incluir my_packages na entrada do nó para minha nova VM do servidor de horário, porque recebo um erro de "Declaração duplicada" neste caso.

Um problema semelhante ocorreu ao usar um servidor de nomes local. Cada VM possui um arquivo /etc/resolv.conf apontando para o servidor de nomes local, portanto, há um recurso de arquivo para isso em my_packages. Mas o próprio servidor de nomes local deve ter um arquivo /etc/resolv.conf diferente - ele não pode apontar para si mesmo até que sua instalação seja concluída, o que não é o caso durante a instalação.

Qual é a melhor prática para usar um conjunto comum de recursos, mas permitindo exceções ocasionais?

Responder1

Se você estiver usando o Puppet 3 ou posterior, a melhor maneira de abordar isso seria usar o hiera para executarpesquisa automática de parâmetros. Resumindo, ele permite declarar classes usando a sintaxe include em vez da sintaxe estilo recurso, o que significa que você pode ter múltiplas declarações para a classe. Observe que você não pode misturar declarações de inclusão e de estilo de recurso para uma classe.

Normalmente, se você usasse a sintaxe include para declarar uma classe, ela falharia se tivesse algum parâmetro obrigatório. Quando você usa a pesquisa automática de parâmetros, o puppet tentará pesquisar os valores dos parâmetros por meio do hiera.

Hiera tem esse nome porque tentará pesquisar valores por meio de uma hierarquia de fontes de dados. Você pode especificar essa hierarquia em hiera.yaml e ela pode corresponder a vários fatos (nome do host, fatos personalizados, etc.) ou verificar arquivos codificados.

Aqui está um breve exemplo que pode funcionar no seu caso:

Definição de classe:

class my_packages {
  include ::ntp
  ...
}

meutime.yaml:

----
ntp::servers:
  - 'de.pool.ntp.org'
  - 'ptbtime1.ptb.de'
  - 'ptbtime2.ptb.de'
  - 'ptbtime3.ptb.de'

comum.yaml:

---
ntp::servers: ['de.pool.ntp.org']

hiera.yaml:

...
:hierarchy:
 - "${::fqdn}"
 - common
...

Neste caso, hiera tentaria procurar um valor para o parâmetro de servidores na classe ntp, usando a chave ntp::servers. Ele primeiro procuraria essa chave em qualquer arquivo yaml que correspondesse ao nome do host e, depois disso, procuraria em common.yaml.

Na maioria dos casos, ele usaria a chave em common.yaml, mas no caso do nó mytime, ele encontraria um valor mais alto na hierarquia e pararia de procurá-lo.

Aqui está um link para umexemplo completo, que aliás cobre o módulo ntp.

informação relacionada