Terraform-Funktionen, Ausdrücke und Metaargumente verstehen - AWS Präskriptive Leitlinien

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Terraform-Funktionen, Ausdrücke und Metaargumente verstehen

Ein Kritikpunkt an IaC-Tools, die deklarative Konfigurationsdateien anstelle gängiger Programmiersprachen verwenden, ist, dass sie die Implementierung benutzerdefinierter Programmlogik erschweren. In Terraform-Konfigurationen wird dieses Problem durch die Verwendung von Funktionen, Ausdrücken und Metaargumenten behoben.

Funktionen

Einer der großen Vorteile der Verwendung von Code zur Bereitstellung Ihrer Infrastruktur ist die Möglichkeit, gängige Workflows zu speichern und immer wieder zu verwenden, wobei oft jedes Mal andere Argumente übergeben werden. Terraform-Funktionen ähneln AWS CloudFormation systeminternen Funktionen, obwohl ihre Syntax eher der Art und Weise ähnelt, wie Funktionen in Programmiersprachen aufgerufen werden. Möglicherweise sind Ihnen in den Beispielen in diesem Handbuch bereits einige Terraform-Funktionen wie substr, concat, length und base64decode aufgefallen. Wie CloudFormation bei intrinsischen Funktionen verfügt Terraform über eine Reihe integrierter Funktionen, die in Ihren Konfigurationen verwendet werden können. Wenn ein bestimmtes Ressourcenattribut beispielsweise ein sehr großes JSON-Objekt benötigt, dessen direktes Einfügen in die Datei ineffizient wäre, könnten Sie das Objekt in eine JSON-Datei einfügen und Terraform-Funktionen verwenden, um darauf zuzugreifen. Im folgenden Beispiel gibt die file Funktion den Inhalt der Datei in Zeichenfolgenform zurück und konvertiert ihn dann in einen Objekttyp. jsondecode

resource "example_resource" "example_resource_name" { json_object = jsondecode(file("/path/to/file.json")) }

Ausdrücke

Terraform ermöglicht auch bedingte Ausdrücke, die CloudFormation condition Funktionen ähneln, außer dass sie die traditionellere ternäre Operatorsyntax verwenden. Im folgenden Beispiel geben die beiden Ausdrücke genau dasselbe Ergebnis zurück. Das zweite Beispiel nennt Terraform einen Splat-Ausdruck. Das Sternchen veranlasst Terraform, die Liste in einer Schleife zu durchlaufen und eine neue Liste zu erstellen, indem nur die Eigenschaft jedes Elements verwendet wird. id

resource "example_resource" "example_resource_name" { boolean_value = var.value ? true : false numeric_value = var.value > 0 ? 1 : 0 string_value = var.value == "change_me" ? "New value" : var.value string_value_2 = var.value != "change_me" ? var.value : "New value" } There are two ways to express for loops in a Terraform configuration: resource "example_resource" "example_resource_name" { list_value = [for object in var.ids : object.id] list_value_2 = var.ids[*].id }

Meta-Argumente

Im vorherigen Codebeispiel list_value_2 werden sie als Argumente bezeichnet. list_value Möglicherweise sind Ihnen einige dieser Metaargumente bereits bekannt. Terraform hat auch einige Metaargumente, die sich wie Argumente verhalten, aber mit einigen zusätzlichen Funktionen:

Andere Metaargumente ermöglichen das direkte Hinzufügen von Funktions- und Ausdrucksfunktionen zu einer Ressource. Das Metaargument count ist beispielsweise ein nützlicher Mechanismus, um mehrere ähnliche Ressourcen gleichzeitig zu erstellen. Das folgende Beispiel zeigt, wie Sie zwei Amazon Elastic Container Service (Amazon EKS) -Cluster erstellen, ohne das count Metaargument zu verwenden.

resource "aws_eks_cluster" "example_0" { name = "example_0" role_arn = aws_iam_role.cluster_role.arn vpc_config { endpoint_private_access = true endpoint_public_access = true subnet_ids = var.subnet_ids[0] } } resource "aws_eks_cluster" "example_1" { name = "example_1" role_arn = aws_iam_role.cluster_role.arn vpc_config { endpoint_private_access = true endpoint_public_access = true subnet_ids = var.subnet_ids[1] } }

Das folgende Beispiel zeigt, wie das count Metaargument verwendet wird, um zwei Amazon EKS-Cluster zu erstellen.

