Podczas pracy z Terraformem często pojawia się potrzeba tworzenia różnych zasobów w zależności od pewnych warunków – czasami jeden zasób, innym razem kilka, a niekiedy wcale. Terraform oferuje dwie funkcje, które pomagają to kontrolować: count
i for_each
. Można je zastosować na różne sposoby, w zależności od tego, co chcemy osiągnąć.
1. Użycie count
– prosty wybór: tworzyć zasób czy nie?
count
to narzędzie pozwalające decydować, ile instancji zasobu Terraform ma utworzyć. Gdy ustawisz count
na 0
, zasób nie zostanie utworzony. To podejście jest przydatne, gdy zależy Ci na tworzeniu zasobu w oparciu o jeden warunek.
Przykład: Tworzenie zasobów S3 z count
Załóżmy, że chcesz utworzyć bucket S3, tylko wtedy, gdy zmienna var.create_s3
ma wartość true
. Jeśli jest ustawiona na false
, bucket nie zostanie stworzony:
variable "create_s3" {
type = bool
default = true
}
resource "aws_s3_bucket" "example" {
count = var.create_s3 ? 1 : 0
bucket = "my-example-bucket"
acl = "private"
}
W tym przykładzie, jeśli var.create_s3
jest true
, Terraform utworzy jeden bucket. Gdy wartość zmiennej jest false
, Terraform pominie tworzenie zasobu.
2. Użycie for_each
– tworzenie wielu zasobów
Jeśli potrzebujesz utworzyć kilka zasobów w zależności od listy lub mapy danych, można skorzystać z for_each
. Umożliwia on tworzenie zasobów dla każdego elementu w kolekcji, dzięki czemu można dynamicznie kontrolować liczbę tworzonych zasobów.
Przykład: Tworzenie wielu bucketów S3 z for_each
Załóżmy, że chcesz utworzyć kilka bucketów S3, a ich liczba zależy od listy nazw zdefiniowanej w zmiennej. for_each
umożliwia tworzenie bucketów dla każdej nazwy w liście:
variable "bucket_names" {
type = list(string)
default = ["bucket1", "bucket2"]
}
resource "aws_s3_bucket" "example" {
for_each = toset(var.bucket_names)
bucket = each.value
acl = "private"
}
W tym przypadku Terraform utworzy bucket dla każdej nazwy na liście var.bucket_names
. Jeśli na liście znajdują się dwie nazwy, powstaną dwa buckety.
3. Tworzenie czasami kilku zasobów, a czasami żadnych
W sytuacjach, gdy czasem trzeba utworzyć kilka zasobów, a czasem żadnych, można połączyć for_each
z warunkiem logicznym. Gdy warunek nie jest spełniony, można przekazać pustą mapę do for_each
, co spowoduje, że Terraform nie utworzy żadnych zasobów.
Przykład1: Tworzenie bucketów S3 tylko, gdy warunek jest spełniony
Załóżmy, że chcesz tworzyć kilka bucketów S3 tylko wtedy, gdy zmienna var.create_s3
jest ustawiona na true
. Jeśli nie jest, Terraform nie powinien utworzyć żadnych bucketów:
variable "create_s3" {
type = bool
default = true
}
variable "bucket_names" {
type = list(string)
default = ["bucket1", "bucket2"]
}
resource "aws_s3_bucket" "example" {
for_each = var.create_s3 ? toset(var.bucket_names) : {}
bucket = each.value
acl = "private"
}
Jeśli var.create_s3
jest true
, Terraform utworzy buckety na podstawie listy var.bucket_names
. Jeśli warunek nie jest spełniony, for_each
otrzymuje pustą mapę, co powoduje, że Terraform nie tworzy żadnych bucketów.
Przykład2: Tworzenie bucketów S3 tylko, gdy lista nie jest pusta
variable "bucket_names" {
type = list(string)
default = ["bucket1", "bucket2"]
}
resource "aws_s3_bucket" "example" {
for_each = length(var.bucket_names) > 0 ? toset(var.bucket_names) : {}
bucket = each.value
acl = "private"
}
W tym przykładzie for_each
sprawdza, czy lista bucket_names
zawiera jakiekolwiek elementy. Jeśli lista ma przynajmniej jeden element, zasoby S3 będą tworzone dla każdego elementu z listy. Jeśli lista jest pusta, zasoby nie będą tworzone, ponieważ for_each
dostaje pustą mapę ({}
).
To podejście eliminuje potrzebę dodatkowej zmiennej warunkowej i opiera się wyłącznie na długości listy bucket_names
.
Standardowy Sposób
Oprócz technik pokazanych w tym artykule, count
można również używać w standardowy sposób do tworzenia wielu zasobów. Na przykład, możesz chcieć utworzyć kilka EC2, po prostu dodając zmienną, lub nawet tylko ustawiając wartość count
:
hclCopy coderesource "aws_instance" "example" {
count = 3
ami = "ami-123456"
instance_type = "t2.micro"
}
Ten przykład utworzy 3 instancje danego zasobu.
Przykłady podane w tym artykule pokazują bardziej zaawansowane przypadki, w których count
i for_each
mogą być stosowane warunkowo lub dynamicznie w zależności od potrzeb projektu. Terraform oferuje ogromne możliwości i szeroki wachlarz zastosowań. Warto dokładnie zapoznać się z dokumentacją, aby w pełni wykorzystać jego potencjał w różnych projektach. Więcej informacji można oczywicie znaleźć na oficjalnej strnie w Terraform documentation.
Podsumowanie
count
pozwala w prosty sposób decydować, czy zasób powinien zostać utworzony, opierając się na warunku logicznym.for_each
umożliwia tworzenie wielu zasobów na podstawie listy lub mapy danych.- Gdy potrzebujemy dynamicznie tworzyć kilka zasobów lub żadnych, połączenie
for_each
z warunkiem logicznym pozwala na elastyczną kontrolę nad tym procesem.
Oba podejścia można stosować w zależności od potrzeb projektu i tego, jak dynamicznie chcemy zarządzać infrastrukturą w chmurze. Przydatne, gdy tworzymy moduł, który ma być uniwersalny i elastyczny, dostosowując się do różnych potrzeb użytkowników.