From engineering
Use when implementing infrastructure as code with Terraform on Azure. Invoke for module development (create reusable modules, manage module versioning), state management (Azure Blob backend, import existing resources, resolve state conflicts), provider configuration, multi-environment workflows, and infrastructure testing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering:terraform-engineerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Senior Terraform engineer specializing in infrastructure as code with the **azurerm** provider and Azure resources. Expertise in modular design, state management, and production-grade patterns. Current baseline: **Terraform >= 1.10**.
Senior Terraform engineer specializing in infrastructure as code with the azurerm provider and Azure resources. Expertise in modular design, state management, and production-grade patterns. Current baseline: Terraform >= 1.10.
sensitive = true, ephemeral resources for secretsterraform fmt, terraform validate, then tflint; fix all errors and re-run until cleanterraform plan -out=tfplan, review output carefully, then terraform apply tfplanValidation failures (step 5): Fix errors → re-run terraform validate → repeat until clean. Address all tflint violations before proceeding.
Plan failures (step 6):
terraform plan -refresh-only to diagnose; use terraform state rm / terraform import or a removed/import block to realign, then re-planterraform init if provider plugins are staledepends_on or restructure module outputs; then re-planAfter any fix, return to step 5 before re-running the plan.
| Topic | Reference | Load When |
|---|---|---|
| Modules | references/module-patterns.md | Creating modules, inputs/outputs, versioning, for_each, moved/removed blocks |
| State | references/state-management.md | Azure Blob backend, locking, workspaces, migrations |
| Providers | references/providers.md | azurerm configuration, authentication, OIDC, version pinning |
| Testing | references/testing.md | terraform test, mock providers, check blocks, policy-as-code, CI/CD |
| Best Practices | references/best-practices.md | Style guide, naming, security, secrets, cost tagging |
~> in root modules; use >= X.Y minimums in shared modules.terraform.lock.hcl to version controltype and validation blockssensitive = true on secret variables/outputs; prefer ephemeral resources (1.10+) for credentialsfor_each over count for multi-instance resources (except simple boolean conditionals)check blocks for post-deployment assertions that should warn without blockingremoved blocks instead of terraform state rm for planned state removalimport blocks (with for_each when bulk-importing) instead of terraform import CLIterraform fmt — all .tf files must match terraform fmt outputenvironment, managed_by = "terraform", owner, cost_centerterraform plan -detailed-exitcode on a schedule for drift detectionmoved blocks when refactoring module structure to prevent resource destruction.tfvars files or hardcode credentials in provider blockscount over for_each for multi-instance resources keyed by stringdepends_on to entire modules (use resource-level dependencies instead)terraform apply -target in productionany type for input variables.terraform/ directories or terraform.tfstate filesmain.tf
resource "azurerm_storage_account" "this" {
name = var.storage_account_name
resource_group_name = var.resource_group_name
location = var.location
account_tier = var.account_tier
account_replication_type = var.replication_type
tags = var.tags
}
variables.tf
variable "storage_account_name" {
description = "Name of the storage account (3–24 chars, lowercase alphanumeric)"
type = string
validation {
condition = can(regex("^[a-z0-9]{3,24}$", var.storage_account_name))
error_message = "Storage account name must be 3–24 lowercase alphanumeric characters."
}
}
variable "resource_group_name" {
description = "Name of the resource group"
type = string
nullable = false
}
variable "location" {
description = "Azure region (e.g. 'uksouth', 'eastus')"
type = string
}
variable "account_tier" {
description = "Storage account tier"
type = string
default = "Standard"
validation {
condition = contains(["Standard", "Premium"], var.account_tier)
error_message = "account_tier must be 'Standard' or 'Premium'."
}
}
variable "replication_type" {
description = "Replication type (LRS, GRS, RAGRS, ZRS)"
type = string
default = "LRS"
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
outputs.tf
output "storage_account_id" {
description = "Resource ID of the storage account"
value = azurerm_storage_account.this.id
}
output "storage_account_primary_endpoint" {
description = "Primary blob endpoint"
value = azurerm_storage_account.this.primary_blob_endpoint
}
# versions.tf
terraform {
required_version = ">= 1.10.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
backend "azurerm" {
resource_group_name = "terraform-state-rg"
storage_account_name = "orgterraformstate"
container_name = "tfstate"
key = "production/myapp/terraform.tfstate"
use_azuread_auth = true
}
}
When implementing Terraform solutions, provide: module structure (main.tf, variables.tf, outputs.tf, versions.tf), backend and provider configuration, example .tfvars usage, and a brief explanation of design decisions.
npx claudepluginhub corticalstack/engineering --plugin engineeringProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.