Fantoche - Projeto Vivo
Para realizar o teste ao vivo de aplicação de configuração e manifestos no nó Puppet, usaremos uma demonstração de trabalho ao vivo. Isso pode ser copiado e colado diretamente para testar como a configuração funciona. Se o usuário deseja usar o mesmo conjunto de código, ele precisa ter a mesma convenção de nomenclatura conforme mostrado nos fragmentos de código a seguir.
Vamos começar com a criação de um novo módulo.
Criando um Novo Módulo
A primeira etapa para testar e aplicar a configuração httpd é criar um módulo. Para fazer isso, o usuário precisa mudar seu diretório de trabalho para o diretório do módulo Puppet e criar uma estrutura básica do módulo. A criação da estrutura pode ser feita manualmente ou usando o Puppet para criar clichês para o módulo.
# cd /etc/puppet/modules
# puppet module generate Live-module
Note - O comando de geração do módulo Puppet requer que o nome do módulo tenha o formato [nome de usuário] - [módulo] para cumprir as especificações do Puppet forge.
O novo módulo contém alguns arquivos básicos, incluindo um diretório de manifesto. O diretório já contém um manifesto denominado init.pp, que é o arquivo de manifesto principal dos módulos. Esta é uma declaração de classe vazia para o módulo.
class live-module {
}
O módulo também contém um diretório de teste contendo um manifesto chamado init.pp. Este manifesto de teste contém referência à classe do módulo ativo em manifest / init.pp:
include live-module
O Puppet usará este módulo de teste para testar o manifesto. Agora estamos prontos para adicionar a configuração ao módulo.
Instalando um servidor HTTP
O módulo Puppet instalará os pacotes necessários para executar o servidor http. Isso requer uma definição de recurso que define a configuração dos pacotes httpd.
No diretório de manifesto do módulo, crie um novo arquivo de manifesto chamado httpd.pp
# touch test-module/manifests/httpd.pp
Este manifesto conterá todas as configurações HTTP para nosso módulo. Para fins de separação, manteremos o arquivo httpd.pp separado do arquivo de manifesto init.pp
Precisamos colocar o seguinte código no arquivo de manifesto httpd.pp.
class test-module::httpd {
package { 'httpd':
ensure => installed,
}
}
Este código define uma subclasse de módulo de teste chamada httpd e, em seguida, define uma declaração de recurso de pacote para o pacote httpd. O atributo sure => installed verifica se o pacote necessário está instalado. Se não estiver instalado, o Puppet usa o utilitário yum para instalá-lo. A seguir, é incluir essa subclasse em nosso arquivo de manifesto principal. Precisamos editar o manifesto init.pp.
class test-module {
include test-module::httpd
}
Agora é hora de testar o módulo, o que pode ser feito da seguinte maneira
# puppet apply test-module/tests/init.pp --noop
O comando puppet apply aplica a configuração presente no arquivo de manifesto no sistema de destino. Aqui, estamos usando o teste init.pp que se refere ao init.pp principal. O –noop executa a simulação da configuração, que mostra apenas a saída, mas na verdade não faz nada.
A seguir está a saída.
Notice: Compiled catalog for puppet.example.com in environment
production in 0.59 seconds
Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure:
current_value absent, should be present (noop)
Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 1
events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.67 seconds
A linha de destaque é o resultado do atributo garantir => instalado. O current_value ausente significa que o Puppet detectou que o pacote httpd está instalado. Sem a opção –noop, o Puppet instalará o pacote httpd.
Executando o servidor httpd
Depois de instalar os servidores httpd, precisamos iniciar o serviço usando outro recurso de desaceleração: Serviço
Precisamos editar o arquivo de manifesto httpd.pp e editar o seguinte conteúdo.
class test-module::httpd {
package { 'httpd':
ensure => installed,
}
service { 'httpd':
ensure => running,
enable => true,
require => Package["httpd"],
}
}
A seguir está a lista de metas que alcançamos com o código acima.
o ensure => o status de execução verifica se o serviço está em execução; caso contrário, ele o habilita.
o enable => O atributo true define o serviço a ser executado quando o sistema é inicializado.
o require => Package["httpd"]atributo define uma relação de ordenação entre uma desaceleração de recurso e outra. No caso acima, ele garante que o serviço httpd seja iniciado após a instalação do pacote http. Isso cria uma dependência entre o serviço e o respectivo pacote.
Execute o comando puppet apply para testar as alterações novamente.
# puppet apply test-module/tests/init.pp --noop
Notice: Compiled catalog for puppet.example.com in environment
production in 0.56 seconds
Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure:
current_value absent, should be present (noop)
Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure:
current_value stopped, should be running (noop)
Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 2
events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.41 seconds
Configurando servidor httpd
Assim que as etapas acima forem concluídas, teremos o servidor HTTP instalado e ativado. A próxima etapa é fornecer algumas configurações ao servidor. Por padrão, o httpd fornece algumas configurações padrão em /etc/httpd/conf/httpd.conf que fornece uma porta de host da web 80. Adicionaremos alguns hosts adicionais para fornecer alguns recursos específicos do usuário ao host da web.
Um modelo será usado para fornecer porta adicional, pois requer uma entrada variável. Vamos criar um diretório chamado template e adicionar um arquivo chamado test-server.config.erb no novo direcionador e adicionar o seguinte conteúdo.
Listen <%= @httpd_port %>
NameVirtualHost *:<% = @httpd_port %>
<VirtualHost *:<% = @httpd_port %>>
DocumentRoot /var/www/testserver/
ServerName <% = @fqdn %>
<Directory "/var/www/testserver/">
Options All Indexes FollowSymLinks
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
O modelo acima segue o formato de configuração do servidor apache-tomcat padrão. A única diferença é o uso do caractere de escape Ruby para injetar variáveis do módulo. Temos FQDN que armazena o nome de domínio totalmente qualificado do sistema. Isso é conhecido comosystem fact.
Os fatos do sistema são coletados de cada sistema antes de gerar o catálogo de fantoches de cada sistema respectivo. O Puppet usa o comando facter para obter essas informações e pode-se usar o facter para obter outros detalhes sobre o sistema. Precisamos adicionar as linhas de destaque no arquivo de manifesto httpd.pp.
class test-module::httpd {
package { 'httpd':
ensure => installed,
}
service { 'httpd':
ensure => running,
enable => true,
require => Package["httpd"],
}
file {'/etc/httpd/conf.d/testserver.conf':
notify => Service["httpd"],
ensure => file,
require => Package["httpd"],
content => template("test-module/testserver.conf.erb"),
}
file { "/var/www/myserver":
ensure => "directory",
}
}
Isso ajuda a alcançar as seguintes coisas -
Isso adiciona uma declaração de recurso de arquivo para o arquivo de configuração do servidor (/etc/httpd/conf.d/test-server.conf). O conteúdo desse arquivo é o modelo test-serverconf.erb que foi criado anteriormente. Também verificamos o pacote httpd instalado antes de adicionar este arquivo.
Isso adiciona a segunda declaração de recurso de arquivo que cria um diretório (/ var / www / test-server) para o servidor web.
Em seguida, adicionamos a relação entre o arquivo de configuração e o serviço https usando o notify => Service["httpd"]attribute. Isso verifica se há alguma alteração no arquivo de configuração. Se houver, o Puppet reinicia o serviço.
Em seguida, é incluir o httpd_port no arquivo de manifesto principal. Para isso, precisamos encerrar o arquivo de manifesto init.pp principal e incluir o seguinte conteúdo.
class test-module (
$http_port = 80
) {
include test-module::httpd
}
Isso define a porta httpd para o valor padrão de 80. Em seguida, é executar o comando Puppet apply.
A seguir será a saída.
# puppet apply test-module/tests/init.pp --noop
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera
defaults
Notice: Compiled catalog for puppet.example.com in environment
production in 0.84 seconds
Notice: /Stage[main]/test-module::Httpd/File[/var/www/myserver]/ensure:
current_value absent, should be directory (noop)
Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure:
current_value absent, should be present (noop)
Notice:
/Stage[main]/test-module::Httpd/File[/etc/httpd/conf.d/myserver.conf]/ensure:
current_value absent, should be file (noop)
Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure:
current_value stopped, should be running (noop)
Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 4
events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.51 seconds
Configurando o Firewall
Para se comunicar com o servidor, é necessária uma porta aberta. O problema aqui é que diferentes tipos de sistemas operacionais usam diferentes métodos de controle do firewall. No caso do Linux, as versões abaixo de 6 usam iptables e a versão 7 usa firewalld.
Essa decisão de usar um serviço apropriado é, de certa forma, tratada pelo Puppet usando os fatos do sistema e sua lógica. Para isso, primeiro precisamos verificar o sistema operacional e, em seguida, executar o comando de firewall apropriado.
Para conseguir isso, precisamos adicionar o seguinte trecho de código dentro da classe testmodule :: http.
if $operatingsystemmajrelease <= 6 {
exec { 'iptables':
command => "iptables -I INPUT 1 -p tcp -m multiport --ports
${httpd_port} -m comment --comment 'Custom HTTP Web Host' -j ACCEPT &&
iptables-save > /etc/sysconfig/iptables",
path => "/sbin",
refreshonly => true,
subscribe => Package['httpd'],
}
service { 'iptables':
ensure => running,
enable => true,
hasrestart => true,
subscribe => Exec['iptables'],
}
} elsif $operatingsystemmajrelease == 7 {
exec { 'firewall-cmd':
command => "firewall-cmd --zone=public --addport = $ {
httpd_port}/tcp --permanent",
path => "/usr/bin/",
refreshonly => true,
subscribe => Package['httpd'],
}
service { 'firewalld':
ensure => running,
enable => true,
hasrestart => true,
subscribe => Exec['firewall-cmd'],
}
}
O código acima executa o seguinte -
Usando o operatingsystemmajrelease determina se o sistema operacional usado é a versão 6 ou 7.
Se a versão for 6, ele executará todos os comandos de configuração necessários para configurar a versão 6 do Linux.
Se a versão do sistema operacional for 7, ele executa todos os comandos exigidos para configurar o firewall.
O trecho de código para ambos os sistemas operacionais contém uma lógica que garante que a configuração seja executada somente após a instalação do pacote http.
Finalmente, execute o comando de aplicação Puppet.
# puppet apply test-module/tests/init.pp --noop
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera
defaults
Notice: Compiled catalog for puppet.example.com in environment
production in 0.82 seconds
Notice: /Stage[main]/test-module::Httpd/Exec[iptables]/returns:
current_value notrun, should be 0 (noop)
Notice: /Stage[main]/test-module::Httpd/Service[iptables]: Would have
triggered 'refresh' from 1 events
Configurando o SELinux
Como estamos trabalhando em uma máquina Linux com a versão 7 e superior, precisamos configurá-la para fazer uma comunicação http. O SELinux restringe o acesso não padrão ao servidor HTTP por padrão. Se definirmos uma porta personalizada, precisamos configurar o SELinux para fornecer acesso a essa porta.
O Puppet contém alguns tipos de recursos para gerenciar funções SELinux, como booleanos e módulos. Aqui, precisamos executar o comando semanage para gerenciar as configurações de porta. Essas ferramentas fazem parte do pacote policycoreutils-python, que não é instalado em servidores red-hat por padrão. A fim de alcançar o acima, precisamos adicionar o seguinte código dentro da classe test-module :: http.
exec { 'semanage-port':
command => "semanage port -a -t http_port_t -p tcp ${httpd_port}",
path => "/usr/sbin",
require => Package['policycoreutils-python'],
before => Service ['httpd'],
subscribe => Package['httpd'],
refreshonly => true,
}
package { 'policycoreutils-python':
ensure => installed,
}
O código acima executa o seguinte -
O require => Package ['policycoreutils-python'] garante que temos o módulo python necessário instalado.
O Puppet usa semanage para abrir a porta usando o httpd_port como um verificável.
O serviço before => garante a execução desse comando antes do início do serviço httpd. Se o HTTPD iniciar antes do comando SELinux, a solicitação de serviço SELinux e a solicitação de serviço falharão.
Finalmente, execute o comando Puppet apply
# puppet apply test-module/tests/init.pp --noop
...
Notice: /Stage[main]/test-module::Httpd/Package[policycoreutilspython]/
ensure: current_value absent, should be present (noop)
...
Notice: /Stage[main]/test-module::Httpd/Exec[semanage-port]/returns:
current_value notrun, should be 0 (noop)
...
Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure:
current_value stopped, should be running (noop)
O Puppet instala primeiro o módulo python e, a seguir, configura o acesso à porta e, finalmente, inicia o serviço httpd.
Copiando arquivos HTML no host da web
Com as etapas acima, concluímos a configuração do servidor http. Agora, temos uma plataforma pronta para instalar um aplicativo baseado na web, que o Puppet também pode configurar. Para testar, copiaremos algumas páginas da web de índice html de amostra para o servidor.
Crie um arquivo index.html dentro do diretório de arquivos.
<html>
<head>
<title>Congratulations</title>
<head>
<body>
<h1>Congratulations</h1>
<p>Your puppet module has correctly applied your configuration.</p>
</body>
</html>
Crie um manifest app.pp dentro do diretório de manifesto e adicione o seguinte conteúdo.
class test-module::app {
file { "/var/www/test-server/index.html":
ensure => file,
mode => 755,
owner => root,
group => root,
source => "puppet:///modules/test-module/index.html",
require => Class["test-module::httpd"],
}
}
Esta nova classe contém uma desaceleração de recurso único. Isso copia um arquivo do diretório de arquivos do módulo para o servidor da web e define suas permissões. O atributo obrigatório garante que a classe test-module :: http conclua a configuração com êxito antes de aplicar test-module :: app.
Finalmente, precisamos incluir um novo manifesto em nosso manifesto init.pp principal.
class test-module (
$http_port = 80
) {
include test-module::httpd
include test-module::app
}
Agora, execute o comando apply para realmente testar o que está acontecendo. A seguir será a saída.
# puppet apply test-module/tests/init.pp --noop
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera
defaults
Notice: Compiled catalog for brcelprod001.brcle.com in environment
production in 0.66 seconds
Notice: /Stage[main]/Test-module::Httpd/Exec[iptables]/returns:
current_value notrun, should be 0 (noop)
Notice: /Stage[main]/Test-module::Httpd/Package[policycoreutilspython]/
ensure: current_value absent, should be present (noop)
Notice: /Stage[main]/Test-module::Httpd/Service[iptables]: Would have
triggered 'refresh' from 1 events
Notice: /Stage[main]/Test-module::Httpd/File[/var/www/myserver]/ensure:
current_value absent, should be directory (noop)
Notice: /Stage[main]/Test-module::Httpd/Package[httpd]/ensure:
current_value absent, should be present (noop)
Notice:
/Stage[main]/Test-module::Httpd/File[/etc/httpd/conf.d/myserver.conf]/ensur
e: current_value absent, should be file (noop)
Notice: /Stage[main]/Test-module::Httpd/Exec[semanage-port]/returns:
current_value notrun, should be 0 (noop)
Notice: /Stage[main]/Test-module::Httpd/Service[httpd]/ensure:
current_value stopped, should be running (noop)
Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 8
Notice:
/Stage[main]/test-module::App/File[/var/www/myserver/index.html]/ensur:
current_value absent, should be file (noop)
Notice: Class[test-module::App]: Would have triggered 'refresh' from 1
Notice: Stage[main]: Would have triggered 'refresh' from 2 events Notice:
Finished catalog run in 0.74 seconds
A linha destacada mostra o resultado do arquivo index.html sendo copiado para o host da web.
Finalizando o Módulo
Com todas as etapas acima, nosso novo módulo que criamos está pronto para uso. Se quisermos criar um arquivo do módulo, isso pode ser feito usando o seguinte comando.
# puppet module build test-module