Skip to main content

Command Palette

Search for a command to run...

Terraform HCL Guide

Published
2 min read
Terraform HCL Guide
R

I'm a results-driven professional skilled in both DevOps and Web Development. Here's a snapshot of what I bring to the table:

💻 DevOps Expertise:

  • AWS Certified Solutions Architect Associate: Proficient in deploying and managing applications in the cloud.
  • Automation Enthusiast: Leveraging Python for task automation, enhancing development workflows.

🔧 Tools & Technologies:

  • Ansible, Terraform, Docker, Prometheus, Kubernetes, Linux, Git, Github Actions, EC2, S3, VPC, R53 and other AWS services.

🌐 Web Development:

  • Proficient in HTML, CSS, JavaScript, React, Redux-toolkit, Node.js, Express.js and Tailwind CSS.
  • Specialized in building high-performance websites with Gatsby.js.

Let's connect to discuss how my DevOps skills and frontend expertise can contribute to your projects or team. Open to collaboration and always eager to learn!

Aside from my work, I've also contributed to open-source projects, like adding a feature for Focalboard Mattermost.

HCL is a structured configuration language designed by HashiCorp specifically for their tools, with Terraform being the most prominent user. It combines the human-friendliness of JSON with additional features that make it ideal for infrastructure configuration.

Blocks and Arguments

The basic building blocks of HCL are blocks and arguments. Here's a simple example:

# Block declaration
resource "aws_instance" "web_server" {
  # Arguments
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  # Nested block
  tags = {
    Name = "WebServer"
    Environment = "Production"
  }
}

Variables and Data Types

HCL supports various data types and variable declarations:

# String variable
variable "region" {
  type        = string
  default     = "us-west-2"
  description = "AWS region for resources"
}

# Number variable
variable "instance_count" {
  type        = number
  default     = 2
  description = "Number of EC2 instances"
}

# List variable
variable "availability_zones" {
  type    = list(string)
  default = ["us-west-2a", "us-west-2b"]
}

# Map variable
variable "instance_tags" {
  type = map(string)
  default = {
    Environment = "Production"
    Team        = "DevOps"
  }
}

Dynamic Blocks

Dynamic blocks allow you to create repeated nested blocks based on complex data structures:

locals {
  ingress_rules = [
    {
      port        = 80
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },
    {
      port        = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  ]
}

resource "aws_security_group" "web" {
  name = "web-security-group"

  dynamic "ingress" {
    for_each = local.ingress_rules
    content {
      from_port   = ingress.value.port
      to_port     = ingress.value.port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
}

Conditional Expressions

HCL supports conditional expressions for dynamic resource configuration:

resource "aws_instance" "server" {
  instance_type = var.environment == "production" ? "t2.medium" : "t2.micro"

  tags = {
    Environment = var.environment
    Name        = var.environment == "production" ? "prod-server" : "dev-server"
  }
}

Count and For Each

For creating multiple similar resources:

# Using count
resource "aws_instance" "server" {
  count         = var.instance_count
  ami           = var.ami_id
  instance_type = "t2.micro"

  tags = {
    Name = "server-${count.index + 1}"
  }
}

# Using for_each with a map
resource "aws_instance" "servers" {
  for_each = {
    web  = "t2.micro"
    app  = "t2.small"
    db   = "t2.medium"
  }

  ami           = var.ami_id
  instance_type = each.value

  tags = {
    Name = "server-${each.key}"
    Role = each.key
  }
}

Best Practices

  1. Use Consistent Formatting

    • Use 2-space indentation

    • Align = signs for readability

    • Group related resources together

  2. Variable Management

    • Use descriptive variable names

    • Always include variable descriptions

    • Set appropriate variable constraints

  3. Resource Organization

    • Use separate files for different components

    • Implement proper state management

    • Use workspaces for environment separation

  4. Documentation

    • Comment complex configurations

    • Use README files

    • Document variables and outputs

More from this blog

Rohit's Blog

92 posts

🚀 DevOps Engineer | Fullstack Developer

Find interesting blogs about Devops, Cloud Computing and Web development related topics