12 Prompts for Terraform and IaC: From Modules to Multi-Cloud

Introduction

Infrastructure as Code (IaC) has transformed how organizations manage cloud resources, and Terraform by HashiCorp remains the dominant open-source tool for provisioning across AWS, Azure, and GCP. However, writing efficient Terraform configurations—especially when dealing with reusable modules, state management, or multi-cloud architectures—requires deep understanding of HCL syntax, remote backends, and provider constraints. This article provides 12 ready-to-use prompts that cover the most critical Terraform and IaC tasks. Each prompt includes a clear explanation, a practical example, and actionable code snippets. Whether you are a DevOps engineer or a cloud architect, these prompts will save you hours of research and debugging.

12 Prompts for Terraform and IaC

1. Generate a Terraform Module for AWS VPC

Task: Create a reusable module that provisions a VPC with public and private subnets, an Internet Gateway, and route tables.

Prompt:

"Generate a Terraform module for AWS that creates a VPC with CIDR block 10.0.0.0/16, three public subnets (10.0.1.0/24, 10.0.2.0/24, 10.0.3.0/24) and three private subnets (10.0.101.0/24, 10.0.102.0/24, 10.0.103.0/24) in us-east-1. Include an Internet Gateway for public subnets and a single NAT Gateway for private subnets. Output the VPC ID, subnet IDs, and gateway IDs."

Explanation: This prompt forces the AI to produce a standardized module structure (variables.tf, main.tf, outputs.tf) that follows Terraform Registry best practices. The module should accept variables for environment tags and CIDR blocks, making it reusable across staging and production.

Example usage:

# main.tf
module "vpc" {
  source = "./modules/aws-vpc"
  vpc_cidr = "10.0.0.0/16"
  environment = "production"
}

output "vpc_id" {
  value = module.vpc.vpc_id
}

2. Configure Remote State with S3 and DynamoDB

Task: Set up a remote backend for Terraform state using an S3 bucket with DynamoDB for state locking.

Prompt:

"Write a Terraform configuration that creates an S3 bucket for remote state storage (with versioning enabled) and a DynamoDB table for state locking. Then provide the backend configuration block that references these resources. Use bucket name 'mycompany-terraform-state-1234' and table name 'terraform-state-lock'."

Explanation: Remote state is essential for team collaboration. The prompt ensures the bucket has proper server-side encryption and that the DynamoDB table has a primary key named 'LockID' (as required by Terraform).

Example usage:

# backend.tf
data "terraform_remote_state" "vpc" {
  backend = "s3"
  config = {
    bucket = "mycompany-terraform-state-1234"
    key    = "vpc/terraform.tfstate"
    region = "us-east-1"
    dynamodb_table = "terraform-state-lock"
  }
}

3. Create a Multi-Cloud Deployment (AWS + Azure)

Task: Provision an EC2 instance in AWS and a VM in Azure within a single Terraform configuration.

Prompt:

"Write a Terraform configuration that deploys a t2.micro EC2 instance in us-east-1 (AWS) and a Standard_B1s virtual machine in East US (Azure) simultaneously. Use separate provider blocks for AWS and Azure. Tag both resources with 'project: multi-cloud-demo'."

Explanation: Multi-cloud configurations require careful provider versioning and resource naming to avoid conflicts. The prompt tests the AI's ability to merge two provider configurations while maintaining clear separation.

Example usage:

# providers.tf
provider "aws" {
  region = "us-east-1"
}

provider "azurerm" {
  features {}
}

# main.tf
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name    = "aws-web"
    project = "multi-cloud-demo"
  }
}

resource "azurerm_virtual_network" "main" {
  name                = "azure-vnet"
  location            = "East US"
  resource_group_name = azurerm_resource_group.main.name
  address_space       = ["10.1.0.0/16"]
}

4. Implement Terraform Workspaces for Environments

Task: Use Terraform workspaces to manage separate environments (dev, staging, prod) with the same configuration.

Prompt:

"Write a Terraform configuration that uses workspaces to deploy an EC2 instance with different instance types per environment: t2.micro for dev, t2.small for staging, t2.medium for prod. Use a local variable that checks terraform.workspace to select the instance type."

Explanation: Workspaces are lightweight environment isolation without separate state files. The prompt teaches how to use the terraform.workspace interpolation and conditional expressions.

Example usage:

# variables.tf
variable "instance_type_map" {
  default = {
    dev  = "t2.micro"
    staging = "t2.small"
    prod = "t2.medium"
  }
}

# main.tf
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = var.instance_type_map[terraform.workspace]
}

5. Automate Terraform Plan Approval with GitHub Actions

Task: Create a CI/CD pipeline that runs terraform plan on pull requests and requires manual approval before terraform apply.

Prompt:

"Write a GitHub Actions workflow that triggers on pull requests to the main branch. The workflow should: (1) run terraform fmt and validate, (2) run terraform plan, (3) comment the plan output on the PR, (4) require a manual approval before running terraform apply when the PR is merged."

Explanation: This prompt addresses real-world security and collaboration needs. The workflow uses hashicorp/setup-terraform action and environment protection rules.

Example usage:

# .github/workflows/terraform.yml
name: 'Terraform CI'
on:
  pull_request:
    branches: [main]

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform fmt -check
      - run: terraform plan -out=tfplan

6. Use for_each and count to Manage Multiple Resources

Task: Provision multiple IAM users from a list using for_each and multiple EC2 instances using count.

Prompt:

"Write Terraform code that creates three IAM users (alice, bob, charlie) using for_each and three EC2 instances (web-0, web-1, web-2) using count. Each IAM user should have a policy attachment, and each EC2 instance should have a unique name tag."

