Ansible – Automatizando o Data Center

Introdução

Ansible é uma solução para gerenciar os complexos ambientes de hoje em dia – Clouds, ambientes virtualizados, um crescente número de servidores e a sempre demanda por mais.

É um modo seguro, consistente e confiável de gerenciar seu ambiente, sem os problemas de outras ferramentas que adicionam mais complexidade ainda, a um problema que já está complicado.

Site oficial: Ansible « Simple IT Automation

Foi projetado para ser pequeno, consistente, seguro e altamente confiável, com uma curva de aprendizado extremamente baixa para suporte, desenvolvedores e gerentes de TI. As configurações do Ansible são simples descrições de sua infraestrutura em texto, facilmente compreensíveis e simples de modificar.

O Ansible não precisa, nada mais que uma senha ou chave SSH para começar e não precisa que seja instalado nenhum agente, interferindo o mínimo possível em seu ambiente atual. É uma solução super simples, que evita o problema de gerenciar o gerenciamento. Não existe a preocupação se os agentes estão ativos, se precisa atualizá-los, fazer a segurança deles, etc.

Ansible implementa um modelo de idempotência, onde você apenas descreve o estado desejado do sistema ou serviço, não as tarefas para chegar a aquele estado. Assim, não importa em qual estado o sistema esteja, o Ansible sabe como fazer as mudanças até chegar ao estado desejado. Isso permite aplicação de configurações confiáveis e repetíveis, evitando os problemas de scripts que quebram e executam ações irreversíveis.

Baseado no mais seguro sistema de gerenciamento remoto existente, o OpenSSH. Disponível praticamente em todas as plataformas, é muito leve e problemas de segurança são rapidamente resolvidos.

Como previamente falado, Ansible não precisa de agentes remotos. Ele funciona enviando os módulos e executando as tarefas necessárias para chegar às configurações desejadas.

Esses módulos são executados com credenciais fornecidas pelo usuário, incluindo suporte ao sudo e Kerberos, e não deixam seus rastros no servidor, depois de executar (qualquer arquivo temporário, é limpo após a execução).

Ele não precisa de acesso root, chaves SSH ou usuários dedicados e respeita o modelo de segurança do sistema. Ele não exige que o sistema funcione ou esteja configurado de um determinado modo. Assim, o Ansible é muito fácil de instalar/configurar e muito seguro. 

Instalação / Configuração inicial

Instalação

Convenções: para simplificar, chamaremos a máquina que gerencia as outras de Master e as máquinas gerenciadas, de Slaves. Para esse tutorial, usaremos o Ubuntu 12.04 LTS.

Como foi falado anteriormente, o setup do Ansible é muito simples. Ele pede um mínimo de pacotes no Master, todos plenamente disponíveis nos repositórios da própria distro.

Assim, o setup do tutorial compõe-se de: duas VMs Ubuntu 12.04: uma Master e outra Slave. Mas, nada impede de você usar seu Desktop como Master e apenas uma VM como Slave.

Pré-requisitos gerais:

  • Master e Slave conseguem conectar uma à outra via: ssh operador@<ip>
  • Master e Slave podem instalar normalmente pacotes via apt-get.
  • O usuário padrão na Master e Slave é operador. E ele pode tem permissão de sudo su –.

Configuração do Master:

Logue no Master, com o usuário operador. Instale os seguintes pacotes:

$ sudo apt-get install python-paramiko python-yaml python-jinja2 sshpass git

Instalação do Ansible:

Crie um diretório que conterá, tanto o Ansible, quando a infraestrutura de gerenciamento:

$ mkdir ~/manager
$ mkdir -p ~/manager/{hosts,books}

Agora, instale o Ansible:

$ cd ~/manager
$ git clone https://github.com/ansible/ansible.git

Aguarde o download do Ansible via Git.

Configuração inicial

Nesse momento, o Ansible está instalado em ~/manager/ansible. Para ativá-lo, execute:

$ source ~/manager/ansible/hacking/env-setup

Digitando ansible, sem parâmetros, já deveria trazer o Help dele. É recomendável colocar em seu ~/.bashrc, para facilitar, o comando:

source ~/manager/ansible/hacking/env-setup

O próximo passo, é a criação de um arquivo de hosts. Esse arquivo lista os seus servidores e os parâmetros de acesso. Então, crie o arquivo usando o editor de textos de sua preferência, como no exemplo abaixo:

