

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
<a name="functions-expressions"></a>

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
<a name="functions"></a>

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](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html), 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](https://developer.hashicorp.com/terraform/language/functions/substr), [concat](https://developer.hashicorp.com/terraform/language/functions/concat), [length](https://developer.hashicorp.com/terraform/language/functions/length) und base64decode aufgefallen.](https://developer.hashicorp.com/terraform/language/functions/base64decode) [Wie CloudFormation bei intrinsischen Funktionen verfügt Terraform über eine Reihe integrierter Funktionen, die in Ihren Konfigurationen verwendet werden können.](https://developer.hashicorp.com/terraform/language/functions) 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
<a name="expressions"></a>

Terraform ermöglicht auch [bedingte Ausdrücke](https://developer.hashicorp.com/terraform/language/expressions/conditionals), die CloudFormation `condition` Funktionen ähneln, außer dass sie die traditionellere [ternäre](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_operator) Operatorsyntax verwenden. Im folgenden Beispiel geben die beiden Ausdrücke genau dasselbe Ergebnis zurück. Das zweite Beispiel nennt Terraform einen [Splat-Ausdruck](https://developer.hashicorp.com/terraform/language/expressions/splat). 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
<a name="meta-arguments"></a>

*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:
+ [Das [meta-Argument depends\_on](https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on) ist dem Attribut sehr ähnlich. CloudFormation DependsOn](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html)
+ Das [Provider-Metaargument](https://developer.hashicorp.com/terraform/language/meta-arguments#provider) ermöglicht es Ihnen, mehrere Anbieterkonfigurationen gleichzeitig zu verwenden.
+ [Mit dem [Lifecycle-Metaargument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) können Sie Ressourceneinstellungen anpassen, ähnlich den Richtlinien zum [Entfernen und Löschen von](https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk/RemovalPolicy.html).](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) CloudFormation

Andere Metaargumente ermöglichen das direkte Hinzufügen von Funktions- und Ausdrucksfunktionen zu einer Ressource. Das Metaargument [count](https://developer.hashicorp.com/terraform/language/meta-arguments/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](https://developer.hashicorp.com/terraform/language/meta-arguments/for_each) ins Spiel. Das `for_each` Meta-Argument ist sehr ähnlich`count`, 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 festlegen`count = 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. Das folgende Beispiel würde zwei Ressourcen erstellen, die über `id-0` und `id-1` als ihre verfügen IDs.

```
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 | <pre>["poodle", "chihuahua"]</pre> | <pre>each.key = "poodle"<br /><br />each.value = null</pre> | <pre>each.key = "chihuahua"<br /><br />each.value = null</pre> | 
| B | <pre>[<br /><br />{<br /><br />type = "poodle",<br /><br />name = "Sparky"<br /><br />},<br /><br />{<br /><br />type = "chihuahua",<br /><br />name = "Fluffy"<br /><br />}<br /><br />]</pre> | <pre>each.key = {<br /><br />type = "poodle",<br /><br />name = "Sparky"<br /><br />}<br /><br />each.value = null</pre> | <pre>each.key = {<br /><br />type = "chihuahua",<br /><br />name = "Fluffy"<br /><br />}<br /><br />each.value = null</pre> | 
| C | <pre>{<br /><br />poodle = "Sparky",<br /><br />chihuahua = "Fluffy"<br /><br />}</pre> | <pre>each.key = "poodle"<br /><br />each.value = "Sparky"</pre> | <pre>each.key = "chihuahua"<br /><br />each.value = "Fluffy"</pre> | 
| D | <pre>{<br /><br />dogs = {<br /><br />poodle = "Sparky",<br /><br />chihuahua = "Fluffy"<br /><br />},<br /><br />cats = {<br /><br />persian = "Felix",<br /><br />burmese = "Morris"<br /><br />}<br /><br />}</pre> | <pre>each.key = "dogs"<br /><br />each.value = {<br /><br />poodle = "Sparky",<br /><br />chihuahua = "Fluffy"<br /><br />}</pre> | <pre>each.key = "cats"<br /><br />each.value = {<br /><br />persian = "Felix",<br /><br />burmese = "Morris"<br /><br />}</pre> | 
| E | <pre>{<br /><br />dogs = [<br /><br />{<br /><br />type = "poodle",<br /><br />name = "Sparky"<br /><br />},<br /><br />{<br /><br />type = "chihuahua",<br /><br />name = "Fluffy"<br /><br />}<br /><br />],<br /><br />cats = [<br /><br />{<br /><br />type = "persian",<br /><br />name = "Felix"<br /><br />},<br /><br />{<br /><br />type = "burmese",<br /><br />name = "Morris"<br /><br />}<br /><br />]<br /><br />}</pre> | <pre>each.key = "dogs"<br /><br />each.value = [<br /><br />{<br /><br />type = "poodle",<br /><br />name = "Sparky"<br /><br />},<br /><br />{<br /><br />type = "chihuahua",<br /><br />name = "Fluffy"<br /><br />}<br /><br />]</pre> | <pre>each.key = "cats"<br /><br />each.value = [<br /><br />{<br /><br />type = "persian",<br /><br />name = "Felix"<br /><br />},<br /><br />{<br /><br />type = "burmese",<br /><br />name = "Morris"<br /><br />}<br /><br />]</pre> | 

 

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
}
```