Hoe maak je Ansible-sjablonen om configuratietijd te besparen

Het beheren van configuraties van meerdere servers en omgevingen is een groot voordeel van het gebruik van Ansible. Maar wat gebeurt er wanneer configuratiebestanden verschillen van server tot server? In plaats van voor elke server of omgeving een aparte configuratie te maken, moet je kijken naar Ansible-sjablonen.

In deze tutorial ga je leren wat Ansible-sjablonen zijn, hoe ze werken en hoe je de Ansible-sjabloonmodule kunt gebruiken om veel tijd te besparen.

Vereisten

Deze post zal een stapsgewijze handleiding zijn. Als je wilt meedoen, zorg er dan voor dat je een Ansible-controllerhost hebt. Deze tutorial zal Ansible v2.9.18 gebruiken

Wat is een Ansible-sjabloon?

Soms moet je tekstbestanden naar externe hosts overbrengen. Die tekstbestanden zijn meestal een soort configuratiebestand. Als je bijvoorbeeld met een enkele server werkt, moet je mogelijk een configuratiebestand genaamd app.conf maken dat door een bepaalde service wordt gebruikt.

Die configuratiebestand kan informatie bevatten die specifiek is voor die server, zoals de hostnaam, het IP-adres, enzovoort. Omdat je met een enkele server werkt, kun je het bestand op de Ansible-controller maken en vervolgens de copy-module gebruiken in een playbook om het naar de server te kopiëren.

Maar wat als je meerdere webservers hebt die elk hetzelfde configuratiebestand nodig hebben, maar elk met hun eigen specifieke waarden? Je kunt het configuratiebestand niet zomaar naar alle machines kopiëren; het is alleen gebouwd voor een enkele server met een specifieke hostnaam, IP-adres, enzovoort. Je hebt een Ansible-template nodig.

Ansible-templates stellen je in staat om tekstbestanden te definiëren met variabelen in plaats van statische waarden, en vervolgens die variabelen te vervangen tijdens de uitvoering van het playbook.

Hoe ziet een Ansible-template eruit?

Een Ansible-template is een tekstbestand dat is opgebouwd met de Jinja2-templatingtaal met een j2-bestandsextensie. Een Jinja2-template ziet er precies uit als het tekstbestand dat je op een externe host wilt krijgen. Het enige verschil is dat in plaats van statische waarden het bestand variabelen bevat.

Bijvoorbeeld, misschien moet je een configuratiebestand genaamd `app.conf` op al je webservers krijgen dat verwijzingen bevat naar het IP-adres van elke respectievelijke server, de Ansible-host en de Ansible-gebruiker. Het `app.conf`-bestand van één server kan er als volgt uitzien:

my_ip    = "192.168.0.1"
my_host  = "ANSBILECONTROL"
my_user  = "ansible_user"

Je kunt dit bestand niet naar elke webserver kopiëren omdat elk item uniek zal zijn, afhankelijk van het IP-adres van de externe host, de hostnaam van de Ansible-controller en de Ansible-gebruiker.

In plaats van deze waarden statisch in te stellen, maakt een Ansible-sjabloon het mogelijk om variabelen te definiëren die tijdens runtime worden geïnterpreteerd en vervangen op de externe host.

Hieronder vind je een voorbeeld van het sjabloonbestand `app.conf.j2`. Je kunt nu zien dat elke statische waarde is vervangen door een variabele die is genoteerd met dubbele accolades aan beide zijden. In dit geval komen deze variabelen van `Ansible-facts`.

Sjabloonbestanden hebben altijd de extensie J2 en hebben meestal dezelfde naam als het bestand dat ze op de doelhost maken.

my_ip    = "{{ansible_default_ipv4["address"]}}"
my_host  = "{{ansible_host}}"
my_user  = "{{ansible_user}}"

Hoe worden gesjabloneerde bestanden gemaakt op externe hosts?

Zodra je een sjabloon hebt gemaakt, moet je dat sjabloonbestand overzetten naar de externe host en “omzetten” naar het daadwerkelijke tekstbestand zoals het eruit hoort te zien. Om dat te doen, moet je het sjabloonbestand refereren in een playbook.

