Integratie van Terraform met Ansible

Terraform en Ansible zijn krachtige tools die worden gebruikt om infrastructuren te implementeren en applicaties te configureren.

Terraform

Terraform is een infrastructuur als code tool waarmee je op een veilige en efficiënte manier infrastructuur kunt bouwen, wijzigen en versiebeheren. Hieronder vallen zowel laag-niveau componenten zoals rekeneenheden, opslag en netwerken, als hoog-niveau componenten zoals DNS-vermeldingen en SaaS-functies.

Ansible

Ansible is een open-source, opdrachtregel IT-automatiseringssoftware geschreven in Python. Het kan systemen configureren, software implementeren en geavanceerde workflows orchestreren om applicatie-implementatie, systeemupdates en meer te ondersteunen.

De belangrijkste sterke punten van Ansible zijn eenvoud en gebruiksgemak. Het heeft ook een sterke focus op beveiliging en betrouwbaarheid, met minimale bewegende onderdelen. Het gebruikt OpenSSH voor transport en een leesbare taal die is ontworpen om snel aan de slag te gaan zonder veel training.

De verschillen en overeenkomsten

Terraform richt zich voornamelijk op het implementeren van een (cloud) infrastructuur en de focus van Ansible ligt op het configureren van een reeds geïmplementeerd systeem. Dat gezegd hebbende, Ansible is ook in staat om infrastructuren te implementeren en Terraform is ook in staat om systemen en applicatiestacks te configureren.

Dit roept de vraag op, welke tool het beste is voor wat we willen doen. En het antwoord op die vraag hangt, zoals altijd, af van de use case, de omgeving en ook de capaciteiten en kennis van de mensen die de “stack” onderhouden. Het is ook mogelijk om deze te combineren en de sterke punten van beide te gebruiken. Er zijn (3rd party) Terraform resources die het mogelijk maken om Ansible te gebruiken in een Terraform-plan en voor Ansible is er een Terraform-module die ondersteuning biedt voor het implementeren van resources met Terraform en het terugtrekken van resource-informatie in Ansible.

In deze blog zullen we uitleggen hoe de Terraform-module met Ansible kan worden gebruikt om (virtuele) systemen te implementeren en ze te configureren na implementatie.

Onze Use Case

Ons gebruiksscenario is heel eenvoudig: we willen een webapplicatie implementeren. Voor de eenvoud zullen we een webserver (NGINX) implementeren op een virtuele server die wordt ingezet met behulp van Terraform.

Opzet

Terraform gebruikt “providers” om systemen te voorzien op een specifieke (cloud)provider, bijvoorbeeld AWS (Amazon) of GKE (Google). In dit geval zullen we de “libvirt” provider gebruiken die virtuele machines kan voorzien op een Linux hypervisor. De virtuele machine zal worden gecreëerd met behulp van een Rocky Linux cloud image.

We zullen het ‘infrastructuur’-gedeelte dat wordt gedaan met Terraform scheiden van het configuratiegedeelte dat wordt uitgevoerd met Ansible. Deze gelaagde opzet zorgt ervoor dat overstappen naar een andere infrastructuurprovider kan worden gedaan zonder significante investering.

Vereisten

Zowel Ansible als Terraform moeten geïnstalleerd zijn, evenals de Ansible-collectie community.general, die de Terraform-module bevat. De Terraform-provider libvirt kan vooraf geïnstalleerd zijn op de controller-host, anders wordt deze opgehaald tijdens de ’terraform init’-fase.

Ansible playbook

Ons Ansible playbook bevat twee plays, één om de virtuele machine te installeren en de andere om de webserver te configureren. De belangrijkste truc die wordt gebruikt, is dat in het eerste deel het inventarisbestand (in het geheugen) wordt gemaakt voor het tweede deel.

playbook.yml

Kopiëren naar het Klembord

