Skip to main content

WORKSHOP 9: Vault

Alle workshops die je tot nu toe uitgevoerd hebt maakten gebruik van unencrypted passwords. In de vorige workshop leerde je al hoe je het SSH-wachtwoord kon elimineren uit de inventory door gebruik te maken van een public/private key-pair. Dat is echter niet voldoende. Er zijn steeds verschillende variabelen die wachtwoorden of andere gevoelige data kunnen bevatten. Dit kunnen we oplossen door gebruik te maken van een Ansible vault.

Doelstelling

In deze workshop leer je:

  • een Ansible vault aanmaken
  • de Ansible Playbooks en vars aan te passen om gebruik te maken van een Vault.

Workshop Inleiding Vault

Vault is een mechanisme dat toelaat om inhoud te encrypteren en transparant te gebruiken in Ansible workflows. Dergelijke vaults kunnen zowel met het command ansible als ansible-playbook werken.

Vault werkt op bestandsniveau en dat betekent dat een volledige file geëncrypteerd of gedecrypteerd wordt. Vault maakt gebruik van het AES256 algoritme met symmetric keys. Meer info te vinden in de documentatie.

Stap 1 - Een nieuwe vault aanmaken

Het commando ansible-vault is de centrale tool waarmee we de verschillende bewerkingen op encrypted bestanden gaan uitvoeren. Hiermee kunnen we bestanden initieel encrypteren en later bekijken, bewerken of decrypteren.

caution

Werk voor dit deel van de workshop in een aparte map van je Ansible-project.

  • Voorzie een map workshop-vault in je homefolder:

    [student@ControlHost ansible-files]$ cd ~
    [student@ControlHost ~]$ mkdir workshop-vault
    [student@ControlHost ~]$ cd workshop-vault
    [student@ControlHost workshop-vault]$
  • Maak een nieuwe vault (encrypted bestand) aan met de naam vault.yml:

    [student@ControlHost workshop-vault]$ ansible-vault create vault.yml
  • Je wordt gevraagd om een wachtwoord te bedenken waarmee je deze vault wil beveiligen.

    New Vault password:
    Confirm New Vault password:
  • Hierna zal ansible-vault onmiddellijk een standaard editor (vim) uitvoeren waarin je kan je gevoelige data opnemen.

    .vault.yml
    Hier is je supergeheime data!!!!

    Na het verlaten van de editor zou je vault de geëncrypteerde data moeten bevatten.

  • Controleer de inhoud van het bestand vault.yml:

    [student@ControlHost workshop-vault]$ cat vault.yml

    $ANSIBLE_VAULT;1.1;AES256
    63653532313932363434393036376536303164333239656134353230636236306562653466386237
    6332356362353165626365656333613235663336646266380a386332393531333064623339363464
    34373264363733623431623263303735323263646133343039613036616533353865383439616438
    3032343935646535610a356634653539373363386462363833643335633061316231653231323831
    3264

Stap 2 - Bestaande files encrypteren

Als je al over bestanden beschikt die je achteraf wil encrypteren dan kan dat met ansible-vault encrypt.

  • Als test maken we eerst een eenvoudig, niet-geëncrypteerd bestand aan:

    [student@ControlHost workshop-vault]$ echo 'unencrypted data' > encrypt_me.txt
  • Dit bestand encrypteren we nu als volgt:

    [student@ControlHost workshop-vault]$ ansible-vault encrypt encrypt_me.txt
    New Vault password:
    Confirm New Vault password:
    Encryption successful

    In plaats van een editor te openen zal ansible-vault nu onmiddellijk het bestand encrypteren.

  • Bekijk het encrypted bestand:

    [student@ControlHost workshop-vault]$ cat encrypt_me.txt

    $ANSIBLE_VAULT;1.1;AES256
    39346339376237643963363433346233343034333137363835623030626663343765626134356266
    6238346233363931306136653061653636363230666331640a323866313464386566386566333730
    38303935336262376236373138336233303033346633633363326636393432616630613864303964
    6233633136373664330a663366323465656132356237663138323438383835643539303962323763
    37313833333563346664613339313830303665613366353934343563303836353236

Stap 3 - Encrypted bestanden bekijken

