lesson ── terraform-beginner ── ~10 мин ── 4 шагов
In the last lesson the bucket name was hardcoded into the HCL. That is bad:
you have to edit the code for every environment. Now you will move the name
into a variable and teach Terraform to read the value from the CLI or from
a file.
Variables. This is the main mechanism that lets one HCL run in dev, staging, and prod. See tf-variable and tf-variable-sources.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
The ~/tf-vars directory already has a provider.tf. Create a
variables.tf file next to it with one variable:
variable "env" {type = string
description = "Environment: dev, staging, or prod"
default = "dev"
}
type = string. Terraform checks that the value you pass is really a
string. default = "dev", if no value is set anywhere, this one is used.
More about the variable block, tf-variable.
The `variables.tf` file: this is a convention, you could put everything in one `main.tf`. But splitting it makes reading easier.
✓ The variable is declared. Now use it in a resource.
Create a main.tf file with a bucket whose name depends on var.env:
resource "aws_s3_bucket" "demo" { bucket = "linuxlab-${var.env}-${random_id.suffix.hex}" tags = {Environment = var.env
ManagedBy = "terraform"
}
}
resource "random_id" "suffix" {byte_length = 4
}
The var. prefix is required, that is the syntax for referring to a
variable. Inside a string you need ${...} for interpolation, in a plain
argument, just var.env. See tf-references and tf-interpolation.
`${var.env}` inside a string, `var.env` in a plain argument such as `Environment = var.env`.
✓ var.env will be substituted into the name and tags.
Run:
cd /home/student/tf-vars
terraform init
terraform plan
Since env is not set from the outside, Terraform takes default = "dev".
In the plan the bucket name should start with linuxlab-dev-.
If init fails: check that `provider.tf` has no stray edits.
✓ The default was used, the bucket name contains 'dev'.
OpenTofu keeps its CLI and state compatible with Terraform for the
commands in this step: migration usually goes through mv .terraform .terraform.bak; tofu init -upgrade. But on the first switch, make a
state backup and run it on a feature branch, the differences cluster in
the newer features (variables in the backend, state encryption,
OCI registry-backed modules). See tf-opentofu-parity for the full
matrix.
Now apply the configuration with the prod environment. You can do it
three ways; try -var:
terraform apply -auto-approve -var='env=prod'
The created bucket name will start with linuxlab-prod-. This overrides
the default and gives you a completely different deployment without
editing the HCL.
The quotes around env=prod: required for the shell, otherwise it swallows the = sign.
✓ In state: a bucket with the tag Environment=prod. Variables work.
Terraform reads values from six places. If a value is set in several, the one closest to the CLI wins:
You moved the bucket name into a variable, saw four ways to supply a
value (CLI, env, .tfvars, default), and learned their precedence.
команды
terraform plan -var='env=prod'value through the CLITF_VAR_env=prod terraform planvalue through envterraform plan -var-file=prod.tfvarsvalue from a fileконцепции