HashiCorp hat mit Ihrem Produkt Terraform ein sehr mächtiges Werkzeug im Bereich Infrastructure as Code im Portfolio. Mit dessem Artikel möchte ich einen Einstieg bieten in die Nutzung eines der vielen Provider und zwar den VMware vCloud Director Provider for Terraform.
Terraform Installieren
Unter Windows muss lediglich die Terraform.exe in einen beliebigen Ordner gepackt werden und dieser der Umgebungsvariable Path hinzugefügt werden. Mehr Infos finden sich im Getting Started Guide.
Überprüfen der Installation
Zur Überprüfung der Installation kann nach dem Anpassen der Umgebungsvariablen einfach ein terraform Kommando in der CMD aufgerufen werden.
C:\>terraform Usage: terraform [--version] [--help] <command> [args] The available commands for execution are listed below. The most common, useful commands are shown first, followed by less common or more advanced commands. If you're just getting started with Terraform, stick with the common commands. For the other commands, please read the help and docs before usage. Common commands: apply Builds or changes infrastructure console Interactive console for Terraform interpolations destroy Destroy Terraform-managed infrastructure env Workspace management fmt Rewrites config files to canonical format get Download and install modules for the configuration graph Create a visual graph of Terraform resources import Import existing infrastructure into Terraform init Initialize a Terraform working directory output Read an output from a state file plan Generate and show an execution plan providers Prints a tree of the providers used in the configuration push Upload this Terraform module to Atlas to run refresh Update local state file against real resources show Inspect Terraform state or plan taint Manually mark a resource for recreation untaint Manually unmark a resource as tainted validate Validates the Terraform files version Prints the Terraform version workspace Workspace management All other commands: debug Debug output management (experimental) force-unlock Manually unlock the terraform state state Advanced state management
vCloud Director Provider for Terraform Basics
Ordnerstruktur
Ich habe für mich den Weg gefunden, für jedes Projekt bzw. für jede Applikation einen eigenen Unterordner innerhalb eines GitHub Repository anzulegen. Die Applikation ist in den Beispiel „Basics“.
<Repository Root> │ .gitignore │ README.md │ ├───Basics │ │ 00 Config.tf │ │ 01 Network.tf │ │ 02 vApp.tf │ │ 03 Firewall.tf │ │ terraform.tfstate │ │ terraform.tfstate.backup │ │ vcd.tfvars │ │ │ └───.terraform │ └───plugins │ └───windows_amd64 │ lock.json │ terraform-provider-vcd_v1.0.0_x4.exe │ └───Media terraform-vcd-logo.png
Wie man an dem Beispiel sehen kann erzeugt Terraform in dem Arbeitsverzeichnis des Projekts einige weitere Files und eines davon ist von besonderer Relevanz:
- terraform.tfstate (lokales State File)
- terraform.tfstate.backup
- .terraform
- plugins
- …
- plugins
Der Inhalt des State Files kann entweder mit terraform show aufgerufen werden oder einfach der Texteditor eingesehen werden.
Ich habe hier alleine an diesem kleinen Terraform Projekt gearbeitet, wenn jedoch später geplant wird im Team an einem Projekt zu arbeiten, sollte unbedingt über die Konfiguration eines Remote Backends nachgedacht werden. Damit kann dann der Terraform State zum Beispiel in einem AWS S3 Bucket abgelegt und das State Locking über eine AWS DynamoDB Table abgehandelt werden.
Falls das Projekt auch bei dir ein GitHub (oder ähnliches) Repository werden soll bei dem das State File lokal liegen, unbedingt auf eine sinnvolle .gitignore achten und niemals sensible Daten (Passwörter, etc.) direkt in die .tf Files schreiben!
# ========================= # App Files # ========================= # Terraform # ========================= # Local .terraform directories **/.terraform/* # .tfstate files *.tfstate *.tfstate.* # .tfvars files *.tfvars
Das es wirklich Sinn macht, seine Terraform Projekte in einer Versioncontrol (GIT, etc) zu verwalten sieht man an diesem kleinen Beispiel:
Initialisierung
Zur Basis-Initialisierung ist erst einmal nur die Provider Konfiguration notwendig. Diese lege ich in jedem Fall in ein separates .tf File.
Basis Provider Konfiguration:
# VMware vCloud Director Provider Variables (Blank) variable "vcd_user" { description = "vCD Tenant User" } variable "vcd_pass" { description = "vCD Tenant Password" } variable "vcd_org" { description = "vCD Tenant Org" } variable "vcd_url" { description = "vCD Tenant URL" } variable "vcd_vdc" { description = "vCD Tenant VDC" } variable "vcd_max_retry_timeout" { description = "Retry Timeout" default = "240" } # VMware vCloud Director Provider Configuration provider "vcd" { user = "${var.vcd_user}" password = "${var.vcd_pass}" org = "${var.vcd_org}" url = "${var.vcd_url}" vdc = "${var.vcd_vdc}" max_retry_timeout = "${var.vcd_max_retry_timeout}" }
Mit dieser Provider Konfiguration kann Terraform nun initialisiert werden und wenn nötig wird der VMware vCloud Director Provider installiert bzw. wird in dem aktuellen Arbeitsbereich bereitgestellt.
Nach der erfolgreichen Initialisierung mit der VMware vCloud Director Provider for Terraform Konfiguration, kann nun auch diese Version überprüft werden.
Planung und Validierung
In der aktuellen Konfiguration macht die Planung einer Änderung mir dem Kommando plan noch nicht viel Sinn, man kann jedoch sehr gut sein Variables File und die Verbindung zur Umgebung damit überprüfen.
*.tfvars File für die Provider Config:
vcd_user = "******" vcd_org = "******" vcd_vdc = "******" vcd_url = "https://******/api"
Mit dem Kommando validate kann alternativ (und unabhängig von der Verbindung) auch nur die Syntax der Files geprüft werden.
vCloud Director Provider for Terraform Provisioning
Simples Netzwerk und neue vApp anlegen
Um im VMware vCloud Director mit Terraform ein neues Organisationsnetzwerk und eine vApp aus einem Template zu erstellen sind zwei zusätzliche Ressourcen Konfigurationen notwendig, vcd_network und vcd_vapp. Um sicherzustellen, dass die Konfigurationen auch in der korrekten Reihenfolge abgearbeitet werden, habe ich eine Nummerierung zu den einzelnen Files hinzugefügt (die Übersicht beim plan und apply Kommando zeigt aber nicht umgedingt die korrekte Reihenfolge an).
Orderstruktur:
<Project Folder> │ 00 Config.tf │ 01 Network.tf │ 02 vApp.tf │ terraform.tfstate │ terraform.tfstate.backup │ vcd.tfvars │ └───.terraform └───plugins └───windows_amd64 lock.json terraform-provider-vcd_v1.0.0_x4.exe
Ressourcen Konfigurationen:
# VMware vCloud Director Network Variables (Blank) variable "vcd_edge" { description = "vCD Tenant Edge Gateway" } # VMware vCloud Director Network Resource Definition resource "vcd_network" "tf-net" { name = "my-tf-net" edge_gateway = "${var.vcd_edge}" gateway = "172.20.0.1" static_ip_pool { start_address = "172.20.0.100" end_address = "172.20.0.200" } }
# VMware vCloud Director vApp Variables (Blank) variable "vcd_catalog" { description = "vCD Catalog Name" } # VMware vCloud Director vApp Ressource Definition resource "vcd_vapp" "tf-vapp" { name = "tf-vapp" catalog_name = "${var.vcd_catalog}" template_name = "Ubuntu 16.04 LTS" memory = 2048 cpus = 1 network_name = "${vcd_network.tf-net.name}" }
In der Ressourcen Definition für die vApp ist auch zu sehen, wie auf vorab definierte Ressourcen referenziert werden kann (network_name = „${vcd_network.tf-net.name}“). Mit der neuen Konstellation macht es nun schon wesentlich mehr Sinn einen eine Planung durchzuführen.
Da das gewünschte Ergebnis simuliert wurde, kann die Konfiguration mit dem Kommando apply nun auch angewendet werden.
Nach erneuter Bestätigung werden die Änderungen durch den vCloud Director Provider for Terraform durchführt.
In-Place Update der vApp VM
Eine Änderung der vCPU Anzahl von vApp VMs ist zum Beispiel ein In-Place Update, was bedeutet die Ressource muss nicht neu bereitgestellt werden.
Weitere VMs zur vApp hinzufügen
Die neuen vApp Ressourcen Definition sieht nun zwei weitere VMs in der bestehenden vApp vor. Diese werden über die Ressource vcd_vapp_vm definiert und erhalten fixe IPs aus dem Bereich des static_ip_pool. Wird keine IP für die VM konfiguriert steht die Netzwerkkarte auf DHCP.
# VMware vCloud Director vApp Variables (Blank) variable "vcd_catalog" { description = "vCD Catalog Name" } # VMware vCloud Director vApp Ressource Definition resource "vcd_vapp" "tf-vapp" { name = "tf-vapp" catalog_name = "${var.vcd_catalog}" template_name = "Ubuntu 16.04 LTS" memory = 2048 cpus = 2 network_name = "${vcd_network.tf-net.name}" } resource "vcd_vapp_vm" "tf-vapp-add-1" { vapp_name = "${vcd_vapp.tf-vapp.name}" name = "tf-vapp-add-1" catalog_name = "${var.vcd_catalog}" template_name = "Ubuntu 16.04 LTS" memory = 2048 cpus = 1 ip = "172.20.0.100" } resource "vcd_vapp_vm" "tf-vapp-add-2" { vapp_name = "${vcd_vapp.tf-vapp.name}" name = "tf-vapp-add-2" catalog_name = "${var.vcd_catalog}" template_name = "Ubuntu 16.04 LTS" memory = 2048 cpus = 1 ip = "172.20.0.101" }
Die finale vApp sieht nun im VMware vCloud Director so aus:
Neue Firewall Regel hinzufügen
In einem weiteren Terraform File habe ich eine Firewall Ressourcen Definition festgelegt. Es sollen zwei Allow-Regeln für das neue Netz erzeugt werden. Falls bereits existierende Regeln vorhanden sind, werden diese nicht angefasst.
# VMware vCloud Director Firewall Ressource Definition resource "vcd_firewall_rules" "fw" { edge_gateway = "${var.vcd_edge}" default_action = "drop" rule { description = "allow-http" policy = "allow" protocol = "tcp" destination_port = "80" destination_ip = "any" source_port = "any" source_ip = "172.20.0.0/24" } rule { description = "allow-https" policy = "allow" protocol = "tcp" destination_port = "443" destination_ip = "any" source_port = "any" source_ip = "172.20.0.0/24" } }
Die Ressource vcd_firewall_rules kann ebenso wie in einem vorherigen Beispiel mit Übergabewerten aus anderen Ressourcen arbeiten. Dadurch ist wesentlich weniger Pflege von IPs bei komplexen Konstrukten in den Firewall Regelwerken notwendig.
Hier ein Beispiel für eine zusätzliche Regel:
# VMware vCloud Director Firewall Ressource Definition resource "vcd_firewall_rules" "fw" { edge_gateway = "${var.vcd_edge}" default_action = "drop" rule { description = "allow-http" policy = "allow" protocol = "tcp" destination_port = "80" destination_ip = "any" source_port = "any" source_ip = "172.20.0.0/24" } rule { description = "allow-https" policy = "allow" protocol = "tcp" destination_port = "443" destination_ip = "any" source_port = "any" source_ip = "172.20.0.0/24" } rule { description = "allow-ntp" policy = "allow" protocol = "udp" destination_port = "123" destination_ip = "any" source_port = "any" source_ip = "${vcd_vapp_vm.tf-vapp-add-1.ip}" } }
Ressourcen wieder löschen
Wichtiger Teil des Lebenszyklus der bereitgestellten Ressourcen ist natürlich auch das Löschen dieser, dafür kennt Terraform das Kommando destroy. Alle durch Terraform verwaltetet Ressourcen werden damit wieder in einer sinnvollen Reihenfolge gelöscht.
vCloud Director Provider for Terraform Fazit
Terraform ist in jedem Fall ein super nützliches Tool und der VMware vCloud Director Provider kann in der Version 1.0 auch bereits für viele Grundlegende Dinge verwendet werden. Dennoch hat speziell der Provider noch enorm Verbesserungspotential.
Ich kann daher um das Produkt weiter auszubauen nur alle Nutzer und Interessierten anhalten die Probleme und Verbesserungswünsche in dem GitHub Provider Repository als Issue einzukippen sowie sich in der Community einzubringen. Der Entwurf für den Plan für die Version 2 sieht auf jeden Fall schon vielversprechend aus.
vCloud Director Provider for Terraform Beispiele
Meine gesamten Beispiele habe ich in einem GitHub Repository zusammengefasst:
VMware-vCD-Terraform