Terraform Generator
Overview
This skill enables the generation of production-ready Terraform configurations following best practices and current standards. Automatically integrates validation and documentation lookup for custom providers and modules.
Critical Requirements Checklist
STOP: You MUST complete ALL steps in order. Do NOT skip any REQUIRED step.
Step Action Required
1 Understand requirements (providers, resources, modules) ✅ REQUIRED
2 Check for custom providers/modules and lookup documentation ✅ REQUIRED
3 Consult reference files before generation ✅ REQUIRED
4 Generate Terraform files with ALL best practices ✅ REQUIRED
5 Include data sources for dynamic values (region, account, AMIs) ✅ REQUIRED
6 Add lifecycle rules on critical resources (KMS, databases) ✅ REQUIRED
7 Invoke Skill(devops-skills:terraform-validator)
✅ REQUIRED
8 FIX all validation/security failures and RE-VALIDATE ✅ REQUIRED
9 Provide usage instructions (files, next steps, security) ✅ REQUIRED
IMPORTANT: If validation fails (terraform validate OR security scan), you MUST fix the issues and re-run validation until ALL checks pass. Do NOT proceed to Step 9 with failing checks.
Core Workflow
When generating Terraform configurations, follow this workflow:
Step 1: Understand Requirements
Analyze the user's request to determine:
-
What infrastructure resources need to be created
-
Which Terraform providers are required (AWS, Azure, GCP, custom, etc.)
-
Whether any modules are being used (official, community, or custom)
-
Version constraints for providers and modules
-
Variable inputs and outputs needed
-
State backend configuration (local, S3, remote, etc.)
Step 2: Check for Custom Providers/Modules
Before generating configurations, identify if custom or third-party providers/modules are involved:
Standard providers (no lookup needed):
-
hashicorp/aws
-
hashicorp/azurerm
-
hashicorp/google
-
hashicorp/kubernetes
-
Other official HashiCorp providers
Custom/third-party providers/modules (require documentation lookup):
-
Third-party providers (e.g., datadog/datadog, mongodb/mongodbatlas)
-
Custom modules from Terraform Registry
-
Private or company-specific modules
-
Community modules
When custom providers/modules are detected:
Use WebSearch to find version-specific documentation:
Search query format: "[provider/module name] terraform [version] documentation [specific resource]" Example: "datadog terraform provider v3.30 monitor resource documentation" Example: "terraform-aws-modules vpc version 5.0 documentation"
Focus searches on:
-
Official documentation (registry.terraform.io, provider websites)
-
Required and optional arguments
-
Attribute references
-
Example usage
-
Version compatibility notes
If Context7 MCP is available and the provider/module is supported, use it as an alternative:
mcp__context7__resolve-library-id → mcp__context7__query-docs
Step 2.5: Consult Reference Files (REQUIRED)
Before generating configuration, you MUST consult reference files using this matrix:
Reference Requirement Read When
terraform_best_practices.md
REQUIRED Always - contains baseline required patterns
provider_examples.md
REQUIRED Any AWS, Azure, GCP, or Kubernetes resource generation
common_patterns.md
OPTIONAL by default, REQUIRED for complex requests Multi-environment, workspace, composition, DR, or conditional patterns
Open references by path:
devops-skills-plugin/skills/terraform-generator/references/terraform_best_practices.md devops-skills-plugin/skills/terraform-generator/references/provider_examples.md devops-skills-plugin/skills/terraform-generator/references/common_patterns.md
Step 3: Generate Terraform Configuration
Generate HCL files following best practices:
File Organization:
terraform-project/ ├── main.tf # Primary resource definitions ├── variables.tf # Input variable declarations ├── outputs.tf # Output value declarations ├── versions.tf # Provider version constraints ├── terraform.tfvars # Variable values (optional, for examples) └── backend.tf # Backend configuration (optional)
Best Practices to Follow:
Provider Configuration:
terraform { required_version = ">= 1.10, < 2.0"
required_providers { aws = { source = "hashicorp/aws" version = "~> 6.0" # Major pin; verify exact current version when needed } } }
provider "aws" { region = var.aws_region }
Resource Naming:
-
Use descriptive resource names
-
Follow snake_case convention
-
Include resource type in name when helpful
resource "aws_instance" "web_server" {
...
}
Variable Declarations:
variable "instance_type" { description = "EC2 instance type for web servers" type = string default = "t3.micro"
validation { condition = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type) error_message = "Instance type must be t3.micro, t3.small, or t3.medium." } }
Output Values:
output "instance_public_ip" { description = "Public IP address of the web server" value = aws_instance.web_server.public_ip }
Use Data Sources for References:
data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical
filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] } }
Module Usage:
module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.0.0"
name = "my-vpc" cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] }
Use locals for Computed Values:
locals { common_tags = { Environment = var.environment ManagedBy = "Terraform" Project = var.project_name } }
Lifecycle Rules When Appropriate:
resource "aws_instance" "example" {
...
lifecycle { create_before_destroy = true prevent_destroy = true ignore_changes = [tags] } }
Dynamic Blocks for Repeated Configuration:
resource "aws_security_group" "example" {
...
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 } } }
Comments and Documentation:
-
Add comments explaining complex logic
-
Document why certain values are used
-
Include examples in variable descriptions
Security Best Practices:
-
Never hardcode sensitive values (use variables)
-
Use data sources for AMIs and other dynamic values
-
Implement least-privilege IAM policies
-
Enable encryption by default
-
Use secure backend configurations
Required: Data Sources for Dynamic Values (Provider-Aware)
You MUST include provider-appropriate data lookups for dynamic infrastructure values. Do NOT hardcode cloud/account/region/image IDs.
Provider Required Dynamic Context Typical Data Sources
AWS Region/account/AZ/image IDs aws_region , aws_caller_identity , aws_availability_zones , aws_ami
Azure Tenant/subscription/client context azurerm_client_config , azurerm_subscription
GCP Project/client context/zone discovery google_client_config , google_compute_zones , google_compute_image
Kubernetes Cluster endpoint/auth from trusted source Use module outputs or cloud data sources; avoid hardcoded tokens/endpoints
AWS dynamic context
data "aws_region" "current" {} data "aws_caller_identity" "current" {}
Azure dynamic context
data "azurerm_client_config" "current" {} data "azurerm_subscription" "current" {}
GCP dynamic context
data "google_client_config" "current" {}
Required: Lifecycle and Deletion Safeguards (Provider-Aware)
You MUST protect stateful and critical resources from accidental destruction/deletion using both Terraform lifecycle and provider-native safeguards.
Provider Critical Resource Classes Required Protection Mechanism
AWS KMS, RDS, S3 data buckets, DynamoDB, ElastiCache, secrets lifecycle { prevent_destroy = true } and service-specific deletion protection where supported
Azure Key Vaults, SQL, Storage, stateful compute prevent_destroy where appropriate plus provider feature flags/resource deletion protection
GCP Cloud SQL, GKE, storage, stateful compute prevent_destroy and resource-level deletion_protection = true where supported
Kubernetes Stateful workloads and persistent data Avoid destructive replacement patterns and protect backing cloud resources
resource "aws_db_instance" "main" {
...
deletion_protection = true lifecycle { prevent_destroy = true } }
resource "google_sql_database_instance" "main" {
...
deletion_protection = true }
Required: Object Storage Lifecycle Safeguards
When using AWS S3 lifecycle configuration, ALWAYS include a rule to abort incomplete multipart uploads:
resource "aws_s3_bucket_lifecycle_configuration" "main" { bucket = aws_s3_bucket.main.id
REQUIRED: Abort incomplete multipart uploads to prevent storage costs
rule { id = "abort-incomplete-uploads" status = "Enabled"
# Filter applies to all objects (empty filter = all objects)
filter {}
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
}
Other lifecycle rules (e.g., transition to IA)
rule { id = "transition-to-ia" status = "Enabled"
filter {
prefix = "" # Apply to all objects
}
transition {
days = 90
storage_class = "STANDARD_IA"
}
noncurrent_version_transition {
noncurrent_days = 30
storage_class = "STANDARD_IA"
}
noncurrent_version_expiration {
noncurrent_days = 365
}
} }
Why? Incomplete multipart uploads consume storage and incur costs. Checkov check CKV_AWS_300 enforces this for AWS.
For Azure/GCP object storage, add equivalent lifecycle/retention rules for stale objects and old versions.
Step 4: Validate Generated Configuration (REQUIRED)
After generating Terraform files, ALWAYS validate them using the devops-skills:terraform-validator skill:
Invoke: Skill(devops-skills:terraform-validator)
The devops-skills:terraform-validator skill will:
-
Check HCL syntax with terraform fmt -check
-
Initialize the configuration with terraform init
-
Validate the configuration with terraform validate
-
Run security scan with Checkov
-
Perform dry-run testing (if requested) with terraform plan
CRITICAL: Fix-and-Revalidate Loop
If ANY validation or security check fails, you MUST:
-
Review the error - Understand what failed and why
-
Fix the issue - Edit the generated file to resolve the problem
-
Re-run validation - Invoke Skill(devops-skills:terraform-validator) again
-
Repeat until ALL checks pass - Do NOT proceed with failing checks
┌─────────────────────────────────────────────────────────┐ │ VALIDATION FAILED? │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────────────────┐ │ │ │ Fix │───▶│ Re-run │───▶│ All checks pass? │ │ │ │ Issue │ │ Skill │ │ YES → Step 5 │ │ │ └─────────┘ └─────────┘ │ NO → Loop back │ │ │ ▲ └─────────────────────┘ │ │ │ │ │ │ └────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘
Common validation failures to fix:
Check Issue Fix
CKV_AWS_300
Missing abort multipart upload Add abort_incomplete_multipart_upload rule
CKV_AWS_24
SSH open to 0.0.0.0/0 Restrict to specific CIDR
CKV_AWS_16
RDS encryption disabled Add storage_encrypted = true
terraform validate
Invalid resource argument Check provider documentation
If custom providers are detected during validation:
-
The devops-skills:terraform-validator skill will automatically fetch documentation
-
Use the fetched documentation to fix any issues
Step 5: Provide Usage Instructions (REQUIRED)
After successful generation and validation with ALL checks passing, you MUST provide the user with:
Required Output Format:
Generated Files
| File | Description |
|---|---|
<actual-file-path> | What was generated in that file |
Only list files that were actually generated for this request. Do not include placeholder paths or files that do not exist.
Next Steps
- Review and customize
terraform.tfvarswith your values - Initialize Terraform:
terraform init
-
Review the execution plan: terraform plan
-
Apply the configuration: terraform apply
Customization Notes
-
Update variable_name in terraform.tfvars
-
Configure backend in backend.tf for remote state
-
Adjust resource names/tags as needed
Security Reminders
⚠️ Before applying:
-
Review IAM policies and permissions
-
Ensure sensitive values are NOT committed to version control
-
Configure state backend with encryption enabled
-
Set up state locking for team collaboration
IMPORTANT: Do NOT skip Step 5. The user needs actionable guidance on how to use the generated configuration.
Common Generation Patterns
Pattern 1: Simple Resource Creation
User request: "Create an AWS S3 bucket with versioning"
Generated files:
main.tf- S3 bucket resource with versioning enabledvariables.tf- Bucket name, tags variablesoutputs.tf- Bucket ARN and name outputsversions.tf- AWS provider version constraints
Pattern 2: Module-Based Infrastructure
User request: "Set up a VPC using the official AWS VPC module"
Actions:
- Identify module: terraform-aws-modules/vpc/aws
- Web search for latest version and documentation
- Generate configuration using module with appropriate inputs
- Validate with devops-skills:terraform-validator
Pattern 3: Multi-Provider Configuration
User request: "Create infrastructure across AWS and Datadog"
Actions:
- Identify standard provider (AWS) and custom provider (Datadog)
- Web search for Datadog provider documentation with version
- Generate configuration with both providers properly configured
- Ensure provider aliases if needed
- Validate with devops-skills:terraform-validator
Pattern 4: Complex Resource with Dependencies
User request: "Create an ECS cluster with ALB and auto-scaling"
Generated structure:
- Multiple resource blocks with proper dependencies
- Data sources for AMIs, availability zones, etc.
- Local values for computed configurations
- Comprehensive variables and outputs
- Proper dependency management using implicit references
Error Handling
Common Issues and Solutions:
-
Provider Not Found:
- Ensure provider is listed in
required_providersblock - Verify source address format:
namespace/name - Check version constraint syntax
- Ensure provider is listed in
-
Invalid Resource Arguments:
- Refer to web search results for custom providers
- Check for required vs optional arguments
- Verify attribute value types (string, number, bool, list, map)
-
Circular Dependencies:
- Review resource references
- Use
depends_onexplicit dependencies if needed - Consider breaking into separate modules
-
Validation Failures:
- Run devops-skills:terraform-validator skill to get detailed errors
- Fix issues one at a time
- Re-validate after each fix
Version Awareness
Always consider version compatibility:
-
Terraform Version:
- Use
required_versionconstraint with both lower and upper bounds - If generated configuration includes write-only arguments (
*_wo): userequired_version = ">= 1.11, < 2.0". - Else if it uses ephemeral constructs (
ephemeralblocks, ephemeral variables/outputs) without write-only arguments: userequired_version = ">= 1.10, < 2.0". - Else use the project baseline (default
>= 1.8, < 2.0unless repository policy requires newer). - Use
>= 1.14, < 2.0for latest features (actions, query command) - Document any version-specific features used (see below)
- Use
-
Provider Version Policy (canonical):
- Pin provider major versions with
~>constraints (for example~> 6.0,~> 4.0,~> 7.0). - Do not claim "latest" version unless verified online during the current run.
- Keep cross-provider guidance consistent:
- AWS family: major-pin policy (for example
~> 6.0) - AzureRM: major-pin policy (for example
~> 4.0) - Google: major-pin policy (for example
~> 7.0) - Kubernetes: major/minor pin based on target cluster/provider compatibility
- AWS family: major-pin policy (for example
- Use the same provider/version language in
SKILL.md,references/terraform_best_practices.md, and templateassets/minimal-project/versions.tf.
- Pin provider major versions with
-
Module Versions:
- Always pin module versions
- Review module documentation for version compatibility
- Test module updates in non-production first
Required Version Decision Table
| Generated Output Contains | Required Version to Emit |
|---|---|
Any write-only argument (*_wo) | >= 1.11, < 2.0 |
| Ephemeral constructs only (no write-only) | >= 1.10, < 2.0 |
| Neither write-only nor ephemeral | Project baseline (default >= 1.8, < 2.0) |
Feature-Gating Examples
# Positive: write-only usage requires Terraform 1.11+
terraform {
required_version = ">= 1.11, < 2.0"
}
ephemeral "random_password" "db_password" {
length = 16
}
resource "aws_db_instance" "main" {
identifier = "mydb"
instance_class = "db.t3.micro"
allocated_storage = 20
engine = "postgres"
username = "admin"
skip_final_snapshot = true
password_wo = ephemeral.random_password.db_password.result
password_wo_version = 1
}
# Negative: reject this pattern (write-only with Terraform 1.10)
terraform {
required_version = ">= 1.10, < 2.0"
}
resource "aws_db_instance" "invalid" {
password_wo = "do-not-generate-this"
}
Terraform Version Feature Matrix
Feature
Minimum Version
terraform_data
resource
1.4+
import {}
blocks
1.5+
check {}
blocks
1.5+
Native testing (.tftest.hcl
)
1.6+
Test mocking
1.7+
removed {}
blocks
1.7+
Provider-defined functions
1.8+
Cross-type refactoring
1.8+
Enhanced variable validations
1.9+
templatestring
function
1.9+
Ephemeral resources
1.10+
Write-only arguments
1.11+
S3 native state locking
1.11+
Import blocks with for_each
1.12+
Actions block
1.14+
List resources (tfquery.hcl
)
1.14+
terraform query
command
1.14+
Modern Terraform Features (1.8+)
Provider-Defined Functions (Terraform 1.8+)
Provider-defined functions extend Terraform's built-in functions with provider-specific logic.
Syntax: provider::<provider_name>::<function_name>(arguments)
# AWS Provider Functions (v5.40+)
locals {
# Parse an ARN into components
parsed_arn = provider::aws::arn_parse(aws_instance.web.arn)
account_id = local.parsed_arn.account
region = local.parsed_arn.region
# Build an ARN from components
custom_arn = provider::aws::arn_build({
partition = "aws"
service = "s3"
region = ""
account = ""
resource = "my-bucket/my-key"
})
}
# Google Cloud Provider Functions (v5.23+)
locals {
# Extract region from zone
region = provider::google::region_from_zone(var.zone) # "us-west1-a" → "us-west1"
}
# Kubernetes Provider Functions (v2.28+)
locals {
# Encode HCL to Kubernetes manifest YAML
manifest_yaml = provider::kubernetes::manifest_encode(local.deployment_config)
}
Ephemeral Resources (Terraform 1.10+)
Ephemeral resources provide temporary values that are never persisted in state or plan files. Critical for handling secrets securely.
# Generate a password that never touches state
ephemeral "random_password" "db_password" {
length = 16
special = true
override_special = "!#$%&*()-_=+[]{}<>:?"
}
# Fetch secrets ephemerally from AWS Secrets Manager
ephemeral "aws_secretsmanager_secret_version" "api_key" {
secret_id = aws_secretsmanager_secret.api_key.id
}
# Ephemeral variables (declare with ephemeral = true)
variable "temporary_token" {
type = string
ephemeral = true # Value won't be stored in state
}
# Ephemeral outputs
output "session_token" {
value = ephemeral.aws_secretsmanager_secret_version.api_key.secret_string
ephemeral = true # Won't be stored in state
}
Write-Only Arguments (Terraform 1.11+)
Write-only arguments accept ephemeral values and are never persisted. They use _wo
suffix and require a version attribute.
terraform {
required_version = ">= 1.11, < 2.0"
}
# Secure database password handling
ephemeral "random_password" "db_password" {
length = 16
}
resource "aws_db_instance" "main" {
identifier = "mydb"
instance_class = "db.t3.micro"
allocated_storage = 20
engine = "postgres"
username = "admin"
# Write-only password - never stored in state!
password_wo = ephemeral.random_password.db_password.result
password_wo_version = 1 # Increment to trigger password rotation
skip_final_snapshot = true
}
# Secrets Manager with write-only
resource "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
# Write-only secret string
secret_string_wo = ephemeral.random_password.db_password.result
secret_string_wo_version = 1
}
Enhanced Variable Validations (Terraform 1.9+)
Validation conditions can now reference other variables, data sources, and local values.
# Reference data sources in validation
data "aws_ec2_instance_type_offerings" "available" {
filter {
name = "location"
values = [var.availability_zone]
}
}
variable "instance_type" {
type = string
description = "EC2 instance type"
validation {
# NEW: Can reference data sources
condition = contains(
data.aws_ec2_instance_type_offerings.available.instance_types,
var.instance_type
)
error_message = "Instance type ${var.instance_type} is not available in the selected AZ."
}
}
# Cross-variable validation
variable "min_instances" {
type = number
default = 1
}
variable "max_instances" {
type = number
default = 10
validation {
# NEW: Can reference other variables
condition = var.max_instances >= var.min_instances
error_message = "max_instances must be >= min_instances"
}
}
S3 Native State Locking (Terraform 1.11+)
S3 now supports native state locking without DynamoDB.
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "project/terraform.tfstate"
region = "us-east-1"
encrypt = true
# NEW: S3-native locking (Terraform 1.11+)
use_lockfile = true
# DEPRECATED: DynamoDB locking (still works but no longer required)
# dynamodb_table = "terraform-locks"
}
}
Import Blocks (Terraform 1.5+)
Declarative resource imports without command-line operations.
# Import existing resources declaratively
import {
to = aws_instance.web
id = "i-1234567890abcdef0"
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
# ... configuration must match existing resource
}
# Import with for_each
import {
for_each = var.existing_bucket_names
to = aws_s3_bucket.imported[each.key]
id = each.value
}
Moved and Removed Blocks
Safely refactor resources without destroying them.
# Rename a resource
moved {
from = aws_instance.old_name
to = aws_instance.new_name
}
# Move to a module
moved {
from = aws_vpc.main
to = module.networking.aws_vpc.main
}
# Cross-type refactoring (1.8+)
moved {
from = null_resource.example
to = terraform_data.example
}
# Remove resource from state without destroying (1.7+)
removed {
from = aws_instance.legacy
lifecycle {
destroy = false # Keep the actual resource, just remove from state
}
}
Import Blocks with for_each (Terraform 1.12+)
Import multiple resources using for_each
meta-argument.
# Import multiple S3 buckets using a map
locals {
buckets = {
"staging" = "bucket1"
"uat" = "bucket2"
"prod" = "bucket3"
}
}
import {
for_each = local.buckets
to = aws_s3_bucket.this[each.key]
id = each.value
}
resource "aws_s3_bucket" "this" {
for_each = local.buckets
}
# Import across module instances using list of objects
locals {
module_buckets = [
{ group = "one", key = "bucket1", id = "one_1" },
{ group = "one", key = "bucket2", id = "one_2" },
{ group = "two", key = "bucket1", id = "two_1" },
]
}
import {
for_each = local.module_buckets
id = each.value.id
to = module.group[each.value.group].aws_s3_bucket.this[each.value.key]
}
Actions Block (Terraform 1.14+)
Actions enable provider-defined operations outside the standard CRUD model. Use for operations like Lambda invocations, cache invalidations, or database backups.
# Invoke a Lambda function (example syntax)
action "aws_lambda_invoke" "process_data" {
function_name = aws_lambda_function.processor.function_name
payload = jsonencode({ action = "process" })
}
# Create CloudFront invalidation
action "aws_cloudfront_create_invalidation" "invalidate_cache" {
distribution_id = aws_cloudfront_distribution.main.id
paths = ["/*"]
}
# Actions support for_each
action "aws_lambda_invoke" "batch_process" {
for_each = toset(["task1", "task2", "task3"])
function_name = aws_lambda_function.processor.function_name
payload = jsonencode({ task = each.value })
}
Triggering Actions via Lifecycle:
Use action_trigger
within a resource's lifecycle block to automatically invoke actions:
resource "aws_lambda_function" "example" {
function_name = "my-function"
# ... other config ...
lifecycle {
action_trigger {
events = [after_create, after_update]
actions = [action.aws_lambda_invoke.process_data]
}
}
}
action "aws_lambda_invoke" "process_data" {
function_name = aws_lambda_function.example.function_name
payload = jsonencode({ action = "initialize" })
}
Manual Invocation:
Actions can also be invoked manually via CLI:
terraform apply -invoke action.aws_lambda_invoke.process_data
List Resources and Query Command (Terraform 1.14+)
Query and filter existing infrastructure using .tfquery.hcl
files and the terraform query
command.
# my-resources.tfquery.hcl
# Define list resources to query existing infrastructure
list "aws_instance" "web_servers" {
filter {
name = "tag:Environment"
values = [var.environment]
}
include_resource = true # Include full resource details
}
list "aws_s3_bucket" "data_buckets" {
filter {
name = "tag:Purpose"
values = ["data-storage"]
}
}
# Query infrastructure and output results
terraform query
# Generate import configuration from query results
terraform query -generate-config-out="import_config.tf"
# Output in JSON format
terraform query -json
# Use with variables
terraform query -var 'environment=prod'
Preconditions and Postconditions (Terraform 1.5+)
Add custom validation within resource lifecycle.
resource "aws_instance" "example" {
instance_type = "t3.micro"
ami = data.aws_ami.example.id
lifecycle {
# Check before creation
precondition {
condition = data.aws_ami.example.architecture == "x86_64"
error_message = "The selected AMI must be for the x86_64 architecture."
}
# Verify after creation
postcondition {
condition = self.public_dns != ""
error_message = "EC2 instance must be in a VPC that has public DNS hostnames enabled."
}
}
}
# Preconditions on outputs
output "web_url" {
value = "https://${aws_instance.web.public_dns}"
precondition {
condition = aws_instance.web.public_dns != ""
error_message = "Instance must have a public DNS name."
}
}
Resources
references/
The references/
directory contains detailed documentation for reference:
- terraform_best_practices.md
- Comprehensive best practices guide
- common_patterns.md
- Common Terraform patterns and examples
- provider_examples.md
- Example configurations for popular providers
Open a reference directly by relative path:
devops-skills-plugin/skills/terraform-generator/references/[filename].md
assets/
The assets/
directory contains template files:
- minimal-project/
- Minimal Terraform project template
Templates can be copied and customized for the user's specific needs.
Notes
- Always run devops-skills:terraform-validator after generation
- For feature/version drift checks in CI, run bash scripts/run_ci_checks.sh
- Web search is essential for custom providers/modules
- Follow the principle of least surprise in configurations
- Make configurations readable and maintainable
- Include helpful comments and documentation
- Generate realistic examples in terraform.tfvars when helpful