linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/lessons/tf-beginner-02-variables

lesson ── terraform-beginner ── ~10 мин ── 4 шагов

Variables: removing the hardcode

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 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Declare the env variable

    The ~/tf-vars directory already has a provider.tf. Create a variables.tf file next to it with one variable:

    hcl
    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.

  2. 02

    Use the variable in the bucket name

    Create a main.tf file with a bucket whose name depends on var.env:

    hcl
    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.

  3. 03

    init and plan with the default value

    Run:

    bash
    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'.

    The same thing on OpenTofu

    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.

    • → OpenTofu parity
  4. 04

    Apply with a different value through -var

    Now apply the configuration with the prod environment. You can do it three ways; try -var:

    bash
    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.

    Source precedence

    Terraform reads values from six places. If a value is set in several, the one closest to the CLI wins:

    1. -var on the CLI (highest precedence)
    2. -var-file on the CLI
    3. *.auto.tfvars (alphabetical)
    4. terraform.tfvars
    5. env TF_VAR_*
    6. default in the variable block (lowest)
    • → Variable value sources
    • → .tfvars files

Что ты узнал

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 CLI
  • TF_VAR_env=prod terraform planvalue through env
  • terraform plan -var-file=prod.tfvarsvalue from a file

концепции

  • · variable: input, output: output, locals: internal
  • · Precedence: -var > -var-file > *.auto.tfvars > terraform.tfvars > env > default
  • · default is needed only when the value is optional

← предыдущий

CDKTF, Terraform from TypeScript

следующий →

Troubleshooting Garden: state and the cloud have drifted apart

Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies