Terraform Infrastructure as Code: Umgang mit Änderungen von außen

Terraform Infrastructure as Code: Umgang mit Änderungen von außen

Du willst Deine Infrastruktur mit Terraform verwalten, aber dann passiert es doch, dass Änderungen manuell gemacht wurden – und Du eine Lösung dafür finden musst. Der Umgang damit unterscheidet sich von Fall zu Fall.

Es ist eine große Stärke von Terraform, dass es mit Änderungen außerhalb der von ihm verwalteten Ressourcen umgehen kann. Die Stichworte sind: data, import, removed, ignore_changes, lock, variables.

Table of Contents

Ausgangssituation

Wir wollen unsere gesamte Infrastruktur in der Cloud automatisiert bereitstellen, und zwar mit Terraform. Die Herausforderung kann sein, dass plötzlich Änderungen auftauchen, die manuell oder durch externe Tools verursacht wurden.

Ein weiterer Fall wäre, dass die Infrastruktur ursprünglich anders aufgebaut wurde und nun auf Terraform umgestellt werden soll. Wie gehe ich nun am besten mit den Ressourcen um, die außerhalb von Terraform erstellt wurden? Das ist tatsächlich von Fall zu Fall unterschiedlich, und wir zeigen Dir, wie.

Manuelle Veränderungen und Terraform

Terraform ist so gebaut, dass es mit anderen Methoden zur Erstellung und Pflege von Infrastruktur koexistieren kann. Nicht nur das, sondern Terraform hat auch Konzepte zur Integration von externen Ressourcen. Andere Tools, wie beispielsweise Bicep oder Templates, haben das nicht.

Dieser Beitrag setzt ein Grundverständnis von Terraform voraus. Vor allem des „State“. Hier wird er von Hashicorp beschrieben als „Mapping to the real World“. Unsere Autorin stellt ihn sich als digitalen Zwilling vor.

Was kannst Du also tun, wenn ein Bezug zu einer externen Ressource hergestellt werden muss? Oder wenn etwas unter Terraform-Kontrolle gebracht, also in den State geholt werden soll? Oder herausgenommen? Oder wenn es eine einzelne Eigenschaft gibt, die von anderen Tools modifiziert wird?

Das klären wir in unserem Beitrag. Indem wir annehmen, dass manuelle Änderungen vorgenommen wurden. Die Ressourcen können aber ebenso gut von Terraform-Code mit anderem State, von anderen Tools oder einer Policy angelegt oder geändert worden sein.

Diagramm zu HashiCorp Terraform mit Elementen wie Key Vault, Resource Groups, Tags, Policy, Subnet, VM (Classic) und Worker Container App. Markierungen zeigen Aktionen wie change, ignore_changes, do not delete, removed und import.

Manuell angelegte Ressourcen referenzieren

Szenario:
Eine Ressource wurde im Portal erstellt.

Problem:
Wir wollen von Terraform aus darauf Bezug nehmen. In unserem Beispiel ist es ein Key Vault. Der Key Vault selbst soll nicht von Terraform verwaltet werden, aber Terraform muss auf ein Secret darin zugreifen.

Lösung 1:
Den Key Vault (eventuell auch das Secret) als „data source“ in Terraform bekanntgeben.

In data.tf:

data "azurerm_key_vault" "kv-manuell" {
  name                = "kv-ist-und-bleibt-manuell"
  resource_group_name = "rg"
}

data "azurerm_key_vault_secret" "dbpw" {
  name         = "database-password"
  key_vault_id = data.azurerm_key_vault.kv-manuell.id
}

