Puppet, Ansible, Salt
Maturidade, Simplicidade e Flexibilidade
Diego Morales
morales@propus.com.br
@dgmorales
/papodesysadmin
Por quê?
Infraestrutura como código
É para todos
Exemplo: um base system
- Repositórios de pacotes (mirrors/proxy)
- Resolver DNS, cliente NTP
- Usuários, integração LDAP/AD
- Agente de monitoramento, SNMP
- Backup (agente, etc)
- Regras gerais de FW
- Config de envio de emails
- Logs: rotação, servidor central
Ahh ... mas eu tenho uma imagem, preseed/kickstart, script, documentação ...
Não é só velocidade e escala
É documentação executável. Permite ...
- ... consistência na implementação
- ... preservar e evoluir conhecimentos
- ... versionamento
- ... revisão pelos pares
- ... testes repetíveis, e até automatizados
- ... uma gerência de mudanças que faz sentido
Config Management
Em uma palavra ...
Puppet: Maturidade
Ansible: Simplicidade
Salt: Flexibilidade
Puppet
Criado em 2005, por um sysadmin, Luke Kanies
Recentemente: PuppetLabs → Puppet
Puppet (2)
- Master (pull) e Masterless (pull rodando local).
- Linguagem: Puppet DSL + templates ERB (ruby)
- Feito em ruby / clojure / java ...
- ... DSL torna isso geralmente irrelevante.
- Segurança e auth: certificados SSL.
- Mcollective para orquestração.
Puppet (3): Enterprise
Puppet (4): não Enterprise
Ansible & RedHat
"Ansible’s main goals are simplicity and ease-of-use."
Criado em 2012, por Michael DeHaan.
Ansible (2)
- Agentless
- Push over SSH (Simplicidade!). Pull rodando local.
- Lento? Veja algumas alternativas [1] [2]
- Windows: WinRM + PowerShell Remoting
- Simplifica orquestração em várias máquinas
- Linguagem: YAML + templates jinja2
- Python!
- Auth/Crypto: seu fiel amigo SSH
Ansible (3): Tower
- Dashboard, Inventário, Remote Execution ...
- ... e agora System Tracking também.
- 3 variantes, US$ ~ 50-140/node/ano.
Ansible (4): não Tower
- Rundeck como frontend do Ansible parece bem popular.
- Semaphore: Open Source Alternative to Ansible Tower.
- (não, não é o SemaphoreCI)
- Foreman de novo.
Salt & SaltStack
Criado em 2011, por Thomas Hatch.
Salt (2)
- Push/Pull com ZeroMQ , Pull rodando local. (Flexibilidade!)
- Rápido! (com ZeroMQ)
- Linguagem: YAML + templates jinja2
- A sua receita é um template jinja!
- Python again
- Auth/Crypto: meio problemático.
- ZeroMQ não tem SSL. Salt adiciona AES em cima.
- Novos transportes no forno: RAET, outro TCP usando Tornado.
Salt (3): Enterprise
?
- Novato: 4.0 em early adopter program. 4.5 a ser lançado
- Sem pricing divulgado. É meio camuflado.
Salt (4): não Enterprise
Package, File, Service
Se fosse possível fazer apenas isso, já seria muita coisa.
Puppet
package { 'openssh-server':
ensure => installed,
}
file { '/etc/ssh/sshd_config':
source => 'file:///vagrant/puppet/sshd_config',
owner => 'root',
group => 'root',
mode => '0644',
notify => Service['ssh']
# require => Package['openssh-server'],
}
service { 'ssh':
ensure => running,
enable => true,
}
O require não é mais necessário no 4.x, ele segue a ordem do manifest
package, file e service são resources
Ansible
- hosts: all
name: Install SSH Server
tasks:
- package: name=openssh-server state=present
- template:
src: sshd_config
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: 0644
notify:
- restart ssh
- service: name=ssh state=started
handlers:
- name: restart ssh
service: name=ssh state=restarted
Não me ajuda na tese de simplicidade, eu sei
Install SSH Server é uma play, aplicada em all hosts
package, template e service são modules
Salt
openssh-server:
pkg.installed:
- name: openssh-server
service.running:
- name: ssh
- enable: True
file.managed:
- name: /etc/ssh/sshd_config
- source: salt://sshd_config
- user: root
- group: root
- mode: 644
- watch_in:
- service: openssh-server
Esta é uma formula, pkg.installed, service.running e file.managed descrevem states dentro da fórmula.
Loops
Puppet
$binaries = ["run", "build", "update", "foo"]
$binaries.each |String $binary| {
file {"/usr/local/bin/myapp-$binary":
ensure => link,
target => "/opt/myapp/bin/$binary",
}
}
Requer puppet 4.x ou parser=future
each, slice, filter, map, e mais
Ansible
- hosts: all
tasks:
- name: create symlinks for our app
file: >
state=link src=/opt/myapp/bin/{{ item }}
dest=/usr/local/bin/myapp-{{ item }} force=yes
with_items:
- run
- build
- update
- foo
with_dict, with_nested, with_fileglobs, e mais...
outros jeitos de quebrar ... >
... linhas
Aproveitando: Idempotência?
Salt
{% for binary in ['run', 'build', 'update', 'foo'] %}
/usr/local/bin/myapp-{{ binary }}:
file.symlink:
- target: /opt/myapp/bin/{{ binary }}
{% endfor %}
Jinja. Dentro da sua formula salt.
Programe o seu código. Pode ser bom, pode ser ruim.
Usado por tudo, inclusive pillar (definição condicional de variáveis).
Comunidade e Brasil
Puppet, pacote completo: listas br e en, telegram, IRC #puppet-br, #puppet, meetup. Empresa BR: Instruct e outras...
https://telegram.me/puppetbr
Ansible em inglês: #ansible, lista. Meetups BR parados: SP e RJ. Lista BR?
https://telegram.me/ansiblebr
Salt ... em inglês: #salt, lista. Comunidade muito forte, campeão em contribuidores (1500+). No Brasil, nada...
Concluindo
De novo: maturidade, flexibilidade, simplicidade. Qual é o mais importante?
Github repo: exemplos de código nos 3, dashboards, etc.
https://github.com/dgmorales/cm-sandbox
Cena pós-creditos!
Terminologia