$ vim ~/manager/hosts/ansible_hosts

Como exemplo, criaremos um grupo chamado AppServers com apenas a Slave de testes. O conteúdo do arquivo está listado abaixo (substitua de acordo com seu ambiente). No exemplo abaixo, temos uma VM VirtualBox rodando na mesma máquina, com a porta SSH/22 “nateada” para 51222.

[AppServers]
127.0.0.1 ansible_ssh_port=51222 ansible_ssh_user=operador ansible_ssh_pass=opersenha01

O próximo passo, é exportar a variável ANSIBLE_HOSTS. Ela aponta para o o arquivo ansible_hosts que contém os Slaves que você quer administrar.

Em nosso caso, exportaremos assim:

$ export ANSIBLE_HOSTS=~/manager/hosts/ansible_hosts

Obs.: recomendo colocar a linha acima também em seu .bashrc.

Para testar a configuração:

$ ansible all -m ping

Deveria responder algo assim:

$ ansible all -m ping
127.0.0.1 | success >> {
“changed”: false,
“ping”: “pong”
}

Se der erro, revise o seguintes passos:

1. Usuário/senha do arquivo ansible_hosts.
2. Pode ser necessário instalar o pacote python-simplejson na máquina Slave:

# apt-get install python-simplejson

Outros exemplos, usando módulos:

$ ansible all -m shell -a ‘touch ~/teste.txt’
$ ansible all -m shell -a ‘date’
$ ansible all -m file -a ‘path=~/teste.txt owner=operador group=operador mode=0664’

Módulo / Playbooks

Módulo

Os módulos são os blocos de construção dos Playbooks.

Existem módulos para, praticamente, qualquer tarefa e eles estão evoluindo rapidamente.

Aqui, há uma referência online deles:

Playbooks

São a base do gerenciamento de configuração e deployment de múltiplas máquinas.

Playbooks contém declarações, mas também, podem orquestrar passos de deploy de aplicativos, podem ativar/desativar serviços e garantir que a configuração de um servidor está de um modo específico.

Nesse tutorial, será mostrada uma visão mais prática e imediata dos playbooks. Para a teoria sobre eles, veja a documentação no site:

Então, algumas definições iniciais. Primeiro, como organizar os playbooks. O ideal é que os playbooks fique sob algum controle de versão – de preferência, o Git. Acostume-se a, sempre que alterar e testar um playbook, fazer o git commit, adicionando um comentário relevante sobre a mudança, para consultas futuras.

Inicialmente, vamos começar com um playbook que configurará uma máquina base. Essa máquina poderá, depois, ser customizada para ser um servidor PostgreSQL ou Tomcat, através de outro playbook. Então, vamos ver como criar e aplicar essa configuração.

O primeiro passo, é criar a estrutura de diretórios:

Mude para o diretório de playbooks:

$ cd ~/manager/books/

Vamos chamar essa configuração de Basica e criar a estrutura. Rode os seguintes comandos:

$ mkdir Basica
$ mkdir -p Basica/uploads
$ cd Basica

* Copie um arquivo /etc/sudoers de um S.O. identico ao quê você vai instalar para o diretório uploads.

O diretório Basica/uploads, agora, deverá conter o arquivo sudoers copiado.

Edite esse arquivo, com o editor de sua preferência (vim uploads/sudoers) e adicione a seguinte linha no final do arquivo:

operador   ALL=(ALL) NOPASSWD:ALL

Agora, vamos criar o playbook que vai enviar esse arquivo para o servidor, com as permissões corretas. Agora, edite o arquivo Basica.yml e adicione o seguinte conteúdo:


– hosts: all
user: operador
sudo: yes
tasks:
– name: Ativando o sudo sem senha
action: copy src=./uploads/sudoers dest=/etc/sudoers owner=root group=root mode=0440

– name: (A) Remove o sources.list original
action: shell rm -f /etc/apt/sources.list

– name: (B) Baixando o sources.list
action: get_url url=http://172.25.137.131/sources/sources12.04.list dest=/etc/apt/sources.list owner=root group=root mode=0644

– name: Atualizando o cache do apt
action: apt update_cache=yes

– name: Atualizando o sistema
action: apt upgrade=full

– name: Criando o locale pt_BR.UTF-8
action: shell locale-gen pt_BR.UTF-8

– name: Atualizando todos os locales
action: shell locale-gen