De meeste Ansible-beheerders gebruiken het kopieer module om bestanden naar externe hosts over te zetten, maar zoals hierboven vermeld, is dit niet haalbaar met sjablonen.

Hieronder ziet u een eenvoudig voorbeeldreferentie uit een playbook dat het app.conf bestand kopieert naar de /opt directory op alle doelhosts van het playbook.

- name: copy file from local host to remote host
  copy:                               # Declaring Copy Module 
    src: "app.conf"                   # Source Location 
    dest: "/opt/app.conf"             # Destination Location on remote host

Stel dat u nu de app.conf configuratiebestand “getemplateized” hebt tot een app.conf.j2 sjabloonbestand zoals besproken in de vorige sectie op uw Ansible-controller. U moet er nu voor zorgen dat app.conf nog steeds naar de /opt directory wordt verplaatst, maar met de variabelen vervangen door echte waarden.

Om het playbook te vertellen het app.conf bestand in de /opt directory aan te maken, vervangt u eenvoudig de copy-referentie door template zoals hieronder getoond. Wanneer u dit doet, roept Ansible vervolgens het sjabloonmodule aan om zowel het sjabloon over te zetten als de variabelen te vervangen door statische waarden.

- name: template file to remote host
  template:                 # Ansible template module
    src: "app.conf.j2"      # This is template src i.e source location 
    dest: "/opt/app.conf"   # Destination of Remote host

Zodra de bovenstaande taak in het playbook wordt uitgevoerd, zal Ansible het app.conf.j2 naar de directory van de externe host /opt kopiëren, alle variabelen daarin vervangen door statische waarden en het bestand hernoemen naar app.conf.

Wanneer je de sjabloon src voorziet van een map-pad, zoekt Ansible naar sjablonen in de /<ansible_installatie_directory>/files/ directory. Als je alleen de bestandsnaam opgeeft, zal Ansible het sjabloon zoeken in de /<ansible_installatie_directory>/templates/ directory.

Renderen van een configuratiebestand: Een sjabloonvoorbeeld

Laten we nu een demo bekijken om te zien hoe je een Ansible-sjabloon instelt en de Ansible-sjabloonmodule gebruikt om dynamisch een configuratiebestand te genereren. In dit voorbeeld maak je een bestand genaamd app.conf in de map /etc op een server genaamd SRV1.

De stappen in deze sectie werken voor elk type tekstbestand. De tutorial zal een configuratiebestand als enkel voorbeeld gebruiken.

1. Maak verbinding met je Ansible-controllerhost met de gebruiker die je normaal gebruikt om Ansible te beheren.

2. Maak een map aan in je thuismap om de demobestanden van deze tutorial te bewaren en verander het werkdirectory ernaar.

mkdir ~/ansible_template_demo
cd ~/ansible_template_demo

3. Maak een sjabloonbestand genaamd app.conf.j2 in de map die er als volgt uitziet.

my_ip = {{ansible_default_ipv4["address"]}}
my_host  = {{ansible_host}}
my_user  = {{ansible_user}}

Je kunt ook verschillende variabelen gebruiken die specifiek zijn voor de Ansible-sjabloonmodule in je sjabloon.

4. Maak een eenvoudig playbook in dezelfde map genaamd my_playbook.yml. Dit playbook maakt het bestand app.conf aan in de map /etc.


name: Ansible template example 
hosts: myserver 
remote_user: ubuntu   # Using Remote host as ubuntu 
tasks: 
 - name: Create the app.conf configuration file
   template:
     src: "~/ansible_template_demo/app.conf.j2"
     dest: "/etc/app.conf"
   become: true 

5. Roep het Ansible-playbook aan dat is gericht op de SRV1 externe host.

ansible-playbook my_playbook.yml --inventory SRV1
You should then see Ansible execute the playbook.

6. Bevestig nu dat het configuratiebestand /etc/app.conf bestaat en de verwachte waarden heeft.

confirm the /etc/app.conf configuration file

Bestandsmachtigingen bijwerken met de Template Module

Nu je de basisprincipes van het gebruik van de template-module hebt gezien, laten we nu iets geavanceerder gaan. Voor deze demonstratie ga je hetzelfde app.conf-bestand maken als eerder getoond. Maar deze keer ga je de eigenaar en machtigingen van dat bestand instellen.