Eerder geëncrypteerde bestanden kunnen bekeken worden met ansible-vault view.

  • Test dit uit op je eerste bestand:

    [student@ControlHost workshop-vault]$ ansible-vault view vault.yml
    Vault password:
    Hier is je supergeheime data!!!!

Stap 4 - Encrypted bestanden bewerken

Op een gelijkaardige manier kunnen we eerder geëncrypteerde bestanden bewerken met de default editor via ansible-vault edit.

[student@ControlHost workshop-vault]$ ansible-vault edit vault.yml
Vault password:

Stap 5 - Decrypteren van bestanden

Wanneer een geëncrypteerd bestand niet meer beveiligd moet blijven kan je het decrypteren met ansible-vault decrypt.

[student@ControlHost workshop-vault]$ ansible-vault decrypt vault.yml
Vault password:
  • Controleer of je het bestand nu weer gewoon kan bekijken:

    [student@ControlHost workshop-vault]$ cat vault.yml

    Hier is je supergeheime data!!!!

Workshop Ansible Playbooks met vault

Nu we gezien hebben hoe je bestanden kan encrypteren moeten we even bekijken hoe we dit nu nuttig kunnen toepassen in ansible playbooks en andere bestanden.

Stap 1 - Voorbereiding vars

Om het gebruik van vault in de vingers te krijgen passen we eerst onze bestaand ansible-project wat aan. Momenteel staan in de inventory nogal wat variabelen (waaronder usernames en wachtwoorden). Een aangewezen manier is deze variabelen in de group_vars of host_vars te plaatsen i.p.v. in de inventory.

  • Haal de variabelen in je inventory hosts die betrekking hebben op de groep all weg en plaats deze in een nieuw bestand met de naam all.yml in de map group_vars.

    hosts.yml
    ---
    all:
    hosts:
    children:
    web:
    hosts:
    node1:
    ansible_host: X.X.X.X
    node2:
    ansible_host: Y.Y.Y.Y
    node3:
    ansible_host: Z.Z.Z.Z
    ftpserver:
    hosts:
    node2:
    ansible_host: Y.Y.Y.Y
    control:
    hosts:
    ansible-1:
    ansible_host: A.A.A.A
    vars:
    ansible_user: student
    ansible_password: student
    ansible_connection: local
    ansible_become_pass: student
    vars:
    ansible_port: 22
    # => onderstaande variabelen worden hier weggenomen
    # ansible_user: ubuntu
    # ansible_connection: ssh
    # ansible_become_pass: Azerty123

    In de map ./ansible-files/group_vars/ maak je het nieuwe bestand all.yml waarin je de variabelen van daarnet overneemt:

    all.yml
    ansible_user: ubuntu
    ansible_connection: ssh
    ansible_become_pass: Azerty123
  • Controleer even of je playbook nog steeds werkt. In principe is er niets veranderd en werd alleen de locatie van de variabelen aangepast.

    [student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml

Stap 2 - vars-bestand encrypteren

  • Zoals eerder gezien kunnen we nu het bestand all.yml encrypteren met ansible-vault.

    [student@ControlHost ansible-files]$ ansible-vault encrypt group_vars/all.yml
    New Vault password:
    Confirm New Vault password:
    Encryption successful

Om nu Ansible tijdens de uitvoering van je playbook toegang te geven tot deze geëncrypteerde data geven we de optie --ask-vault-pass mee. Op die manier zal de data on-the-fly gedecrypteerd en gebruikt kunnen worden.

  • Test je playbook uit met de optie --ask-vault-pass:

    [student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml --ask-vault-pass

We passen nu de inventory hosts verder aan zodat er helemaal geen confidentiële data meer staat.

  • Verwijder nu ook de variabelen onder vars in je inventory van de groep control:

    hosts.yml
    ---
    all:
    hosts:
    children:
    web:
    hosts:
    node1:
    ansible_host: X.X.X.X
    node2:
    ansible_host: Y.Y.Y.Y
    node3:
    ansible_host: Z.Z.Z.Z
    ftpserver:
    hosts:
    node2:
    ansible_host: Y.Y.Y.Y
    control:
    hosts:
    ansible-1:
    ansible_host: A.A.A.A
    vars:
    # => onderstaande variabelen worden hier weggenomen
    # ansible_user: student
    # ansible_password: student
    # ansible_connection: local
    # ansible_become_pass: student
    vars:
  • Neem deze variabelen over in een nieuw bestand control.yml in de map group_vars:

    ansible_user: student
    ansible_password: student
    ansible_connection: local
    ansible_become_pass: student
  • Test voor het encrypteren van het bestand control.yml nog eens je project uit. Aangezien we nu de variabelen van de groep control aangepast hebben, testen we best even deze groep uit. Met het onderstaande commando kan je eens alle variabelen opvragen voor een bepaalde host of groep. Zo kan je controleren of effectief de juiste waardes toegekend worden.

    [student@ControlHost ansible-files]$ ansible control -m debug -a "var=hostvars[inventory_hostname]" --ask-vault-pass
note

Desondanks dat we in bovenstaande command enkel ansible gebruiken voor de groep control moeten we toch het wachtwoord opgeven voor het geëncrypteerde bestand all.yml. Dat is omdat ansible by default alle bestanden probeert te laden die in de voorziene mappen-structuur van je project staan.

  • Encrypteer nu ook het bestand control.yml

    [student@ControlHost ansible-files]$ ansible-vault encrypt group_vars/control.yml
    New Vault password:
    Confirm New Vault password:
    Encryption successful
  • Test je playbook nu nogmaals uit:

    [student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml --ask-vault-pass
    [student@ControlHost ansible-files]$ ansible control -m ping --ask-vault-pass

Proficiat! Op dit moment heb je nu een volledig werkend ansible-project dat gebruik maakt van roles en zijn gevoelige data geëncrypteerd heeft.

Stap 3 - Ansible Vault en automation

Op dit moment is er nog steeds een interactie nodig met de uitvoerder van het Ansible-project. Er moet immers telkens een wachtwoord ingegeven worden vooraleer het Ansible commando kan uitgevoerd worden.

We kunnen dus nog een stukje verder gaan en vermijden dat er manueel een wachtwoord moet opgegeven worden.

Dit lossen we op door een bestand aan te maken waar het Ansible Vault Password in staat.

caution

de locatie van dit bestand kan best goed beveiligd zijn. Je slaat dit bestand best niet op samen met je Ansible-project en je beperkt daarnaast best ook de permissies op dit bestand.

  • Maak een bestand .vault_pass.txt aan waarin je vault-wachtwoord staat in je home-folder:

    [student@ControlHost ansible-files]$ echo "MijnWachtwoord123" > ~/.vault_pass.txt

Met de optie --vault-password-file kan je dan verwijzen naar de locatie van van dit bestand zodat je bij uitvoering van het ansible-command geen interactie meer hoeft te doen.

  • Test dit uit:

    [student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml --vault-password-file=~/.vault_pass.txt

Je kan het nog iets vereenvoudigen door in je ansible.cfg een entry te voorzien naar dit bestand. Zo wordt je ansible-command ook weer vrij eenvoudig.

  • Pas je ansible.cfg bestand aan in je project-folder:

    [defaults]

    inventory = ./hosts
    vault_password_file = ~/.vault_pass.txt
  • Test je project nogmaals uit. Je ansible-command zou nu heel eenvoudig moeten zijn en toch gebruik maken van een welbepaalde inventory en bijhorende geëncrypteerde vars-bestanden:

    [student@ControlHost ansible-files] ansible ftpserver -m ping

    [student@ControlHost ansible-files] ansible-playbook test_apache_role.yml
tip

Het is heel gebruikelijk om bepaalde variabelen van een inventory-group die niet "gevoelig" zijn af te scheiden van variabelen die je wil afschermen (typisch credentials, keys, certificates,...). Dit kan je makkelijkst bereiken door je mappenstructuur van je "groups" daarop af te stemmen en op die manier bv. 2 bestanden met variabelen bij te houden voor een groep (encrypted en unencrypted). Meer info daarover kan je lezen op volgende blog.

Nogmaals proficiat! Je bent nu in staat om zelf je eigen Ansible-projecten aan te vatten! Veel succes!!!