Ansible 101

Ansible^[Ansible] é uma ferramenta para automação de TIC. Com ela é possível configurar sistemas, realizar deploy de aplicações e serviços, orquestrar ativos de rede, aprovisionar máquinas em ambientes virtualizados ou de nuvem privada ou pública.

Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates. - Ansible Documentation^[Ansible Documentation]

Considero Ansible uma ferramenta bastante versátil no campo de gestão de configuração de ativos de TIC e com uma baixa curva de aprendizado. Sua DSL (Domain-specific language^[Domain-specific language (DSL)]) é fundada no padrão YAML^[YAML Ain’t Markup Language] que também é bem simples de ser escrito. Como visto nesse exemplo simples:

---
- name: "Olá, mundo Ansible!"
  hosts: servidor-01.local
  tasks:
    - name: Uma tarefa fantasma
      debug:
        msg: "Olá, Ansible!"

A gestão do parque de servidores e serviços é realizada sem uso de agente remoto (agente-less) e usa basicamente SSH para orquestrar os recursos, embora também tenha outros recursos de transporte para que cada servidor obtenha sua própria configuração.

Como qualquer ferramenta para gerir configurações de TIC, Ansible pode ser indepotente, a depender de como se escreveu-se sua playbook ou role que são a forma básica que falaremos a seguir.

Idempotência: Em matemática e ciência da computação, a idempotência é a propriedade que algumas operações têm de poderem ser aplicadas várias vezes sem que o valor do resultado se altere após a aplicação inicial. - Wikipedia^[Idempotence]

Playbooks, Roles e Inventário

Para realizar a orquestração automatizada por código via Ansible são necessários basicamente escrever playbooks e/ou roles.

Inventário

Inventários são parâmetros a serem utilizados pelas playbooks/roles e poderão conter por exemplo (inventario.yml):

---
web-server:
  hosts:
    node-1.mylab:
    node-2.mylab:
  vars:
    nginx_version: 1.14.2
    repositorios_extras_enabled: True

Este bloco exemplifica conjunto de atributos para implementação de grupo de servidores web-server que é composto pelos servidores node-1.mylab e node-2.mylab. As variáveis listadas são os parâmetros necessários para customizar o uso da playbook ou role a ser executada.

Playbook

Numa definição simples, playbooks e/ou roles conterão os procedimentos, comandos etc descritos em arquivos base yaml (playbook.yml).

---
- name: "orquestração de web-server"
  hosts: web-server
  roles:
    - my.os_bootstrap
  tasks:
    - name: Uma tarefa fantasma
      debug:
        msg: "Olá, Ansible! Instale NGINX {{ nginx_version }} no {{ ansible_fqdn }}"

No exemplo acima, a playbook será executado nos servidores web-server (definidos no inventário) e requer a role my.os_bootstrap previamente instalada ou escrita. A tarefa da playbook somente irá mostrar a mensagem em cada execução e para cada um dos servidores.

Assim, para executar a playbook com aqueles dados de inventário execute:

$ ansible-playbook --ask-pass -u <SSH_USER> -i inventario.yml playbook.yaml

executção de ansible-playbook

Instalação

A máquina a partir da qual serão executadas as playbooks Ansible (control plane) necessita conter Python 2.7 ou Python 3 (3.5 ou superior). Entretanto, Windows™ não é suportado como control plane^[Ansible - requisitos da máquina de controle].

Assim, será necessário que seja instalada uma máquina com sistema operacional Linux. Aqui a instalação é exemplificada no uso de Fedora.

$ sudo dnf install ansible

É simples assim! E já teria sua máquina de controle para orquestração de máquinas e ambientes sob Ansible.

$ ansible --version

