šŸ¶
Terraform

Terraform if else elsif Conditional Statements Explained

By Filip on 08/01/2024

Learn how to use if, else, and elsif conditional statements in Terraform to create dynamic and efficient infrastructure code.

Terraform if else elsif Conditional Statements Explained

Table of Contents

Introduction

Terraform uses conditional expressions for decision-making instead of traditional if-else statements. This article explains how to use conditional expressions in Terraform with examples for various scenarios. You'll learn how to apply conditional logic within resource arguments, conditionally create resources, and dynamically generate resource blocks. The article also covers important considerations like Terraform's execution model and tips for writing readable code.

Step-by-Step Guide

Terraform doesn't have explicit if, else, or elsif statements like traditional programming languages. Instead, it uses conditional expressions within resource arguments and other constructs to achieve similar logic.

1. Conditional Expressions:

  • The core of conditional logic in Terraform is the ternary operator: condition ? true_val : false_val
  • This evaluates the condition and returns true_val if true, otherwise false_val.
resource "aws_instance" "example" {
  # ... other arguments ...

  instance_type = var.enable_large_instance ? "t3.xlarge" : "t3.micro"
}

In this example, the instance_type will be "t3.xlarge" if the variable enable_large_instance is true, else it will be "t3.micro".

2. Multiple Conditions:

  • You can nest ternary operators for multiple conditions, but it can become less readable.
resource "aws_instance" "example" {
  # ... other arguments ...

  subnet_id = var.environment == "production" ? var.production_subnet_id : (var.environment == "staging" ? var.staging_subnet_id : var.default_subnet_id)
}

This assigns subnet_id based on the value of var.environment.

3. Resource-Level Conditionals:

  • You can conditionally create entire resources using the count meta-argument with a conditional expression.
resource "aws_security_group_rule" "ssh_from_office" {
  # ... other arguments ...

  count = var.allow_ssh_from_office ? 1 : 0
}

Here, the aws_security_group_rule resource will only be created if var.allow_ssh_from_office is true.

4. Dynamic Blocks:

  • Similar to count, you can use for_each with a conditional expression to dynamically generate blocks within a resource.
resource "aws_iam_policy" "example" {
  # ... other arguments ...

  statement {
    # ... other arguments ...

    dynamic "condition" {
      for_each = var.require_mfa ? [1] : []
      content {
        test     = "Bool"
        variable = "aws:MultiFactorAuthPresent"
        values   = ["true"]
      }
    }
  }
}

The condition block within the statement will only be included if var.require_mfa is true.

Important Considerations:

  • Terraform's execution model means it evaluates conditions at plan time, not runtime.
  • Avoid excessive nesting for readability. Consider breaking down logic into separate resources or modules.
  • Explore tools like Terragrunt or Terraform modules for more complex scenarios and code organization.

Remember that while these examples use JavaScript-like syntax for illustration, you'll write the actual conditional expressions using Terraform's configuration language syntax.

Code Example

This code demonstrates conditional logic in Terraform. It shows how to use conditional expressions for choosing resource attributes, applying conditions for resource creation, and dynamically generating blocks within resources based on variables. While the syntax differs from JavaScript, the underlying principles of conditional evaluation are consistent.

Terraform uses its own configuration language, not JavaScript. However, the concepts of conditional logic translate well. Here's how you'd implement the examples in Terraform's language:

1. Conditional Expressions:

resource "aws_instance" "example" {
  # ... other arguments ...

  instance_type = var.enable_large_instance ? "t3.xlarge" : "t3.micro"
}

2. Multiple Conditions:

resource "aws_instance" "example" {
  # ... other arguments ...

  subnet_id = var.environment == "production" ? var.production_subnet_id : (var.environment == "staging" ? var.staging_subnet_id : var.default_subnet_id)
}

3. Resource-Level Conditionals:

resource "aws_security_group_rule" "ssh_from_office" {
  # ... other arguments ...

  count = var.allow_ssh_from_office ? 1 : 0
}

4. Dynamic Blocks:

