Neste artigo, gostaria de falar sobre como usamos o Puppet e o Hiera para configurar servidores virtuais e com ferro. Basicamente, será sobre a arquitetura e a hierarquia que inventamos, o que facilita e sistematiza a configuração dos servidores.
Fui solicitado a escrever este artigo pelo fato de que, na Internet, não encontrei exemplos bons e realmente úteis de como você pode trabalhar com hiera e para que serve. Basicamente, estes são tutoriais com exemplos para entrar no tópico. Mas a aplicação prática real de hiera não está escrita lá. Talvez eu não parecesse bem, mas aqui está um exemplo real que provavelmente o ajudará a colocar todos os pontos em cima de i, como fiz uma vez.
Para quem este artigo seria útil
Se:
- Você sabe o que são Puppet e Hiera, mas na verdade não as usa juntas, porque não está claro como fazê-lo e por que
- Você tem muitas equipes em sua empresa e precisa diferenciar de alguma forma a configuração do servidor no nível do comando
- Você usa um pappet e os arquivos de nós que você cresceu para tamanhos incríveis
- Você gosta de ler a configuração do servidor no formato divino yaml :)
- Você está basicamente interessado no tópico Gerenciamento de configuração e administração do sistema.
Este artigo é para você.
Antes de começar
Avisarei você imediatamente, o artigo acabou sendo longo, mas espero que seja útil. Além disso, entende-se que você já conectou o hiera ao fantoche e pelo menos de alguma forma está familiarizado com o fantoche. Se o hiera não estiver conectado, não será difícil.
Dados de entrada
- Temos cerca de 30 equipes de desenvolvimento no SEMrush, cada uma com seus próprios servidores
- Cada equipe trabalha com seu próprio conjunto de tecnologias (PL, DBMS, etc.)
- As equipes podem e devem (idealmente) usar uma configuração comum para projetos específicos (reutilização de código)
- As próprias equipes gerenciam a implantação de aplicativos em seus servidores (isso não é feito pelo pappet)
Um pouco de história
Inicialmente, tínhamos tudo no pappet da versão 3, depois decidimos implementar o 4º pappet, e todos os novos servidores começaram a ser colocados nele, e os antigos foram lentamente portados para o 4º.
No terceiro pappet, costumávamos usar o sistema clássico de arquivos e módulos de nós. Os módulos foram criados em um grupo especial de projetos no Gitlab, clonados em um servidor pappet (usando r10k ), os agentes do pappet foram ao assistente e receberam um diretório para aplicá-lo ao servidor.
Então eles começaram a tentar não fazer isso e não usar módulos locais, mas colocaram links para os módulos necessários e seus repositórios no Puppetfile. Porque Como esses módulos são constantemente suportados e aprimorados (bem, idealmente) pela comunidade e pelos desenvolvedores, e os nossos locais não. Mais tarde, eles introduziram o hiera e mudaram completamente para ele, e os arquivos dos nós (como o nodes.pp) caíram no esquecimento.
No quarto pappet, tentamos abandonar completamente os módulos locais e usar apenas módulos remotos. Infelizmente, uma reserva deve ser inserida aqui novamente, pois "não funcionou completamente", às vezes você ainda precisa se inclinar e terminar alguma coisa. Obviamente, existem apenas arquivos hiera e nenhum nó.
Quando você tem 30 equipes com um zoológico de tecnologia, o problema de como manter esse zoológico com> 1000 servidores se torna especialmente grave. Além disso, direi como hiera nos ajuda nisso.
Hierarquia
Hiera (de fato, da qual recebeu o nome) estabelece uma hierarquia. Conosco, fica assim:
--- :hierarchy: - "nodes/%{::fqdn}" - "teams/%{::team}_team/nodes/%{::fqdn}" - "teams/%{::team}_team/projects/%{::project}/tiers/%{::tier}" - "teams/%{::team}_team/projects/%{::project}/%{::role}" - "teams/%{::team}_team/projects/%{::project}" - "teams/%{::team}_team/roles/%{::role}" - "teams/%{::team}_team/%{::team}" - "projects/%{::project}/tiers/%{::tier}/%{::role}" - "projects/%{::project}/tiers/%{::tier}" - "projects/%{::project}/%{::role}" - "projects/%{::project}" - "tiers/%{::tier}" - "virtual/%{::virtual}" - "os/%{::operatingsystem}/%{::operatingsystemmajrelease}" - "os/%{::operatingsystem}" - users - common
Primeiro, vamos lidar com variáveis obscuras (fatos).
Cada servidor no SEMrush deve idealmente ter 4 fatos especiais expostos que descrevam sua afiliação:
- fato da
team
- a qual equipe pertence project
fato - a qual projeto ele se relaciona- fato do
role
- que papel esse projeto tem - fato da
tier
- que tipo de preparação ela possui (prod, test, dev)
Como isso funciona? O agente Pappet procura o mestre do Pappet e, com base nesses fatos, procura por arquivos para si mesmo, percorrendo as pastas de acordo com nossa hierarquia. Não há necessidade de indicar que os arquivos de configuração pertencem aos servidores. Em vez disso, os próprios servidores sabem quais arquivos pertencem a eles, observando apenas o caminho e os fatos.
Durante a configuração do servidor, os administradores entram em contato com os desenvolvedores e especificam esses parâmetros (geralmente, pelo contrário, pessoas informadas entram em contato com os próprios administradores) para criar uma hierarquia no hiera no futuro, com base nos quais descrevem a configuração do servidor. Esse sistema ajuda a reutilizar o código e a ser mais flexível em termos de configuração do servidor.
Por exemplo, temos um projeto especial . Neste projeto, pode haver algum servidor front-end com nginx, um servidor back-end com python, um cluster db com mysql, um servidor redis para armazenamento em cache. Todos esses servidores devem ser colocados em um projeto chamado especial e depois atribuir funções aos servidores.
No arquivo do projeto, descrevemos os parâmetros comuns a todo o projeto. A primeira coisa que vem à mente é a criação em todos os servidores do usuário para implantação com a emissão dos direitos necessários a ele e a implementação de suas chaves ssh.
Na função de cada servidor, o serviço geralmente é descrito e personalizado - para o que esse servidor se destina (nginx, python, mysql etc.). Camada nesse caso, definitivamente precisaremos se precisarmos implantar uma cópia do ambiente de produção na plataforma dev, mas mude algo (senhas, por exemplo). Nesse caso, o servidor de desenvolvimento e o servidor de produtos diferem apenas no fato de a camada estar configurada na "posição" desejada (produto ou desenvolvimento). E então um pouco de mágica e hiera farão o truque.
Se precisarmos implantar dois servidores idênticos na mesma função, mas algo neles deve diferir, por exemplo, algumas linhas na configuração, outra parte da hierarquia será resgatada. Colocamos os arquivos com o nome do formato {fqdn }.yaml
no lugar certo (por exemplo, nodes/myserver.domain.net
), definimos os valores necessários das variáveis no nível de um servidor específico, e o pappet aplicará a mesma configuração para os dois servidores para a função e exclusivo para cada dos servidores.
Exemplo: dois backends com código php estão na mesma função e são completamente idênticos. É claro que não queremos fazer backup dos dois servidores - não faz sentido. Podemos criar uma função na qual descrever a mesma configuração para os dois servidores e, em seguida, criar outro arquivo nodes/backend1.semrush.net
no qual colocar a configuração para backup.
O arquivo em lote teams/team-name.yaml
indica a configuração para todos os servidores que pertencem à equipe. Na maioria das vezes, descreve os usuários que podem interagir com esses servidores, bem como seus direitos de acesso.
Com base nessas variáveis, construímos essa hierarquia . Quanto maior o arquivo encontrado na hierarquia, maior a prioridade da configuração especificada nele.
Daqui resulta que as variáveis podem substituir com base nessa hierarquia. Ou seja, a variável no arquivo de função " projects/%{::project}/%{::role}
" tem precedência sobre a variável no arquivo de projeto " projects/%{::project}
". As variáveis também podem ser mescladas em todos os níveis da hierarquia se você tiver um módulo e / ou perfil / função gravados de forma que possam ser executados. Ao especificar a parte comum da configuração do mysql para todos os servidores de projeto, você pode adicionar partes especiais que têm peso para essa função à mesma variável em outros níveis da hierarquia (haverá uma seção adicional na configuração do escravo).
Acontece que o arquivo do nó específico localizado ao longo do caminho “ hieradata/nodes/%{::fqdn}
” tem a maior prioridade. A seguir, vem o arquivo do nó, mas já no nível do comando. Abaixo está o bloco que descreve outros fatos mais gerais:
- "virtual/%{::virtual}" - "os/%{::operatingsystem}/%{::operatingsystemmajrelease}" - "os/%{::operatingsystem}" - users - common
Assim, no arquivo common.yaml
, temos uma configuração que definitivamente deve chegar a todos os servidores, no arquivo users.yaml
todos os usuários são descritos (mas nem todos são criados em servidores, é claro), em os/%{::operatingsystem}
configuração geral típica para servidores com um sistema operacional específico (fact ::operatingsystem
) e assim por diante.
Eu acho que, olhando para essa hierarquia, tudo fica claro. Abaixo, considerarei um exemplo do uso dessa hierarquia. Mas primeiro você precisa falar sobre perfis.
Perfis
Um ponto importante na configuração de servidores usando módulos é o uso de perfis. Eles estão localizados no site/profiles
do caminho e são os pontos de entrada para os módulos. Graças a eles, você pode configurar com mais precisão os módulos suspensos no servidor e criar os recursos necessários.
Considere um exemplo simples. Há um módulo que instala e configura redis. E também queremos definir o parâmetro sysctl vm.overcommit_memory
como 1 ao conectar este módulo, porque aqui . Em seguida, escrevemos um pequeno perfil que fornece essa funcionalidade:
# standalone redis server class profiles::db::redis ( Hash $config = {}, String $output_buffer_limit_slave = '256mb 64mb 60', ) { # https://redis.io/topics/faq#background-saving-fails-with-a-fork-error-under-linux-even-if-i-have-a-lot-of-free-ram sysctl { 'vm.overcommit_memory': ensure => present, value => '1', } class { '::redis': * => $config, } }
Como mencionado acima, os perfis são uma ferramenta que permite alterar / melhorar o comportamento do módulo, além de reduzir o número de configurações no hiera. Se você usar módulos remotos, poderá encontrar o problema de que os módulos “aprovados” geralmente não têm a funcionalidade necessária ou possuem alguns bugs / falhas. Então, em princípio, você pode clonar este módulo e corrigir / adicionar funcionalidade. Mas a decisão certa seria, se possível, escrever um bom perfil que possa "preparar" o módulo da maneira que você precisa. Abaixo estão alguns exemplos de perfis e você pode entender melhor por que eles são necessários.
Escondendo segredos em hiera
Uma das vantagens importantes do hiera, em comparação com o pappet simples, é a capacidade de armazenar dados confidenciais em arquivos de configuração em forma criptografada no repositório. Suas senhas estarão seguras.
Em resumo, você usa a chave pública para criptografar as informações necessárias e as coloca com essa linha no arquivo hiera. A parte privada da chave é armazenada no pappet master, que permite descriptografar esses dados. Mais detalhes podem ser encontrados na página do projeto .
No cliente (computador de trabalho), a ferramenta é instalada simplesmente usando gem install hiera-eyaml
. Além disso, usando um comando no formato eyaml encrypt --pkcs7-public-key=/path/to/public_key.pkcs7.pem -s 'hello'
você pode criptografar dados e colá-los em um arquivo com a extensão eyaml ou apenas yaml, dependendo de como configure e, em seguida, o pappet descobrirá isso. Você obtém algo como:
roles::postrgresql::password: 'ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAbIz1ihQlThMWa9T+Lq194Y6QdElMD1XTev5y+VPSHtkPTu6Al6TJaSrXF+7phJIjue+NF4ZVtJCLkHxUR6nJJqks0fcGS1vF2+6mmM9cy69sIU1A3HqpOHZLuqHAc7jUqljYxpwWSIGOK6I2FygdAp5FfOTewqfcVVmXj97EJdcv3DKrbAlSrIMO2iZRYwQvyv+qnptnZ7pilR2veOCPW2UMm6zagDLutX9Ft5vERbdaiCiEfTOpVa9Qx0GqveNRVJLV/5lfcL5ajdNBJXkvKqDbx8d3ZBtEVAAqeKlw0LqzScgmCbWQx2kUzukX5LSxbTpT0Th984Vp1sl7iPk7UTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCp5GcwidcEMA+0wjAMblkKgBCR/f9KGXUgLh3/Ok60OIT5]'
Ou uma sequência de várias linhas:
roles::postgresql::password: > ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw DQYJKoZIhvcNAQEBBQAEggEAbIz1ihQlThMWa9T+Lq194Y6QdElMD1XTev5y +VPSHtkPTu6Al6TJaSrXF+7phJIjue+NF4ZVtJCLkHxUR6nJJqks0fcGS1vF 2+6mmM9cy69sIU1A3HqpOHZLuqHAc7jUqljYxpwWSIGOK6I2FygdAp5FfOTe wqfcVVmXj97EJdcv3DKrbAlSrIMO2iZRYwQvyv+qnptnZ7pilR2veOCPW2UM m6zagDLutX9Ft5vERbdaiCiEfTOpVa9Qx0GqveNRVJLV/5lfcL5ajdNBJXkv KqDbx8d3ZBtEVAAqeKlw0LqzScgmCbWQx2kUzukX5LSxbTpT0Th984Vp1sl7 iPk7UTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCp5GcwidcEMA+0wjAM blkKgBCR/f9KGXUgLh3/Ok60OIT5]
Parece que terminamos a preparação, agora podemos considerar um exemplo.
Exemplo de dedo
Spoiler : haverá muito mais configurações, portanto quem estiver interessado neste artigo de interesse puramente teórico pode pular esta seção e ir até o final.
Vamos agora ver um exemplo de como configurar um servidor usando o hiera no puppet4. Não publicarei o código para todos os perfis, porque, caso contrário, a postagem será muito grande. Vou me concentrar na hierarquia e configuração da hiera.
A tarefa é esta: precisamos implantar:
- Dois servidores db idênticos nos quais o postgresql está implantado
- Mais dois servidores - front-end com nginx
- Quinto e sexto servidor - back-ends python no docker
- Tudo é o mesmo no ambiente de desenvolvimento, exceto por algumas configurações do servidor
Criaremos nossa hierarquia em ordem e começaremos com o arquivo do projeto.
Projeto
Crie o arquivo de projeto projects/kicker.yaml
. Colocamos nele o que é comum a todos os servidores: precisamos de alguns repositórios e pastas para a implantação, além do próprio usuário da implantação.
--- classes: - apt::debian::semrush files: "/srv/data": ensure: 'directory' owner: 'deploy' group: 'www-data' mode: '0755' '/srv/data/shared_temp': ensure: 'directory' owner: 'deploy' group: 'www-data' mode: '0775' user_management::present: - deploy
Função db
Crie um arquivo de função para os servidores de banco de dados projects/kicker/db.yaml
. Até agora, faremos sem dividir os servidores em ambientes:
--- classes: - profiles::db::postgresql profiles::db::postgresql::globals: manage_package_repo: true version: '10' profiles::db::postgresql::db_configs: 'listen_addresses': value: '*' profiles::db::postgresql::databases: kicker: {} profiles::db::postgresql::hba_rules: 'local connect to kicker': type: 'local' database: 'kicker' user: 'kicker' auth_method: 'md5' order: '001' 'allow connect from 192.168.1.100': type: 'host' database: 'kicker' user: 'kicker' auth_method: 'md5' address: '192.168.1.100/32' order: '002'
Aqui, conectamos um perfil escrito para uso geral por todos que desejam instalar o postgres em seu servidor. O perfil é configurável e permite que você configure com flexibilidade o módulo antes de aplicá-lo.
Para os mais curiosos, abaixo do código do gato para esse perfil:
Perfil :: db :: postgresql class profiles::db::postgresql ( Hash $globals = {}, Hash $params = {}, Hash $recovery = {}, Hash[String, Hash[String, Variant[String, Boolean, Integer]]] $roles = {}, Hash[String, Hash[String, Variant[String, Boolean]]] $db_configs = {}, Hash[String, Hash[String, Variant[String, Boolean]]] $databases = {}, Hash[String, String] $db_grants = {}, Hash[String, Hash[String, String]] $extensions = {}, Hash[String, String] $table_grants = {}, Hash[String, Hash[String, String]] $hba_rules = {}, Hash[String, String] $indent_rules = {}, Optional[String] $role = undef, # 'master', 'slave' Optional[String] $master_host = undef, Optional[String] $replication_password = undef, Integer $master_port = 5432, String $replication_user = 'repl', String $trigger_file = '/tmp/pg_trigger.file', ){ case $role { 'slave': { $_params = { manage_recovery_conf => true, } if $globals['datadir'] { file { "${globals['datadir']}/recovery.done": ensure => absent, } } $_recovery = { 'recovery config' => { standby_mode => 'on', primary_conninfo => "host=${master_host} port=${master_port} user=${replication_user} password=${replication_password}", trigger_file => $trigger_file, } } $_conf = { 'hot_standby' => { value => 'on', }, } file { $trigger_file: ensure => absent, } } 'master': { $_conf = { 'wal_level' => { value => 'replica', }, 'max_wal_senders' => { value => 5, }, 'wal_keep_segments' => { value => 32, }, } file { $trigger_file: ensure => present, } } default: { $_params = {} $_recovery = {} $_conf = {} } } class { '::postgresql::globals': * => $globals, } class { '::postgresql::server': * => deep_merge($_params, $params), } create_resources('::postgresql::server::config_entry', deep_merge($_conf, $db_configs)) create_resources('::postgresql::server::role', $roles) create_resources('::postgresql::server::database', $databases) create_resources('::postgresql::server::database_grant', $db_grants) create_resources('::postgresql::server::extension', $extensions) create_resources('::postgresql::server::table_grant', $table_grants) create_resources('::postgresql::server::pg_hba_rule', $hba_rules) create_resources('::postgresql::server::pg_indent_rule', $indent_rules) create_resources('::postgresql::server::recovery', deep_merge($_recovery, $recovery)) }
Assim, instalamos o Postgresql 10
uma só vez, configuramos o config ( listen
), criamos o banco de dados kicker
e também escrevemos duas regras para acessar esse banco de dados no pg_hba.conf
. Legal!
Função de front-end
Nós assumimos o frontend
. Crie o arquivo projects/kicker/frontend.yaml
com o seguinte conteúdo:
--- classes: - profiles::webserver::nginx profiles::webserver::nginx::servers: 'kicker.semrush.com': use_default_location: false listen_port: 80 server_name: - 'kicker.semrush.com' profiles::webserver::nginx::locations: 'kicker-root': location: '/' server: 'kicker.semrush.com' proxy: 'http://kicker-backend.semrush.com:8080' proxy_set_header: - 'X-Real-IP $remote_addr' - 'X-Forwarded-for $remote_addr' - 'Host kicker.semrush.com' location_cfg_append: 'proxy_next_upstream': 'error timeout invalid_header http_500 http_502 http_503 http_504' proxy_connect_timeout: '5'
Tudo é simples aqui. Conectamos o profiles::webserver::nginx
, que prepara a entrada no módulo nginx, e também definimos as variáveis, especificamente o server
e a location
deste site.
Um leitor atento perceberá que seria mais apropriado colocar a descrição do site mais alta na hierarquia, porque ainda teremos um ambiente de desenvolvimento e outras variáveis ( server_name
, proxy
) serão usadas lá, mas isso não é muito importante. Descrevendo a função dessa maneira, podemos ver como essas variáveis são redefinidas apenas pela hierarquia.
Função do Docker
A função dos projects/kicker/docker.yaml
docker
projects/kicker/docker.yaml
:
--- classes: - profiles::docker profiles::docker::params: version: '17.05.0~ce-0~debian-stretch' packages: 'python3-pip': provider: apt 'Fabric3': provider: pip3 ensure: 1.12.post1 user_management::users: deploy: groups: - docker
O profiles/docker.pp
muito simples e elegante. Vou dar o código dele:
Perfil :: docker class profiles::docker ( Hash $params = {}, Boolean $install_kernel = false, ){ class { 'docker': * => $params, } if ($install_kernel) { include profiles::docker::kernel } }
Está tudo pronto. Isso já é suficiente para implantar o produto que precisamos em muitos servidores, simplesmente atribuindo a eles um projeto e uma função específicos (por exemplo, colocando o arquivo no formato desejado no diretório fatos.d, cuja localização depende do método de instalação do fantoche).
Agora, temos a seguinte estrutura de arquivos:
. ├── kicker │ ├── db.yaml │ ├── docker.yaml │ └── frontend.yaml └── kicker.yaml 1 directory, 4 files
Agora, trataremos dos ambientes e da definição de uma configuração exclusiva para uma função em um site específico.
Ambiente e substituição
Vamos criar a configuração geral para todas as vendas. O arquivo projects/kicker/tiers/prod.yaml
contém uma indicação de que precisamos conectar uma classe a um firewall nesse ambiente (bem, produzir tudo a mesma coisa), bem como uma determinada classe que fornece um nível de segurança maior:
Para um ambiente de desenvolvimento, se precisarmos descrever algo específico, o mesmo arquivo será criado e a configuração necessária será inserida nele.
Em seguida, você ainda precisará redefinir as variáveis para a configuração nginx da função de frontend
- frontend
no ambiente de desenvolvimento. Para fazer isso, você precisa criar o arquivo projects/kicker/tiers/dev/frontend.yaml
. Preste atenção a um novo nível de hierarquia.
--- profiles::webserver::nginx::servers: 'kicker-dev.semrush.com': use_default_location: false listen_port: 80 server_name: - 'kicker-dev.semrush.com' profiles::webserver::nginx::locations: 'kicker-root': location: '/' server: 'kicker-dev.semrush.com' proxy: 'http://kicker-backend-dev.semrush.com:8080' proxy_set_header: - 'X-Real-IP $remote_addr' - 'X-Forwarded-for $remote_addr' - 'Host kicker-dev.semrush.com' location_cfg_append: 'proxy_next_upstream': 'error timeout invalid_header http_500 http_502 http_503 http_504' proxy_connect_timeout: '5'
Você não precisa mais especificar uma classe, ela é herdada dos níveis anteriores da hierarquia. Aqui nós mudamos server_name
e proxy_pass
. Um servidor que possua os fatos role = frontend e tier = dev encontrará primeiro o arquivo projects/kicker/frontend.yaml
, mas as variáveis desse arquivo serão substituídas pelo arquivo com a prioridade mais alta projects/kicker/tiers/dev/frontend.yaml
.
Ocultar senha para PostgreSQL
E assim temos o último item da agenda - defina senhas para o PostgreSQL.
As senhas devem variar em ambientes. Usaremos o eyaml para armazenar senhas com segurança. Crie senhas:
eyaml encrypt -s 'verysecretpassword' eyaml encrypt -s 'testpassword'
Colamos as linhas recebidas nos arquivos **projects/kicker/tiers/prod/db.yaml**
e **projects/kicker/tiers/dev/db.yaml**
(ou você pode usar a extensão eyaml, isso é personalizável), respectivamente. Aqui está um exemplo:
--- profiles::db::postgresql::roles: 'kicker': password_hash: > 'ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAsdpb2P0axUJzyWr2duRKAjh0WooGYUmoQ5gw0nO9Ym5ftv6uZXv25DRMKh7vsbzrrOR5/lLesx/pAVmcs2qbhd/y0Vr1oc2ohHlZBBKtCSEYwem5VN+kTMhWPvlt93x/S9ERoBp8LrrsIvicSYZByNfpS2DXCFbogSXCfEPxTTmCOtlOnxdjidIc9Q1vfAXv7FRQanYIspr2UytScm56H/ueeAc/8RYK51/nXDMtdPOiAP5VARioUKyTDSk8FqNvdUZRqA3cl+hA+xD5PiBHn5T09pnH8HyE/39q09gE0pXRe5+mOnU/4qfqFPc/EvAgAq5mVawlCR6c/cCKln5wJTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDNKijGHBLPCth0sfwAjfl/gBAaPsfvzZQ/Umgjy1n+im0s]'
A seguir, a senha da função kicker
será decodificada e aplicada no servidor de banco de dados no PostgreSQL.
Isso, de fato, é tudo. Sim, o exemplo acabou sendo maciço, mas, espero, funcional, sem deixar perguntas, claro e útil. A hierarquia resultante em hiera é a seguinte:
. ├── db.yaml ├── docker.yaml ├── frontend.yaml └── tiers ├── dev │ ├── db.yaml │ └── frontend.yaml ├── prod │ └── db.yaml └── prod.yaml 3 directories, 7 files
Você pode assistir esses arquivos ao vivo clonando um repositório especialmente criado
Conclusão
O boneco é bom e fácil de usar com o hiera. Eu não chamaria isso de uma ferramenta de configuração ideal no mundo moderno, de maneira alguma, mas merece atenção. Ele lida muito bem com algumas tarefas, e sua “filosofia” de manter um estado constantemente idêntico de recursos e configuração pode desempenhar um papel importante para garantir a segurança e a uniformidade das configurações.
O mundo moderno está gradualmente se sinergizando e se desenvolvendo. Agora, poucas pessoas usam apenas um sistema de configuração, geralmente no arsenal de devops e administradores, existem vários sistemas ao mesmo tempo. E isso é bom, pois há muito por onde escolher. O principal é que tudo deve ser lógico e compreensível, como e onde pode ser configurado.
Como resultado, nosso objetivo como administradores é não configurar nada. Idealmente, tudo isso deve ser feito pelas próprias equipes. E devemos fornecer a eles uma ferramenta ou produto que nos permita fazer isso com segurança, facilidade e, o mais importante, com um resultado preciso. Bem, e ajude a resolver problemas arquitetônicos e mais sérios do que "Você precisa instalar o PostgreSQL no servidor e criar um usuário". Camon, 2018 está no quintal! Então jogue fantoche e ansible e vá para o futuro sem servidor.
Com o desenvolvimento de sistemas de nuvens, contêineres e orquestração de contêineres, os sistemas de gerenciamento de configuração estão lentamente se recuperando para usuários e clientes. Você também pode criar um cluster de contêineres à prova de falhas na nuvem e manter seus aplicativos em contêineres com auto skelling, backup, replicação, descoberta automática, etc., sem escrever uma única linha para ansible, fantoche, chef etc. Você não precisa cuidar de nada (bem, quase). Por outro lado, há menos servidores de ferro devido às nuvens. Só que você não precisa mais configurá-los, essa ação é de responsabilidade do provedor de nuvem. Mas é improvável que eles usem os mesmos sistemas que os mortais comuns.
Créditos
Obrigado:
- Dmitry Tupitsin, Dmitry Loginov, Stepan Fedorov e toda a equipe de administradores de sistemas por sua ajuda na preparação deste artigo
- Vladimir Legkostupov para a foto
- Yana Tabakova por organizar tudo isso e ajudar a passar por todas as etapas de pré-publicação
- Nikita Zakharov pela assistência em questões de licenciamento