resource "aws_eks_cluster" "clusters" { count = 2 name = "cluster_${count.index}" role_arn = aws_iam_role.cluster_role.arn vpc_config { endpoint_private_access = true endpoint_public_access = true subnet_ids = var.subnet_ids[count.index] } }

Um jeder Einheit einen Namen zu geben, können Sie auf den Listenindex innerhalb des Ressourcenblocks unter zugreifen. count.index Was aber, wenn Sie mehrere ähnliche Ressourcen erstellen möchten, die etwas komplexer sind? Hier kommt das Meta-Argument for_each ins Spiel. Das for_each Meta-Argument ist sehr ähnlichcount, außer dass Sie anstelle einer Zahl eine Liste oder ein Objekt übergeben. Terraform erstellt für jedes Mitglied der Liste oder des Objekts eine neue Ressource. Es ist ähnlich wie wenn Sie festlegencount = length(list), außer dass Sie auf den Inhalt der Liste und nicht auf den Schleifenindex zugreifen können.

Dies funktioniert sowohl für eine Liste von Elementen als auch für ein einzelnes Objekt. Im folgenden Beispiel würden zwei Ressourcen mit id-0 und id-1 als IDs erstellt.

variable "ids" { default = [ { id = "id-0" }, { id = "id-1" }, ] } resource "example_resource" "example_resource_name" { # If your list fails, you might have to call "toset" on it to convert it to a set for_each = toset(var.ids) id = each.value }

Im folgenden Beispiel würden ebenfalls zwei Ressourcen erstellt, eine für Sparky, den Pudel, und eine für Fluffy, den Chihuahua.

variable "dogs" { default = { poodle = "Sparky" chihuahua = "Fluffy" } } resource "example_resource" "example_resource_name" { for_each = var.dogs breed = each.key name = each.value }

So wie Sie mithilfe von count.index auf den Loop-Index in count zugreifen können, können Sie mithilfe des Each-Objekts auf den Schlüssel und den Wert jedes Elements in einer for_each-Schleife zugreifen. Da for_each sowohl über Listen als auch über Objekte iteriert, kann es etwas verwirrend sein, den Überblick über die einzelnen Schlüssel und Werte zu behalten. Die folgende Tabelle zeigt die verschiedenen Möglichkeiten, wie Sie das for_each-Metaargument verwenden können und wie Sie bei jeder Iteration auf die Werte verweisen können.

Beispiel for_each-Typ Erste Iteration Zweite Iteration
A
[“poodle”, “chihuahua”]
each.key = "poodle" each.value = null
each.key = "chihuahua" each.value = null
B
[ { type = "poodle", name = "Sparky" }, { type = "chihuahua", name = "Fluffy" } ]
each.key = { type = “poodle”, name = “Sparky” } each.value = null
each.key = { type = “chihuahua”, name = “Fluffy” } each.value = null
C
{ poodle = “Sparky”, chihuahua = “Fluffy” }
each.key = “poodle” each.value = “Sparky”
each.key = “chihuahua” each.value = “Fluffy”
D
{ dogs = { poodle = “Sparky”, chihuahua = “Fluffy” }, cats = { persian = “Felix”, burmese = “Morris” } }
each.key = “dogs” each.value = { poodle = “Sparky”, chihuahua = “Fluffy” }
each.key = “cats” each.value = { persian = “Felix”, burmese = “Morris” }
E
{ dogs = [ { type = “poodle”, name = “Sparky” }, { type = “chihuahua”, name = “Fluffy” } ], cats = [ { type = “persian”, name = “Felix” }, { type = “burmese”, name = “Morris” } ] }
each.key = “dogs” each.value = [ { type = “poodle”, name = “Sparky” }, { type = “chihuahua”, name = “Fluffy” } ]
each.key = “cats” each.value = [ { type = “persian”, name = “Felix” }, { type = “burmese”, name = “Morris” } ]

 

Wenn var.animals also Zeile E entspricht, könnten Sie mit dem folgenden Code eine Ressource pro Tier erstellen.

resource "example_resource" "example_resource_name" { for_each = var.animals type = each.key breeds = each.value[*].type names = each.value[*].name }

Alternativ könnten Sie zwei Ressourcen pro Tier erstellen, indem Sie den folgenden Code verwenden.

resource "example_resource" "example_resource_name" { for_each = var.animals.dogs type = "dogs" breeds = each.value.type names = each.value.name } resource "example_resource" "example_resource_name" { for_each = var.animals.cats type = "cats" breeds = each.value.type names = each.value.name }