resource "aws_iam_policy" "example" {
  # ... other arguments ...

  statement {
    # ... other arguments ...

    dynamic "condition" {
      for_each = var.require_mfa ? [1] : []
      content {
        test     = "Bool"
        variable = "aws:MultiFactorAuthPresent"
        values   = ["true"]
      }
    }
  }
}

Key Points:

  • The syntax is Terraform-specific, not JavaScript.
  • The logic and concepts of conditional evaluation remain the same.
  • These examples demonstrate how to achieve conditional behavior within Terraform's declarative framework.

Additional Notes

This article provides a great overview of how Terraform handles conditional logic using conditional expressions. Here are some additional points to consider:

Understanding the "Declarative" Paradigm:

  • Thinking in terms of desired state: Unlike imperative programming where you write step-by-step instructions, Terraform focuses on defining the desired end state. Conditional logic helps achieve this by specifying what should be created or configured based on certain conditions.
  • No in-place modification: Terraform doesn't directly modify infrastructure. Instead, it determines the changes needed to reach the desired state and applies them. This means conditional logic affects resource creation, modification, or destruction, not their runtime behavior.

Best Practices and Alternatives:

  • Readability and maintainability: While nested ternary operators work, they can quickly become difficult to read. Favor clarity by:
    • Using multiple, simpler expressions.
    • Extracting complex logic into separate modules or functions.
    • Leveraging tools like Terragrunt for managing complex deployments.
  • Data sources for dynamic lookups: Instead of hardcoding values in conditional expressions, use data sources to fetch information dynamically during the planning phase. This promotes flexibility and reusability.
  • The for expression for filtering: The for expression can be used to filter collections based on conditions, offering a more readable alternative to nested ternaries in some cases.

Beyond the Basics:

  • Modules and conditional logic: Modules can accept input variables, allowing you to customize their behavior based on conditions passed from the calling module.
  • Conditional logic in other constructs: While the examples focus on resources, conditional expressions can be used in various Terraform constructs, including outputs, locals, and provisioners.

Troubleshooting:

  • Understanding error messages: Terraform's error messages can help pinpoint issues with conditional logic. Pay close attention to type mismatches and incorrect syntax.
  • Leveraging terraform plan and terraform console: Use terraform plan to preview changes before applying them and terraform console to experiment with expressions and troubleshoot logic.

By mastering conditional logic in Terraform, you can create more flexible, dynamic, and maintainable infrastructure as code.

Summary

This article explains how Terraform implements conditional logic without traditional if/else statements.

Key Takeaways:

  • Conditional Expressions: Terraform uses the ternary operator (condition ? true_val : false_val) for conditional logic within resource arguments and other constructs.
  • Multiple Conditions: While nesting ternary operators is possible, it can hinder readability.
  • Resource-Level Conditionals: The count meta-argument, combined with a conditional expression, allows for the conditional creation of entire resources.
  • Dynamic Blocks: Similar to count, for_each with a conditional expression enables dynamic generation of blocks within a resource.

Important Considerations:

  • Terraform evaluates conditions during the planning stage, not during runtime.
  • Avoid overly nested conditions for better code readability.
  • Leverage tools like Terragrunt or Terraform modules for complex scenarios and improved code organization.

In essence, Terraform provides powerful mechanisms for implementing conditional logic, relying on conditional expressions and specific constructs like count and for_each to achieve desired outcomes.

Conclusion

Terraform's approach to conditional logic, while different from traditional programming languages, provides a powerful and flexible way to manage infrastructure as code. By understanding conditional expressions, resource-level conditionals, and dynamic blocks, you can create adaptable and efficient Terraform configurations. Remember to prioritize readability and consider alternative approaches like data sources and modules for more complex scenarios. As you gain experience, you'll appreciate how Terraform's declarative nature, combined with its conditional logic capabilities, enables you to define and manage infrastructure in a predictable and scalable manner.

References

Were You Able to Follow the Instructions?

šŸ˜Love it!
šŸ˜ŠYes
šŸ˜Meh-gical
šŸ˜žNo
šŸ¤®Clickbait