Dit bestand (playbook.yml) kan worden toegepast met de volgende command:
ansible-playbook -i localhost, playbook.yml
Door de inventaris op deze manier te specificeren, met de hostnaam localhost en een komma aan het einde, vertel je Ansible dat alle hosts op de opdrachtregel zijn gespecificeerd en niet moeten worden gelezen uit een inventarisbestand, zoals je dit normaal zou doen. De infrastructure role voert de TerraForm binary uit op de controller-host, vandaar dat de hostnaam “localhost” wordt gebruikt.

Ansible infrastructuurrol

De infrastructure role installeert de virtual machine en gebruikt een standaard Rocky Linux cloud image om het besturingssysteem te deployen.

roles/infrastructure/tasks/main.yml

Kopiëren naar het Klembord

De meeste cloud-images gebruiken een component genaamd cloud-init om extra configuratie in te voegen, zoals een gebruiker en een veilige shell-sleutel, in de vooraf gemaakte image. De eerste taak in deze rol genereert een cloud-init configuratiebestand dat wordt opgepikt en uitgevoerd tijdens de eerste opstart van het systeem. Het cloud-init bestand dat hier wordt gebruikt, wordt gegenereerd uit een sjabloon. Dat sjabloon verzamelt informatie van de gebruiker die dit Ansible playbook uitvoert en gebruikt deze om het bestand te genereren.

cloud-init.cfg.j2

Kopiëren naar het Klembord

Deze specifieke configuratie zorgt ervoor dat de huidige gebruiker verbinding kan maken met de webserver in het tweede deel en de sudo-command kan gebruiken om bevoorrechte opdrachten uit te voeren. De tweede taks in de infrastructure role genereert een Terraform main.tf-bestand dat de configuratie specificeert die wordt gebruikt om de virtuele machine te deployen.

Kopiëren naar het Klembord

De derde taak in de infrastructure role maakt de webserver met de meegeleverde cloud-init configuratie. Het verwacht ook twee variabelen, domain en installation image. Je kunt die op de command line specificeren of op de voorkeursmanier, in de group_vars of host_vars. Ik heb ‘example.com’ gebruikt als domein en ‘Rocky-9-GenericCloud-Base.latest.x86_64.qcow2’ als installation_image.
De laatste twee taken in de infrastructuurrol maken de inventory file in het geheugen aan en wachten tot de webserver bereikbaar is via SSH.

Ansible webserver rol

De rol om de webserver te installeren is erg eenvoudig, installeer gewoon de NGINX-webserver en start de service. In een real-world scenario zal deze rol alle specifieke details bevatten om de webapplicatie op te zetten.

roles/webserver/task/main.yml

Kopiëren naar het Klembord

Het uiteindelijke resultaat

Als je het playbook uitvoert, krijg je de volgende output te zien. De output laat duidelijk de twee aparte Ansible plays zien en dat de eerste play wordt uitgevoerd op “localhost” en de tweede play wordt uitgevoerd op “webserver”.
Aangezien zowel Ansible als Terraform idempotent zijn, wordt bij een tweede uitvoering de virtuele machine niet opnieuw aangemaakt, maar wordt alleen de status gecontroleerd. Als de status in orde is, worden de gegevens van de draaiende machine verzameld zonder deze aan te raken. Op deze manier is het volledig veilig om de configuratie van de webserver aan te passen en gewoon het volledige playbook opnieuw uit te voeren.

Kopiëren naar het Klembord

Conclusie over Terraform integratie met Ansible

In deze blog hebben we laten zien dat het combineren van Terraform met Ansible mogelijk is. Dit is ‘een manier’ om het te doen en kan goed passen bij jouw bedrijf. Hier hebben we alleen een eenvoudige configuratie laten zien, maar meer complexe opstellingen met bijvoorbeeld meerdere webservers achter een load balancer, waarbij de load balancer automatisch geconfigureerd wordt met de nieuw gecreëerde machine, of een identity management cluster, zijn allemaal mogelijk. Ook met NGINX helpen we graag op weg.

Wil je praten over de mogelijkheden, neem dan contact met ons op!

Contact Ons