> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding Variable Block

> Explains Terraform variable blocks, covering types, defaults, validation, sensitivity, and value sources to enforce input rules, document intent, and secure reusable infrastructure modules.

In this lesson we examine the Terraform `variable` block — a foundational building block for creating reusable, well‑documented, and robust infrastructure code. A clearly defined `variable` block becomes a contract: it documents intent, enforces rules, and improves reuse across teams and automation pipelines.

A minimal variable declaration looks like:

```hcl theme={null}
# ---- variables.tf ----
variable "resource_group_name" {
}
```

With no `type`, `default`, or other arguments, Terraform treats the variable as a required input. If a value is not supplied at runtime, Terraform will prompt for it and stop execution until a value is provided. This behavior prevents accidental deployments with missing configuration.

Key arguments supported by the `variable` block

* `default` — A fallback value. When present, the variable becomes optional.
* `type` — Enforces an expected type (for example `string`, `list(string)`, `object({...})`). Terraform performs type checking before planning or applying.
* `description` — Human‑readable documentation that appears in CLI prompts and module docs.
* `validation` — A nested block that allows arbitrary expressions to validate input values (naming standards, allowed values, lengths, etc.). Validation is evaluated during the planning phase.
* `sensitive` — When true, Terraform hides the value in CLI output and logs. Note that sensitive values may still be stored in the state file.
* `nullable` — Controls whether `null` is an allowed value.
* `ephemeral` — Not a Terraform core attribute. For short‑lived or run‑only secrets, prefer passing values via the CLI (`-var`), environment variables, a secrets manager, or using [Terraform Cloud/Enterprise](https://www.terraform.io/cloud) run‑only variables or other secret management integrations to avoid persisting secrets in state.

<Callout icon="lightbulb" color="#1CB2FE">
  Use `sensitive = true` together with secure state backends (for example, encrypted [remote state](https://www.terraform.io/language/state/remote)) when handling secrets. `sensitive` masks output but does not prevent values from being stored in state.
</Callout>

Arguments quick reference

| Argument      | Purpose                                                             | Example                                                                                         |
| ------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `type`        | Enforces the expected type; Terraform validates before plan/apply   | `string`, `list(string)`, `object({ internal = number, external = number, protocol = string })` |
| `default`     | Provides a fallback value — variable is optional when present       | `default = ["us-west-1"]`                                                                       |
| `description` | Human-readable text used in prompts and docs                        | `description = "Azure region to deploy the resources"`                                          |
| `validation`  | Nested block with `condition` and `error_message` to validate input | `validation { condition = contains(["eastus"], var.region) error_message = "..." }`             |
| `sensitive`   | Hides values in output and logs (state still may contain value)     | `sensitive = true`                                                                              |
| `nullable`    | Controls whether `null` is permitted                                | `nullable = true`                                                                               |

Example: enforce a naming convention and length

```hcl theme={null}
# ---- variables.tf ----
variable "resource_group_name" {
  description = "Name for the resource group"
  type        = string

  validation {
    condition = (
      substr(var.resource_group_name, 0, 3) == "rg-" &&
      length(var.resource_group_name) <= 20
    )
    error_message = "Value must start with 'rg-' and be at most 20 characters long."
  }
}
```

This `validation` block enforces:

1. The value must start with the prefix `rg-`.
2. The value must not exceed 20 characters.

If a provided value fails validation, Terraform halts at planning and returns a clear error. For example:

```bash theme={null}
terraform plan -var "resource_group_name=demo-rg"
```

Might produce:

```plaintext theme={null}
Planning failed. Terraform encountered an error while generating this plan.

Error: Invalid value for variable "resource_group_name"
var.resource_group_name is "demo-rg"
Value must start with 'rg-' and be at most 20 characters long.
This was checked by the validation rule in variables.tf.
```

Working with variables in an editor — common patterns
Below are concise examples demonstrating typical validations and common types.

1. Enforce non‑empty or minimum length for an `rg` variable:

```hcl theme={null}
variable "rg" {
  description = "Name of the resource group"
  type        = string

  validation {
    condition     = length(var.rg) > 10
    error_message = "The resource group name must be greater than 10 characters."
  }
}
```

2. Restrict `region` to an allowlist using `contains`:

```hcl theme={null}
variable "region" {
  description = "Azure region to deploy the resources"
  type        = string

  validation {
    condition     = contains(["eastus", "westus", "centralus"], var.region)
    error_message = "The region must be one of the following: eastus, westus, centralus."
  }
}
```

Passing values on the CLI:

```bash theme={null}
terraform plan -var "rg=rg-kodekloud-tf-01" -var "region=eastus"
```

Example plan output (truncated):

```plaintext theme={null}
Terraform will perform the following actions:

  # azurerm_resource_group.rg will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "rg-kodekloud-tf-01"
      + tags     = {
          + "environment" = "testing"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
```

Complex types and defaults
You can define structured types and defaults for more advanced configurations.

```hcl theme={null}
variable "image_id" {
  type        = string
  description = "The ID of the machine image (AMI) to use for the server."
}

variable "availability_zone_names" {
  type        = list(string)
  description = "List of availability zones where resources will be deployed."
  default     = ["us-west-1"]
}

variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  description = "List of port configurations for Docker containers."
  default = [
    {
      internal = 8320
      external = 8320
      protocol = "tcp"
    }
  ]
}

variable "image_id" {
  description = "The ID of the machine image (AMI) to use for the server."
  validation {
    condition     = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
    error_message = "The image_id must be a valid AMI ID, starting with \"ami-\"."
  }
}
```

Note: These examples are independent snippets. Do not declare the same variable name more than once within the same module — redeclaring a variable name in the same module will cause an error.

Official variable block template
The [official Terraform documentation](https://www.terraform.io/language/values/variables) shows a template like:

```hcl theme={null}
variable "LABEL" {
  type        = string
  default     = "<DEFAULT VALUE>"
  description = "<DESCRIPTION>"
  validation {
    condition     = <EXPRESSION>
    error_message = "<ERROR_MESSAGE>"
  }
  sensitive = false
  nullable  = false
  ephemeral = false
}
```

Ways to set variable values (common methods) and precedence

| Method                                | Description                                                   | Notes                                    |
| ------------------------------------- | ------------------------------------------------------------- | ---------------------------------------- |
| `default` inside the `variable` block | Lowest precedence; used when no other source provides a value | `default` in the block                   |
| `.tfvars` or `.tfvars.json` files     | Common for environment or deployment-specific values          | e.g., `terraform.tfvars`                 |
| `-var-file` on the CLI                | Loads variables from a file at plan/apply time                | `terraform plan -var-file="prod.tfvars"` |
| `-var` on the CLI                     | Highest precedence among non‑environment sources              | `terraform plan -var "rg=..."`           |
| environment variables `TF_VAR_<NAME>` | Useful for automation and CI systems                          | e.g., `TF_VAR_rg="..."`                  |

Note: Precedence can be subtle and may vary between Terraform versions and environments. In general, CLI `-var` and `-var-file` override values from files and environment variables, and defaults in the variable block have the lowest precedence. Consult the [Terraform documentation](https://www.terraform.io/language/values/variables) for exact rules for your version.

Summary

* Use `type`, `description`, and `validation` to make variables self‑documenting and expressive.
* Explicit validations in shared modules and automation catch invalid inputs early.
* Protect secrets with `sensitive = true` and secure state backends; `sensitive` only masks output.
* Choose an appropriate method to supply values (defaults, `tfvars`, CLI, environment) and be aware of precedence for deterministic behavior.

Links and references

* [Terraform Variables — Official Documentation](https://www.terraform.io/language/values/variables)
* [Terraform State — Remote Backends](https://www.terraform.io/language/state/remote)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/terraform-on-azure/module/6909fa70-4ccc-40c3-a918-1188673d8985/lesson/a9827670-df89-4638-9ee0-7063fc36abc1" />
</CardGroup>
