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

# Conditional Expressions

> Explains Terraform conditional and for expressions, using ternary operators, nested versus flat lists, flatten and toset for for_each, and environment-based configuration examples

Conditional expressions in Terraform let you choose one value or another based on a boolean condition — essentially Terraform's ternary operator. This is useful for selecting regions, SKUs, sizes, or toggling small feature differences without duplicating resources or maintaining separate files per environment.

Example — choose region based on environment:

```hcl theme={null}
variable "environment" {
  type = string
  default = "dev"
}

resource "azurerm_resource_group" "rg" {
  name     = "rg-demo"
  location = var.environment == "prod" ? "eastus" : "westus"
}
```

The syntax is: `condition ? value_if_true : value_if_false`.

Use conditional expressions to keep configuration DRY and to decide values dynamically during `terraform plan` and `terraform apply`.

<Callout icon="lightbulb" color="#1CB2FE">
  Use conditional expressions to keep code clean and let Terraform compute configuration values (regions, SKUs, toggles) at plan/apply time.
</Callout>

This article also covers `for` expressions and how they interact with conditional expressions and `for_each`.

Example showing provider, variable, and locals with a conditional:

```hcl theme={null}
provider "azurerm" {
  features {}
}

variable "environment" {
  type    = string
  default = "dev"
}

locals {
  location     = var.environment == "prod" ? "eastus" : "westus"
  environments = ["dev", "prod"]
  apps         = ["api", "web", "db"]
}
```

Generating resource-group names with for expressions

Two common patterns generate combinations (environments × apps):

1. Nested `for` expression that returns a list of lists (nested list)

```hcl theme={null}
locals {
  rg_nested = [
    for env in local.environments :
      [ for app in local.apps : "rg-${env}-${app}" ]
  ]
}
```

`local.rg_nested` becomes a list with inner lists (one per environment), for example:
`[["rg-dev-api","rg-dev-web","rg-dev-db"], ["rg-prod-api","rg-prod-web","rg-prod-db"]]`.

2. Single `for` expression with two iterators that returns a flat list

```hcl theme={null}
locals {
  rg_flat = [ for env in local.environments : for app in local.apps : "rg-${env}-${app}" ]
}
```

`local.rg_flat` produces a flat list:
`["rg-dev-api","rg-dev-web","rg-dev-db","rg-prod-api","rg-prod-web","rg-prod-db"]`.

Using the generated names as resources

Terraform `for_each` supports maps and sets of strings. If you have a nested list (`rg_nested`), flatten it before converting to a set. Example using the nested list:

```hcl theme={null}
locals {
  rg_nested = [
    for env in local.environments :
      [ for app in local.apps : "rg-${env}-${app}" ]
  ]
}

resource "azurerm_resource_group" "rg" {
  for_each = toset(flatten(local.rg_nested))
  name     = each.value
  location = local.location
}
```

If you produce a flat list (`rg_flat`), you can use it directly:

```hcl theme={null}
locals {
  rg_flat = [ for env in local.environments : for app in local.apps : "rg-${env}-${app}" ]
}

resource "azurerm_resource_group" "rg" {
  for_each = toset(local.rg_flat)
  name     = each.value
  location = local.location
}
```

Why flatten? Example error when using a nested list directly

If you use the nested list without `flatten`, `for_each` will fail during `terraform plan`:

```bash theme={null}
# Initialize (example)
terraform init
```

```bash theme={null}
terraform plan
```

```plaintext theme={null}
Error: Invalid for_each set argument

  on main.tf line 18, in resource "azurerm_resource_group" "rg":
  18:   for_each = toset(local.rg_nested)

local.rg_nested is tuple with 2 elements

The given "for_each" argument value is unsuitable: "for_each" supports maps and sets of strings, but you have provided a set containing type tuple.
```

This error occurs because the nested `for` expression produced a list that contains inner lists. `flatten()` converts a nested list into a single flat list, which `toset()` can then convert into a set of strings acceptable to `for_each`.

<Callout icon="warning" color="#FF6B6B">
  If you produce nested lists, call `flatten()` before `toset()` when using `for_each`. Otherwise Terraform will complain that the argument type is not a set of strings.
</Callout>

Plan output and environment overrides

With the default `environment = "dev"`, `local.location` will compute to `"westus"`, so all resource groups are planned for West US. Example plan (after using `flatten` or `rg_flat`):

```plaintext theme={null}
Plan: 6 to add, 0 to change, 0 to destroy.

# azurerm_resource_group.rg["rg-dev-api"] will be created
+ resource "azurerm_resource_group" "rg" {
    + id       = (known after apply)
    + location = "westus"
    + name     = "rg-dev-api"
}
# ... other RGs omitted for brevity
```

Override the environment at plan time to change locations:

```bash theme={null}
terraform plan -var='environment=prod'
```

Now `local.location` evaluates to `"eastus"` and the plan shows East US locations:

```plaintext theme={null}
Plan: 6 to add, 0 to change, 0 to destroy.

# azurerm_resource_group.rg["rg-prod-api"] will be created
+ resource "azurerm_resource_group" "rg" {
    + id       = (known after apply)
    + location = "eastus"
    + name     = "rg-prod-api"
}
# ... other RGs omitted for brevity
```

Quick reference

| Topic                    | When to use                                              | Example / Notes                                                     |
| ------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------- |
| Conditional expressions  | Choose between two values (regions, SKUs, toggles)       | `condition ? true_val : false_val`                                  |
| For expressions (nested) | When you want grouped lists per iterator                 | `local.rg_nested = [ for env in ... : [ for app in ... : "..." ] ]` |
| For expressions (flat)   | When you want a single list of combinations              | `local.rg_flat = [ for env in ... : for app in ... : "..." ]`       |
| Flatten + toset          | Required when converting nested lists to `for_each` sets | `for_each = toset(flatten(local.rg_nested))`                        |

Summary

* Conditional expressions are Terraform's ternary operator — useful for environment-specific values and small toggles.
* `for` expressions build lists. Use a double `for` to produce a flat list directly, or nest `for` expressions to create grouped lists.
* If you have nested lists, use `flatten()` before `toset()` so `for_each` receives a set of strings.
* Override variables at `plan`/`apply` time (e.g., `-var='environment=prod'`) to affect computed locals like `local.location`.

Links and references

* [Terraform Expressions](https://www.terraform.io/docs/language/expressions/index.html)
* [Terraform for Expressions](https://www.terraform.io/docs/language/expressions/for.html)
* [Azure Provider (azurerm) Documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/terraform-on-azure/module/fb5019bb-df21-4583-818e-6dae40fde2ec/lesson/fda91ce8-39e6-4206-b1bb-9491f1b1753e" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/terraform-on-azure/module/fb5019bb-df21-4583-818e-6dae40fde2ec/lesson/5e9c2799-c739-4d2a-a547-bca4eebb7eee" />
</CardGroup>
