Day 5: Understanding Terraform Variables in AWS

 


Variables in Terraform serve as placeholders for values that you can use repeatedly throughout your configuration files. The main benefits of using variables include:

  • Reuse of Values: Instead of hardcoding values across multiple resources, you can define them once as variables and reference them wherever needed.

  • Parameterization: Variables allow you to customize your Terraform configurations based on different environments (dev, prod, etc.) without changing the actual code structure.

Variables can be defined based on their purpose or value constraints (types), and they play an integral role in improving code maintainability.


Terraform classifies variables into three broad categories:

  1. Input Variables: These are variables whose values are provided by the user. They allow for customization of resources in your configuration.

  2. Output Variables: These variables are used to output information from the resources that Terraform creates. They are useful for displaying the result of your infrastructure deployment.

  3. Local Variables: These variables are scoped to the module and can store temporary values for use within that module. Locals are especially useful for combining and reusing expressions and complex data structures.


Input variables are defined within the variable block in your Terraform configuration. Here’s an example of how to define an input variable for the environment:

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

In this example, we define a variable environment with a default value of "dev". The type = string ensures that the variable accepts only string values. The default keyword provides a fallback value in case the variable isn’t defined elsewhere (e.g., in the environment or in a .tfvars file).

You can then reference this variable in resources like so:

resource "aws_instance" "ec2" {
    ami             = "ami-0c55b159cbfafe1f0"
    instance_type   = "t2.micro"
    tags = {
        Name        = "${var.environment}-ec2"   # Using the variable in the tag
        Environment = var.environment
    }
}

By referencing var.environment, you ensure that the resource is tagged dynamically based on the environment.


Local variables allow you to store intermediate or computed values within a configuration. These variables are defined using the locals block and are particularly useful for creating reusable expressions. For example:

locals {
    bucket_name = "${var.environment}-my-bucket"
    vpc_name    = "${var.environment}-vpc"
}

In this case, local variables are defined to dynamically create names for a bucket and a VPC, based on the environment input variable.

You can use these local variables in your resources as follows:

resource "aws_s3_bucket" "bucket" {
    bucket = local.bucket_name
    tags = {
        Name        = local.bucket_name
        Environment = var.environment
    }
}

By using local.bucket_name, you make your code more modular and avoid hardcoding values in your resource blocks.

# Configure the AWS Provider
terraform {

  # backend configuration
  backend "s3" {
    bucket         = "dev-tf-bucket-gurusai-terraform-state"
    key            = "dev/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    use_lockfile  = "true"
  }

  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  # Configuration options
    region = "us-east-1"
}

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

locals {
  bucket_name="${var.environment}.terraform-gurusai-bucket"
  vpc_name="${var.environment}.gurus-vpc"
}


resource "aws_instance" "ec2" {
    ami = "ami-0c55b159cbfafe1f0"
    instance_type = "t2.micro"
    tags = {
        Name = "${var.environment}-ec2"
        Environment = var.environment
    }
}

resource "aws_s3_bucket" "s3" {
    bucket = local.bucket_name
    tags = {
        Name = "my-s3"
        Environment = var.environment
    }
}

resource "aws_vpc" "vpc" {
    cidr_block = ["10.0.0.0/16"]
    tags = {
        Name = "my-vpc"
        Environment = var.environment
    }
}

output "vpc_id" {
    value = aws_vpc.sample.id
}

output "ec2_id" {
    value = aws_instance.example.id
}

Output variables are used to expose values from your resources that you might want to reference elsewhere or display for debugging purposes. For instance, after creating a VPC and an EC2 instance, you might want to know the IDs of these resources.

Here’s how to define output variables in Terraform:

output "vpc_id" {
    value = aws_vpc.sample.id
}

output "ec2_id" {
    value = aws_instance.example.id
}

Once the resources are created, the output values are available for display using the following command:

terraform output

This will return the values of the VPC ID and EC2 instance ID, making it easier to reference them in subsequent operations or configurations.


Terraform uses a specific order of precedence when resolving the values of variables. Understanding this hierarchy can help you control how variables are defined and overridden in your configurations.

  1. Default Values: The values you specify within the variable block using the default keyword are the initial values.

  2. Environment Variables: You can override the default values by setting environment variables using the TF_VAR_<variable_name> pattern. For example:

     export TF_VAR_environment="prod"
    
  3. .tfvars Files: You can create a .tfvars file (e.g., terraform.tfvars) to define variables in a key-value format. This is especially useful for managing multiple configurations:

     environment = "staging"
    
  4. .tfvars.json Files: Alternatively, you can use JSON format to define variables, which is compatible with many automation systems:

     {
         "environment": "prod"
     }
    
  5. Command-Line Options: The highest precedence comes from command-line options using -var or -var-file flags. These override all the previous values:

     terraform apply -var="environment=dev"
    

This flexibility ensures you can configure Terraform in a way that fits different environments and use cases, such as defining different configurations for staging, production, or development environments.



Terraform variables are powerful tools that make your infrastructure as code more flexible, modular, and maintainable. By using input variables to parameterize your configuration, local variables to store reusable values, and output variables to share resource information, you can optimize your Terraform configurations for both ease of use and scalability.

Mastering variable precedence allows you to ensure your configurations are flexible enough to accommodate different environments without the need for excessive manual intervention. Whether you're working with a single environment or managing multiple stages of infrastructure, understanding how to effectively use variables in Terraform is crucial for efficient automation and deployment.

Comments

Popular posts from this blog

Day 1: Introduction to IaC and Step-by-Step Terraform Setup

Day 4: Terraform State File and Remote Backend