In maint.tf:

      secrets = {
        "db-pw" = {
          value = data.azurerm_key_vault_secret.dbpw.value
        }

Lösung 2:
Als Variable in Terraform bekanntmachen.

In .tfvars - File:

shared_keyvault_id                      = "/subscriptions/xxx/resourceGroups/yyy/providers/Microsoft.KeyVault/vaults/zzz"

In main.tf:

resource "azurerm_role_assignment" "kv_app_reader" {
  scope                = var.shared_keyvault_id
  role_definition_name = "Key Vault Secrets User"
  principal_id         = xxx.yyy.principal_id
}

Manuelle Veränderungen integrieren

Szenario:
In einer gemeinsamen Debugging-Session wurde im Cloudportal eine von Terraform verwaltete Ressource verändert.

Problem:
Die Änderung würde vom nächsten Terraformlauf rückgängig gemacht werden.

Lösung:
Nur „terraform plan“ laufen lassen und die angezeigten Änderungen in den Code übernehmen, bis keine Änderung mehr geplant wird.

Manuell angelegte Ressourcen integrieren

Szenario:
In einer gemeinsamen Debugging-Session wurde im Cloudportal eine Ressource angelegt.

Problem:
Die Ressource wird von Terraform ignoriert. Sie kann nicht geändert oder referenziert werden. Aber sie soll ab jetzt von Terraform verwaltet werden.

Lösung 1:
Die Ressource wird mit einem Imports-Block importiert.

Anmerkung:
Wir haben manchmal das Problem, dass Terraform die IDs nicht findet

In imports.tf:

import {
  to = azurerm_subnet.pgsql
  id = "/subscriptions/xxx/resourceGroups/yyy/providers/Microsoft.Network/virtualNetworks/zzz/subnets/aaa"
}

In main.tf:

resource "azurerm_subnet" "pgsql" {
  # If desired, you can leave the body of the resource block blank for now 
  # and return to fill it in once the instance is imported.
}

Lösung 2:
Die Ressource wird in Terraform nachmodelliert wie in „Manuelle Veränderungen integrieren“.

Terraform soll die Änderung einzelner Eigenschaften einer Ressource ignorieren

Szenario:
Eine Policy erstellt automatisch Tags.

Problem:
Die Tags werden ständig hin- und zurückgeändert. Der Terraform-Plan zeigt diese Änderungen jedes Mal an und wird unübersichtlich.

Lösung:
lifecycle ignore_changes

Beispiel:

  lifecycle {
    ignore_changes = [tags,]
  }

Ressourcen aus der Verwaltung von Terraform herausnehmen

Szenario:
Wir wollen eine Ressource stehen lassen, damit ein Entwickler noch etwas nachschauen kann. Danach löscht er sie manuell.

Problem:
Wenn wir sie aus dem Terraform-Code herausnehmen, wird sie sofort gelöscht.

Lösung:
Die Ressource ganz aus der Terraform-Verwaltung herausnehmen. Den Befehl „terraform state rm“ gibt es schon länger. Seit Version 1.7 gibt es den „removed“ block.

Anmerkung:
Bei mir hat der removed block funktioniert, der Befehl nicht.

Beispiel:

removed {
  from = module.containerapp.azurerm_container_app.container_app

  lifecycle {
    destroy = false
  }
}

Manuelle Arbeit vor Terraform schützen

Szenario:
Einem Team wurde mit Terraform eine VM erstellt, auf der sie etwas manuell installieren.

Problem:
Terraform könnte die VM neu anlegen und damit die manuelle Arbeit zerstören.

Lösung 1:
Die Ressource sperren, also ein Änderungs- oder Lösch-Lock im Portal setzen.

Lösung 2:
Removed-Block wie in „Ressourcen aus der Verwaltung von Terraform herausnehmen“.

Lösung 3:
Bei manchen Ressourcen kann „soft delete“ eingestellt werden. Aber Vorsicht: Die Gefahr dabei ist, dass die Löschung so lange unbemerkt bleibt, bis die Ressource endgültig gelöscht wird. Oft ist außerdem „soft delete“ bei Terraform auf „disabled“ konfiguriert. Es verträgt sich schlecht mit der Philosophie von Infrastruktur as Code, nach der alles immer wieder abgerissen und neu aufgebaut werden kann.

Fazit

Wir können Terraform neben anderen Tools einsetzen. Dadurch ist es auch möglich, ein anderes System nach und nach durch Terraform zu ersetzen. Das ist ein schönes Beispiel für das Strangler-Fig-Pattern von Martin Fowler.

Die von uns vorgestellte Lösung funktioniert in der Regel sehr gut, sie kann jedoch von Fall zu Fall auch sehr komplex werden und viel Sorgfalt und Geduld erfordern.

Ist es nicht faszinierend, dass ausgerechnet das Tool, das andere Möglichkeiten zulässt, heute klar dominiert?

Falls Du ein ähnliches Thema hast oder einfach einen Sparring-Partner für Deine Infrastruktur suchst, melde Dich gern bei uns. Unsere DevOps-Profis freuen sich auf Deine Herausforderung!

Du hast Fragen? Kontaktiere uns

Arne Kaiser

Your contact person

Arne Kaiser

Domain Lead Cloud Transformation & Data Infrastructure

Florian Stein

Your contact person

Florian Stein

Domain Lead Cloud Transformation & Data Infrastructure

Ähnliche Beiträge

chevron left icon
Vorheriger Beitrag
Nächster Beitrag
chevron right icon

Kein vorheriger Beitrag

Kein nächster Beitrag