Explanation: The prompt differentiates between for_each (map iteration) and count (integer iteration). It teaches how to access keys and indices in resource references.

Example usage:

# main.tf
locals {
  users = toset(["alice", "bob", "charlie"])
}

resource "aws_iam_user" "this" {
  for_each = local.users
  name     = each.key
}

resource "aws_instance" "web" {
  count         = 3
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "web-${count.index}"
  }
}

7. Manage Terraform State with terraform import

Task: Import an existing AWS S3 bucket into Terraform state.

Prompt:

"Assume you have an existing S3 bucket named 'my-existing-bucket' created manually. Write the Terraform resource block to represent this bucket, and provide the exact CLI command to import it into the state. Use resource name 'existing_bucket'."

Explanation: Importing existing infrastructure is a common IaC migration task. The prompt ensures the AI generates a compatible resource block and the correct import syntax.

Example usage:

# main.tf
resource "aws_s3_bucket" "existing_bucket" {
  bucket = "my-existing-bucket"
  # No other attributes required for import
}

# CLI command:
# terraform import aws_s3_bucket.existing_bucket my-existing-bucket

8. Create a Reusable Module with Input Variables and Outputs

Task: Write a Terraform module for an AWS security group that accepts ingress rules as a variable.

Prompt:

"Create a Terraform module named 'security-group' that accepts a variable named 'ingress_rules' as a list of objects with fields: from_port, to_port, protocol, cidr_blocks. The module should create an AWS security group resource and output the security group ID. Provide an example caller configuration."

Explanation: Modular design is core to IaC. The prompt tests the AI's ability to define complex variable types and use them in resource declarations.

Example usage:

# modules/security-group/variables.tf
variable "ingress_rules" {
  type = list(object({
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
  }))
}

# main.tf
resource "aws_security_group" "this" {
  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
}

9. Use Data Sources to Fetch Existing Resources

Task: Fetch the VPC ID of a default VPC in AWS and use it to launch an EC2 instance.

Prompt:

"Write Terraform code that uses a data source to get the default VPC ID in region us-east-1, and then launches an EC2 instance in that VPC. Use the data source 'aws_vpc' with filter 'isDefault = true'."

Explanation: Data sources avoid hardcoding resource IDs. The prompt teaches how to reference data source attributes in other resources.

Example usage:

# main.tf
data "aws_vpc" "default" {
  default = true
}

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = data.aws_subnets.default.ids[0]
}

10. Handle Sensitive Values with sensitive Parameter

Task: Store a database password in Terraform state as sensitive and output it without exposing it in logs.

Prompt:

"Write Terraform code that creates an AWS RDS instance with a password stored in a variable marked as sensitive. Use the sensitive = true attribute in the output block to prevent the password from being displayed in the CLI output. Provide the variable definition and output."

Explanation: Security is critical in IaC. The prompt reinforces the use of sensitive parameter and best practices for secret management.

Example usage:

# variables.tf
variable "db_password" {
  type      = string
  sensitive = true
}

# outputs.tf
output "db_password" {
  value     = aws_db_instance.main.password
  sensitive = true
}

11. Write a terraform plan Output Parser Script

Task: Create a bash script that parses terraform plan output to extract the number of resources to add, change, or destroy.

Prompt:

"Write a bash script that runs terraform plan -no-color and uses grep to extract lines containing 'Plan:'. The script should output a JSON object with keys 'add', 'change', 'destroy' and their respective counts. Handle the case where no changes are needed."

Explanation: Automating plan analysis is useful for CI/CD dashboards. The prompt tests the AI's ability to parse structured text output.

Example usage:

#!/bin/bash
PLAN_OUTPUT=$(terraform plan -no-color 2>&1)
PLAN_LINE=$(echo "$PLAN_OUTPUT" | grep "Plan:")
ADD=$(echo "$PLAN_LINE" | grep -oP '\d+(?= to add)')
CHANGE=$(echo "$PLAN_LINE" | grep -oP '\d+(?= to change)')
DESTROY=$(echo "$PLAN_LINE" | grep -oP '\d+(?= to destroy)')
echo "{\"add\":${ADD:-0},\"change\":${CHANGE:-0},\"destroy\":${DESTROY:-0}}"

12. Use terraform validate with Custom Policy Checks

Task: Implement a policy check using Sentinel or OPA to ensure all S3 buckets have versioning enabled.

Prompt:

"Write a Sentinel policy that checks if all AWS S3 buckets in a Terraform configuration have versioning enabled. The policy should fail if any bucket has 'versioning' set to disabled or absent. Provide the policy code and instructions for integrating it into Terraform Cloud."

Explanation: Policy-as-code enforces compliance. The prompt introduces Sentinel (HashiCorp's policy language) and its integration with Terraform Cloud.

Example usage:

# policy.sentinel
import "tfplan/v2" as tfplan

all_s3_buckets = filter tfplan.resource_changes as _, rc {
  rc.type is "aws_s3_bucket" and rc.change.actions contains "create"
}

main = rule {
  all all_s3_buckets as _, bucket {
    bucket.change.after.versioning.enabled is true
  }
}

Conclusion

These 12 prompts cover the most frequent Terraform and IaC scenarios, from modular design to multi-cloud orchestration and policy enforcement. By using them as templates, you can accelerate your infrastructure automation and avoid common pitfalls like state corruption or security misconfigurations. For deeper learning, refer to the official Terraform documentation at developer.hashicorp.com/terraform. Apply these prompts in your next project and share your results with the community.

← All posts

Comments