

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Memahami fungsi, ekspresi, dan meta-argumen Terraform
<a name="functions-expressions"></a>

Salah satu kritik terhadap alat IAC yang menggunakan file konfigurasi deklaratif daripada bahasa pemrograman umum adalah bahwa mereka membuatnya lebih sulit untuk mengimplementasikan logika programatik khusus. Dalam konfigurasi Terraform, masalah ini diatasi dengan menggunakan fungsi, ekspresi, dan meta-argumen.

## Fungsi
<a name="functions"></a>

Salah satu keuntungan besar menggunakan kode untuk menyediakan infrastruktur Anda adalah kemampuan untuk menyimpan alur kerja umum dan menggunakannya kembali dan lagi, sering kali melewati argumen yang berbeda setiap kali. Fungsi Terraform mirip dengan fungsi AWS CloudFormation [intrinsik](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html), meskipun sintaksnya lebih mirip dengan bagaimana fungsi dipanggil dalam bahasa terprogram. Anda mungkin telah memperhatikan beberapa fungsi Terraform, seperti seperti [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), dan [base64decode](https://developer.hashicorp.com/terraform/language/functions/base64decode), dalam contoh dalam panduan ini. CloudFormation Seperti fungsi intrinsik, Terraform memiliki serangkaian [fungsi bawaan](https://developer.hashicorp.com/terraform/language/functions) yang tersedia untuk digunakan dalam konfigurasi Anda. Misalnya, jika atribut sumber daya tertentu mengambil objek JSON yang sangat besar yang tidak efisien untuk ditempelkan langsung ke file, Anda dapat meletakkan objek tersebut dalam **file.json** dan menggunakan fungsi Terraform untuk mengaksesnya. Dalam contoh berikut, `file` fungsi mengembalikan isi file dalam bentuk string, dan kemudian `jsondecode` fungsi mengubahnya menjadi tipe objek.

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

## Ekspresi
<a name="expressions"></a>

Terraform juga memungkinkan [ekspresi bersyarat](https://developer.hashicorp.com/terraform/language/expressions/conditionals), yang mirip dengan CloudFormation `condition` fungsi kecuali bahwa mereka menggunakan sintaks operator [ternary](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_operator) yang lebih tradisional. Dalam contoh berikut, kedua ekspresi mengembalikan hasil yang sama persis. Contoh kedua adalah apa yang disebut Terraform sebagai ekspresi [percikan](https://developer.hashicorp.com/terraform/language/expressions/splat). Tanda bintang menyebabkan Terraform mengulang daftar dan membuat daftar baru hanya dengan menggunakan `id` properti setiap item.

```
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-argumen
<a name="meta-arguments"></a>

Dalam contoh kode sebelumnya, `list_value` dan `list_value_2` disebut sebagai *argumen*. Anda mungkin sudah akrab dengan beberapa meta-argumen ini. Terraform juga memiliki beberapa *meta-argumen, yang bertindak seperti argumen* tetapi dengan beberapa fungsionalitas tambahan:
+ [Meta-argument [depends\$1on](https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on) sangat mirip dengan atribut. CloudFormation DependsOn](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html)
+ Meta-argument [penyedia](https://developer.hashicorp.com/terraform/language/meta-arguments#provider) memungkinkan Anda menggunakan beberapa konfigurasi penyedia sekaligus.
+ [Meta-argumen [siklus hidup](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) memungkinkan Anda untuk menyesuaikan setelan sumber daya, mirip dengan kebijakan [penghapusan dan penghapusan](https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk/RemovalPolicy.html) di.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) CloudFormation

Meta-argumen lain memungkinkan fungsi dan ekspresi fungsionalitas ditambahkan langsung ke sumber daya. Misalnya, [hitungan](https://developer.hashicorp.com/terraform/language/meta-arguments/count) meta-argumen adalah mekanisme yang berguna untuk membuat beberapa sumber daya serupa pada saat yang bersamaan. Contoh berikut menunjukkan cara membuat dua cluster Amazon Elastic Container Service (Amazon EKS) tanpa menggunakan `count` meta-argumen.

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

Contoh berikut menunjukkan cara menggunakan `count` meta-argumen untuk membuat dua cluster Amazon EKS.

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

Untuk memberikan masing-masing nama unit, Anda dapat mengakses indeks daftar dalam blok sumber daya di`count.index`. Tetapi bagaimana jika Anda ingin membuat beberapa sumber daya serupa yang sedikit lebih kompleks? Di situlah [meta-argumen for\$1each](https://developer.hashicorp.com/terraform/language/meta-arguments/for_each) masuk. `for_each`Meta-argumen sangat mirip dengan`count`, kecuali bahwa Anda meneruskan daftar atau objek bukan angka. Terraform membuat sumber daya baru untuk setiap anggota daftar atau objek. Ini mirip dengan jika Anda mengatur`count = length(list)`, kecuali Anda dapat mengakses isi daftar daripada indeks loop.

Ini berfungsi untuk daftar item atau objek tunggal. Contoh berikut akan menciptakan dua sumber daya yang memiliki `id-0` dan `id-1` sebagai milik mereka 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
}
```

Contoh berikut akan menciptakan dua sumber daya juga, satu untuk Sparky, pudel, dan satu untuk Fluffy, chihuahua.

```
variable "dogs" {
  default = {
    poodle    = "Sparky"
    chihuahua = "Fluffy"
  }
}

resource "example_resource" "example_resource_name" {
  for_each = var.dogs
  breed    = each.key
  name     = each.value
}
```

Sama seperti Anda dapat mengakses indeks loop dalam hitungan dengan menggunakan count.index, Anda dapat mengakses kunci dan nilai setiap item dalam loop for\$1each dengan menggunakan setiap objek. Karena for\$1each mengulangi daftar dan objek, setiap kunci dan nilai bisa sedikit membingungkan untuk dilacak. Tabel berikut menunjukkan berbagai cara yang dapat Anda gunakan meta-argumen for\$1each dan bagaimana Anda dapat mereferensikan nilai pada setiap iterasi.


****  

| Contoh | `for_each`jenis | Iterasi pertama | Iterasi kedua | 
| --- | --- | --- | --- | 
| 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> | 

 

Jadi jika `var.animals` sama dengan baris E, maka Anda bisa membuat satu sumber daya per hewan dengan menggunakan kode berikut.

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

Atau, Anda dapat membuat dua sumber daya per hewan dengan menggunakan kode berikut.

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