DEV Community

丁久
丁久

Posted on • Originally published at dingjiu1989-hue.github.io

Terraform Tools: Terragrunt, terratest, tfsec, Infracost

This article was originally published on AI Study Room. For the full version with working code examples and related articles, visit the original post.

Terraform Tools: Terragrunt, terratest, tfsec, Infracost

Introduction

Terraform has become the standard for infrastructure as code, but managing Terraform at scale requires additional tools. Terragrunt reduces configuration duplication. Terratest enables automated infrastructure testing. Tfsec scans configurations for security issues. Infracost provides cost estimates before deployment. This article covers each tool with practical examples.

Terragrunt

A thin wrapper that keeps Terraform configurations DRY:

# terragrunt.hcl (root configuration)

remote_state {

  backend = "s3"

  config = {

    bucket         = "my-company-terraform-state"

    key            = "${path_relative_to_include()}/terraform.tfstate"

    region         = "us-east-1"

    encrypt        = true

    dynamodb_table = "terraform-locks"

  }

}

generate "provider" {

  path      = "provider.tf"

  if_exists = "overwrite_terragrunt"

  contents  = <<EOF

provider "aws" {

  region = local.aws_region

  default_tags {

    tags = {

      Environment = local.environment

      ManagedBy   = "terragrunt"

    }

  }

}

EOF

}

locals {

  aws_region  = "us-east-1"

  environment = reverse(split("/", get_terragrunt_dir()))[1]

}

# dev/vpc/terragrunt.hcl

terraform {

  source = "../../modules/vpc"

}

include "root" {

  path = find_in_parent_folders()

}

inputs = {

  vpc_name         = "dev-vpc"

  cidr_block       = "10.0.0.0/16"

  enable_nat       = true

  enable_vpn       = false

  private_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]

  public_subnets   = ["10.0.101.0/24", "10.0.102.0/24"]

}

# Apply all modules in dependency order

terragrunt run-all apply

# Plan only changed modules

terragrunt run-all plan

# Output dependency graph

terragrunt graph | dot -Tpng > graph.png

# Validate all configurations

terragrunt run-all validate

# Destroy with confirmation

terragrunt run-all destroy
Enter fullscreen mode Exit fullscreen mode

Terratest

Go library for writing automated infrastructure tests:

package test

import (

    "testing"

    "github.com/gruntwork-io/terratest/modules/terraform"

    "github.com/gruntwork-io/terratest/modules/aws"

    "github.com/stretchr/testify/assert"

)

func TestVPCDeployment(t *testing.T) {

    terraformOptions := &terraform.Options{

        TerraformDir: "../examples/vpc",

        Vars: map[string]interface{}{

            "vpc_name":   "test-vpc",

            "cidr_block": "10.0.0.0/16",

        },

        NoColor: true,

    }

    // Clean up at the end

    defer terraform.Destroy(t, terraformOptions)

    // Deploy infrastructure

    terraform.InitAndApply(t, terraformOptions)

    // Verify outputs

    vpcID := terraform.Output(t, terraformOptions, "vpc_id")

    assert.NotEmpty(t, vpcID)

    // Verify the VPC actually exists in AWS

    vpc := aws.GetVpcById(t, vpcID, "us-east-1")

    assert.Equal(t, "10.0.0.0/16", vpc.CidrBlock)

    // Verify subnets were created

    subnets := aws.GetSubnetsForVpc(t, vpcID, "us-east-1")

    assert.Len(t, subnets, 4)

    // Verify security group rules

    sgID := terraform.Output(t, terraformOptions, "web_sg_id")

    sgRules := aws.GetSecurityGroupRules(t, sgID, "us-east-1")

    assert.GreaterOrEqual(t, len(sgRules), 2)

}
Enter fullscreen mode Exit fullscreen mode

tfsec (now Trivy)

Security scanning for Terraform configurations:

# Install tfsec

brew install tfsec

# Or use Trivy which includes tfsec rules

brew install trivy

# Scan Terraform files

tfsec .

tfsec ./environments/production

tfsec --no-color --format json > scan-results.json

# In CI

tfsec --soft-fail  # Don't fail CI, just report

# Trivy equivalent

trivy config --severity HIGH,CRITICAL .

# Bad configuration that tfsec catches

resource "aws_s3_bucket" "data" {

  bucket = "my-data-bucket"

  acl    = "public-read"  # tfsec: aws-s3-no-public-read-acl

}

resource "aws_security_group" "web" {

  ingress {

    from_port = 22

    to_port   = 22

    protocol  = "tcp"

    cidr_blocks = ["0.0.0.0/0"]  # tfsec: aws-vpc-no-public-ingress-sgr

  }

}

# Fixed configuration

resource "aws_s3_bucket" "data" {

  bucket = "my-data-bucket"

  acl    = "private"

}

resource "aws_security_group" "web" {

  ingress {

    from_port   = 22

    to_port     = 22

    protocol    = "tcp"

    cidr_blocks = ["10.0.0.0/8"]  # Restricted to internal network

  }

}
Enter fullscreen mode Exit fullscreen mode

Infracost

Cost estimation for Terraform projects:

# Install

brew install infracost

infracost auth login

# Generate cost estimate for current stat
Enter fullscreen mode Exit fullscreen mode

Read the full article on AI Study Room for complete code examples, comparison tables, and related resources.

Found this useful? Check out more developer guides and tool comparisons on AI Study Room.

Top comments (0)