Om machtigingen van het bestand dat de template-module creëert te wijzigen, moet je drie parameters binnen het playbook gebruiken:

  • eigenaar – De bestandseigenaar
  • groep – De groep waartoe het bestand moet behoren
  • modus – De machtigingen. Deze tekenreeks kan worden uitgedrukt in symbolen of als octale getallen

In symbolische modus vertegenwoordigt u “gebruiker”, g “groep” en o “anderen”.

Assuming you still have the ~/ansible_template_demo map aangemaakt in de vorige sectie, open het playbook my_playbook.yml en vervang de inhoud met wat hieronder staat. In dit voorbeeld zal Ansible de eigenaar en groep instellen op de Ansible-gebruiker met behulp van verbindingsvariabelen. Vervolgens stelt het de bestandsrechten in op 0644, wat betekent:

  • Eigenaar heeft lees/schrijf toestemming
  • Gebruikers in de groep en anderen hebben leestoestemming
---
- name: Ansible file permission example
  remote_user: ubuntu
  tasks:
    - name: Create the app.conf configuration file and assign permissions
      template:
          src: "~/ansible_template_demo/app.conf.j2"
          dest: "/etc/app.conf"
	  owner: "{{ ansible_user }}"
          group: "{{ ansible_user }}"
          mode:  0644 ## OR  mode: u=rw, g=w,o=r       
      become: true

Alle beschikbare sjabloonelementparameters vind je in de documentatie van de Ansible-sjabloonelementmodule.

Voer nu het playbook opnieuw uit zoals hieronder weergegeven.

ansible-playbook my_playbook.yml --inventory SRV1

Je kunt nu zien dat app.conf de verwachte bestandsrechten heeft gekregen.

app.conf

Gebruik van Loops om Meerdere Bestanden te Sjabloneren

Soms is één bestand niet genoeg; je moet meerdere bestanden toevoegen op een externe host. In dat geval kun je lussen gebruiken met de sjabloonelementmodule. Het definiëren van een lus met de loop-parameter stelt je in staat om veel tekstbestanden toe te voegen die zijn opgeslagen in een map.

Als je nog steeds de ~/ansible_template_demo map hebt aangemaakt in de vorige sectie, zou je al app.conf.j2 daar moeten hebben.

1. Maak een tweede sjabloonbestand genaamd app2.conf.j2 in de map ~/ansible_template_demo zoals hieronder weergegeven.

 template_host = "{{ template_host }}"
 template_uid = "{{ template_uid }}"
 template_path = "{{ template_path }}"
 template_fullpath = "{{ template_fullpath }}"
 template_run_date = "{{ template_run_date }}"

2. Open het bestand my_playbook.yml en vervang alle inhoud met de onderstaande YAML. Dit playbook maakt gebruik van de {{item}} variabele om elk sjabloonbestand te vertegenwoordigen dat in de lus wordt verwerkt. De loop parameter definieert vervolgens elk van de sjabloonbestanden voor de lus om te verwerken.

---
- name: Ansible file permission example 
  remote_user: ubuntu 
  tasks: 
   - name: Create the app.conf configuration file and assign permissions 
     template:   
        src: "~/ansible_template_demo/{{item}}.j2"    # Itereert over 2 sjablonen   
        dest: "/etc/{{item}}"
        owner: "{{ ansible_user }}"   
        group: "{{ ansible_user }}"   
        mode:  0644 ## OF  mode: u=rw, g=w,o=r        
     become: true     
     loop: # Vertel het sjabloonmodule om elk van deze sjablonen te vinden en te verwerken                                              
      - app1.conf 
      - app2.conf 

3. Voer het playbook nu opnieuw uit. ansible-playbook my_playbook.yml --inventory SRV1

ansible-playbook my_playbook.yml --inventory SRV1
Notice now that Ansible sees each template file and processes them accordingly.

Conclusie

Ansible-sjablonen en de sjabloonmodule kunnen je veel tijd besparen en dynamische tekstbestanden maken op al je externe hosts. Het kopieermodule biedt vergelijkbare functionaliteit, maar als je ooit dynamische tekstbestanden moet maken, is de sjabloonmodule je vriend.

Source:
https://adamtheautomator.com/ansible-template/