ansible 2.8.2
 config file = /etc/ansible/ansible.cfg
 configured module search path = ['/home/adriano.vieira/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
 ansible python module location = /usr/lib/python3.7/site-packages/ansible
 executable location = /usr/bin/ansible
 python version = 3.7.4 (default, Jul  9 2019, 16:32:37) [GCC 9.1.1 20190503 (Red Hat 9.1.1-1)]

Após a instalação, você poderá acessar a estrutura de configurações do Ansible em /etc/ansible e ajustar conforme a sua necessidade. Naquele diretório você poderá encontar a seguinte estrutra:

/etc/ansible
├── ansible.cfg    # arquivo base para configurar o ansible
├── group_vars     # diretório para manter inventário seguindo o nome de grupos de servidores
├── hosts          # arquivo base para definir nomes de grupos de servidores
├── host_vars      # diretório para manter inventário seguindo o nome servidores
└── roles          # diretório base para conter roles instaladas ou criadas por você

Esta estrutura pode variar dependendo de configurações do seu S.O. ou personalizações que um sysadmin tenha feito.

Encriptar / Desencriptar dados sensíveis

Cofre lógigo para dados sensíveis (Vault ou Cofre de senhas), é o recurso que viabiliza que dados do inventário sejam armazenados na forma encriptada. Assim, havendo dados sensíveis e armazena-los em texto puro num sistema de controle de fontes pode deixa-los vulneráveis a acessos indevidos. Para contornar isso, dados sensíveis podem ser armazenados usando-se Ansible Vault^[Ansible Vault].

Vault é um recurso Ansible para armazenar dados sensíveis como senhas, dados de ambientes produtivos, entre outros que forem considerados necessários proteger via um “cofre lógico”.

Para encriptar dados sensíveis o Ansible Vault poderá ser usado como neste exemplo:

ansible-vault encrypt_string <--ask-vault-pass | --vault-id arquivo_de_chave_do_cofre> \
                             --name 'nome_variavel'  'dado sensível'

onde:

  • <--ask-vault-pass | --vault-id arquivo_de_chave_do_cofre>: para informar a chave a ser usada para encriptar o 'dado sensível' - e deve ser a mesma para encriptar ou desencriptar. Apenas o --vault-id ou --ask-vault-pass deve ser usado para encriptar ou desencriptar.
nome_variavel: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          64343630316366316565393535383739653537653466383932366335303062613734323136636434
          6131316161336436633264326537653539646436383765360a313834323132346637303934326564
          64643537386164333265363935613365663536623963353133306263663136343065373566393935
          6534653534323730390a363265653939623432633261373063313136653533343237666231323664
          3430
Encryption successful

Estes valores pode ser armazenados em variáveis (em texto puro ou via vault) em diretórios/arquivos especiais podendo ser declaradas diretamente na Playbook ou em arquivos de inventário (ex: host_vars, group_vars etc). Exemplo disto são:

  • group_vars/web-server.yml
nginx_version: 1.14.2
repositorios_extras_enabled: True
# variável com valor encriptado
nome_variavel: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          64343630316366316565393535383739653537653466383932366335303062613734323136636434
          6131316161336436633264326537653539646436383765360a313834323132346637303934326564
          64643537386164333265363935613365663536623963353133306263663136343065373566393935
          6534653534323730390a363265653939623432633261373063313136653533343237666231323664
          3430

Alem de encriptar/desencriptar uma chave de cada vez, também é possível fazer com um arquivo e todo o seu conteúdo. Suponha que tenha o datasource acme-ds.xml e conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<datasources xmlns="http://www.jboss.org/ironjacamar/schema"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd">

  <datasource jta="false" jndi-name="java:jboss/datasources/acmeDS" enabled="true"
              pool-name="acmeDS_Pool" use-java-context="true" use-ccm="true">
    <connection-url>jdbc:postgresql://db-server01.mylab:5432/db_acme</connection-url>
    <driver>org.postgresql</driver>
    <driver-class>org.postgresql.Driver</driver-class>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
      <min-pool-size>2</min-pool-size>
      <max-pool-size>20</max-pool-size>
      <prefill>true</prefill>
      <use-strict-min>false</use-strict-min>
      <flush-strategy>FailingConnectionOnly</flush-strategy>
    </pool>
    <security>
      <user-name>DB_USERNAME</user-name>
      <password>DB9USERP@sS</password>
    </security>
    <statement>
      <prepared-statement-cache-size>32</prepared-statement-cache-size>
      <share-prepared-statements />
    </statement>
  </datasource>
</datasources>

Para encriptar o arquivo use o comando ansible-vault encrypt com a chave foo_Key4Vault para encriptar o datasource.

$ ansible-vault encrypt --ask-vault-pass acme-ds.xml

New Vault password:
Confirm New Vault password:
Encryption successful

Após o comando, o conteúdo do arquivo (cat acme-ds.xml) será como o mostrado a seguir:

$ANSIBLE_VAULT;1.1;AES256
36643436663931326264336137643030626636666630356239616435386361316466373734373034
6533356539313937383364383665613933636235386639330a363734306666626138636433303863
66326562316533613262353365656239386231333236663765643431333364396439656333316134
6166613466316638340a646639383738396535393064623165386136656664633133396430353231
31393566646466363337313235323038386538343430623834383334393039613238633839323664
65353634656533646430363763623132353533623866363865303265333939623566386366626232
66346237353234356463643935313037373536383666323166393461343339313661646437653530
63666339643162386530623032626530343630333637396632376539393135646662626661633332
65623837353361343565663732353337303833343538373035613663386639646265343262643839
66323462333834366138376562386235346431633361383238383366363263333663306232376432
62363462626238343232316538396432343735663832363536623730666137386438313937636664
33393739386130396630613363653831383935336465643337626337303566366361396232383563
35316263653434343031336433356565636361363234623037623234373862353639383131373465
32363037346638366635386632653433656261363635623131303133323537633138613535393730
65336437313635313738393662396534323966343164303365663661383263613339646336383164
32613439333036373032383738303733623835376463663066356237363164383163663864623635
65643962633661303536656138333635326435666462336430636635366237626163383630356464
62366337343636643631396163353832643965363332633735616566663437616361316461633039
34313131393163613963303563373162353561633334383665653965656632356266373062313962
39326466353431623261366536393830356364653230633038623764353763363634366339396535
36323438643361656531303562356533356163383465303661396462373630643362313162643764
39346137636233366439323834663636363938646435393266303036306162353262393734663362
36386435353432316435366535376436663434313839386664383535306638303333343835386336
64336432396431376361373431373363306237636264333330363839386433343532323165366333
31653338653039333138623631393063626239313966316632343436303938626263616364613937
33626535613431393064383761643264306239343033626332646237663765623535353632376539
65306261663438363466656561383534653332653265656533663237653639376633393733383333
30393138626531633463326137393033346339636634636239356336326639356463393739616535
61353161616330376335636132363430373635623538613439356236313131316537633165383761
39633837383135303434633735656534383139383864353638363633613465646330303638383332
31636436366430393434306464333564323037393065396131343466643831623964343837633566
65353963326531396136663335356334613438316139373637306437313035646333363939383636
38636238393031613163653235313363313263386333663932656338313331626234653764303635
38346636393934636363643063666232333437303563633664353132636233356135336535386137
62323332396561613262653233616630313862386634326666323731356662363537636263656330
61646430333230303433313036303661303766326231383139623862376236653737633530656462
64663835363933613534666263636134636330643933376565363661393230336562393261346163
62376236306134613831323666313462383938326430363935346364653230313732353235663361
32313638393835393035656231383666643031643962643161623336616531336163306366343365
35373235613739653161373733386536303863316234306461323366326633323664396232636462
31666531633366323366323465626665353661366233373061366261333033613130323230653161
65306333653462303264613434313238376161636461343162653262333961653534323033376131
30373965633731396661653139393361633465353734396230363231366233343931366165373264
64306464666133643062613933383165323134663530633563363730613935383965666532336662
34623861323630613861616537326633373862363835336661383964363835663237666265656132
35636230636535353232643939643831343135643932396536643566646431623862666565336465
31616263636636326666633231376430363861656634623536316531366561306431343238316437
61653036636635613661643331643236656166376565633863623166313032306231303465363439
61336165646566653462336663336366633862623735383736323363323862373031613538666635
35623661336135343433313635656331653738326566353231373463303564646331356364343538
31646633663635616161666131616133373230366563633930366361396239336436613034626330
30376331623965343230373062616462643136376232326538653866366434336435366166376532
63663837326461326562363335356566363266386235326162623836306633396639336162646535
36616130636131633933663237333236663832343735313462323638616535373932623036393335
66323663666538383265663065663538306236393563346238373732303739653064393336316232
63346533613436373435626439393537363339343861656434303031323262373832303062643763
36346463346236643435356332313565356235396236346133346235316232656636343130653839
36336635323061323232306335643539356462653134643263653336646365373166336333363432
37343664613661333462343134376364343135656336303261393836313435636562346464313265
37393661386334613265633637616165663261363034313764663338636539336434633733616630
66313765646339633165393830353966653665656636316130366136616265613165646236343634
62643739636239353531363039663539376133336638343637346139396637643433666136633230
32623664336563363665353466383564646131373632373734393030653766396164636161626437
39366362323561383863373666366532373964323664633762376364653037643466326463393432
61396261626638333035333264353734646662323932663434363734346634323334633231653962
6138373665633364306666646639663632366165616563616636

E para desencriptar…

$ ansible-vault decrypt --ask-vault-pass acme-ds.xml

Vault password:
Decryption successful

Referências