– name: Instala o DKMS
action: apt name=dkms state=latest

– name: Instalando o Build-essential
action: apt name=build-essential state=latest

– name: Mudando o scheduler de disco default para NOOP
action: lineinfile dest=/etc/default/grub regexp=’^GRUB_CMDLINE_LINUX_DEFAULT=’ line=GRUB_CMDLINE_LINUX_DEFAULT\=\”elevator\=noop\”

– name: Mudando o scheduler de disco para NOOP
action: lineinfile dest=/etc/default/grub regexp=’^GRUB_CMDLINE_LINUX=’ line=GRUB_CMDLINE_LINUX\=\”elevator\=noop\”

– name: Atualizando o Grub
action: shell sudo update-grub

– name: Limpa o cache do Apt
action: shell sudo apt-get clean all

– name: Reiniciando o servidor
action: command reboot

O playbook acima é, praticamente, autoexplicativo. O mais notável é que ele altera arquivos de configuração do sistema para a opção desejada (os módulos lineinfile).

Obs.: as ações (A) e (B) só são necessárias, se você usa um sources.list customizado. Senão, retire-as do playbook.

Para executar esse playbook:

$ ansible-playbook –ask-sudo-pass Basica.yml

A razão da opção –ask-sudo-pass é que, nesse momento, o S.O. ainda está pedindo senha para fazer sudo su –. Ele executará um pouco e falhará, porque está esperando o prompt de sudo. Mas na segunda vez, execute-o assim:

$ ansible-playbook Basica.yml

Depois do playbook ser executado, ele não mais pedirá senha para comandos administrativos.

ansible_hosts / arquivo Ansible Host

Senhas ansible_hosts

Particularmente, eu prefiro o uso do arquivo ansible_hosts com usuário e senhas. Mas, se quiseres usar por chave mesmo, eu recomendo o seguinte: se a quantidade de servidores for muito grande (como é o caso de vocês), coloquem a senha no ansible_hosts, como no exemplo que mandei, rodem os comandos abaixo:

1. Enviando sua chave somente para o servidor nova:

$ ansible all –limit nova -m copy -a ‘src=~/.ssh/id_rsa.pub dest=~/minhachave.pub’

2. Verifique se o servidor realmente tem o diretório .ssh com a chave privada:

$ ansible all –limit nova -m shell -a ‘ls .ssh -al’

nova | FAILED | rc=2 >>
ls: cannot access .ssh: No such file or directory

Nesse caso, não tem. Então, vou mandar criar remotamente a chave:

$ ansible all –limit nova -m shell -a “ssh-keygen -P ‘f0rm1g@’ -f /home/operador/.ssh/id_rsa”

2. Agora sim, você pode adicionar sua chave copiada no passo 1 para o servidor:

$ ansible all –limit nova -m shell -a “cat minhachave.pub >>.ssh/authorized_keys”

3. Garantindo que o arquivo authorized_keys esteja com as permissões corretas:

$ ansible all –limit nova -m shell -a “chmod 644 .ssh/authorized_keys”

Nesse ponto, você já deveria conseguir fazer SSH para o servidor sem precisar de senha. Agora, retire as senhas do ansible_hosts.

Ou, então, deixe apenas uma pessoa com o arquivo com senhas, responsável por enviar as chaves para os servidores e os outros conectam apenas por chave.

P.S.: lembre-se que, se o arquivo ansible_hosts está sem as senhas, será preciso adicionar “–ask-pass” nas chamadas do Ansible, para que ele peça a senha.

Criando arquivo Ansible Host

Para criação do arquivo ansible_host, é necessário editar o arquivo:

Obs.: coloquei as barras como comentários no arquivo.

[centos]  // Nome do Grupo de Host
34 ansible_ssh_host=172.25.137.34 ansible_ssh_user=root ansible_ssh_pass=xxxx23
101 ansible_ssh_host=172.25.137.101 ansible_ssh_user=root ansible_ssh_pass=xxxx23
129 ansible_ssh_host=172.25.137.129 ansible_ssh_user=root ansible_ssh_pass=xxxx23
132 ansible_ssh_host=172.25.137.132 ansible_ssh_user=root ansible_ssh_pass=xxxx23

Na ordem de leitura e composta de:

  1. Nome do host.
  2. IP ou DNS de destino onde será executado o procedimento.
  3. Usuário que irá conectar ao host.
  4. Senha de acesso ao host.
Rolar para cima