/refactor-module
Transform monolithic Terraform configurations into reusable, maintainable modules following HashiCorp's module design principles and community best practices.
$ npx -y skills add hashicorp/agent-skills --skill refactor-module --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/refactor-module
Context preview
The summary Claude sees to decide when to auto-load this skill.
Transform monolithic Terraform configurations into reusable, maintainable modules following HashiCorp's module design principles and community best practices.
SKILL.md
refactor-module.SKILL.mdname: refactor-module
description: Transform monolithic Terraform configurations into reusable, maintainable modules following HashiCorp's module design principles and community best practices.
metadata:
copyright: Copyright IBM Corp. 2026
version: "0.0.1"
Skill: Refactor Module
Overview
This skill guides AI agents in transforming monolithic Terraform configurations into reusable, maintainable modules following HashiCorp's module design principles and community best practices.
Capability Statement
The agent will analyze existing Terraform code and systematically refactor it into well-structured modules with:
- Clear interface contracts (variables and outputs)
- Proper encapsulation and abstraction
- Versioning and documentation
- Testing frameworks
- Migration path for existing state
Prerequisites
- Existing Terraform configuration to refactor
- Understanding of resource dependencies
- Access to current state file (for migration planning)
- Knowledge of module registry patterns
Input Parameters
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `source_directory` | string | Yes | Path to existing Terraform configuration | | `module_name` | string | Yes | Name for the new module | | `abstraction_level` | string | No | "simple", "intermediate", "advanced" (default: intermediate) | | `preserve_state` | boolean | Yes | Whether to maintain state compatibility | | `target_registry` | string | No | Target module registry (local, private, public) |
Execution Steps
1. Analysis Phase
**Identify Refactoring Candidates**
- Group resources by logical function
- Identify repeated patterns
- Map resource dependencies
- Detect configuration coupling
- Analyze variable usage patterns
**Complexity Assessment**
- Count resource relationships
- Measure variable propagation depth
- Identify cross-resource references
- Evaluate state migration complexity
2. Module Design
Interface Design
# Define clear input contract
variable "network_config" {
description = "Network configuration parameters"
type = object({
cidr_block = string
availability_zones = list(string)
enable_nat = bool
})
validation {
condition = can(cidrhost(var.network_config.cidr_block, 0))
error_message = "CIDR block must be valid IPv4 CIDR."
}
}
# Define output contract
output "vpc_id" {
description = "ID of the created VPC"
value = aws_vpc.main.id
}
output "private_subnet_ids" {
description = "List of private subnet IDs"
value = { for k, v in aws_subnet.private : k => v.id }
}Encapsulation Strategy
**What to Include in Module:**
- Tightly coupled resources (VPC + subnets)
- Resources with shared lifecycle
- Configuration with clear boundaries
**What to Keep Separate:**
- Cross-cutting concerns (monitoring, tagging)
- Resources with different lifecycles
- Provider-specific configurations
3. Code Transformation
Before: Monolithic Configuration
# main.tf (monolithic)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "production-vpc"
Environment = "prod"
}
}
resource "aws_subnet" "public_1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
tags = {
Name = "public-subnet-1"
Type = "public"
}
}
resource "aws_subnet" "public_2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
tags = {
Name = "public-subnet-2"
Type = "public"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "production-igw"
}
}
# ... more repetitive subnet and routing resourcesAfter: Modular Structure
# modules/vpc/main.tf
locals {
subnet_count = length(var.availability_zones)
}
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
tags = merge(
var.tags,
{
Name = var.name
}
)
}
resource "aws_subnet" "public" {
for_each = var.create_public_subnets ? toset(var.availability_zones) : []
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.cidr_block, 8, index(var.availability_zones, each.value))
availability_zone = each.value
map_public_ip_on_launch = true
tags = merge(
var.tags,
{
Name = "${var.name}-public-${each.value}"
Type = "public"
}
)
}
resource "aws_internet_gateway" "main" {
count = var.create_public_subnets ? 1 : 0
vpc_id = aws_vpc.main.id
tags = merge(
var.tags,
{
Name = "${var.name}-igw"
}
)
}
# modules/vpc/variables.tf
variable "name" {
description = "Name prefix for all resources"
type = string
}
variable "cidr_block" {
description = "CIDR block for the VPC"
type = string
validation {
condition = can(cidrhost(var.cidr_block, 0))
error_message = "Must be a valid IPv4 CIDR block."
}
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
}
variable "create_public_subnets" {
description = "Whether to create public subnets"
type = bool
default = true
}
variable "enable_dns_hostnames" {
description = "Enable DNS hostnames in the VPC"
type = bool
default = true
}
variable "enable_dns_support" {
description = "Enable DNS support in the VPC"
type = bool
default = true
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
# modules/vpc/outputs.tf
output "vpc_id" {
description = "ID of the VPC"
value = aws_vpc.main.id
}
output "vpc_cidr_block" {
description = "CIDR block of the VPC"
value = aws_vpc.mRead more
name: refactor-module description: Transform monolithic Terraform configurations into reusable, maintainable modules following HashiCorp's module design principles and community best practices. metadata: copyright: Copyright IBM Corp. 2026 version: "0.0.1"
Skill: Refactor Module
Overview
This skill guides AI agents in transforming monolithic Terraform configurations into reusable, maintainable modules following HashiCorp's module design principles and community best practices.
Capability Statement
The agent will analyze existing Terraform code and systematically refactor it into well-structured modules with:
- Clear interface contracts (variables and outputs)
- Proper encapsulation and abstraction
- Versioning and documentation
- Testing frameworks
- Migration path for existing state
Prerequisites
- Existing Terraform configuration to refactor
- Understanding of resource dependencies
- Access to current state file (for migration planning)
- Knowledge of module registry patterns
Input Parameters
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `source_directory` | string | Yes | Path to existing Terraform configuration | | `module_name` | string | Yes | Name for the new module | | `abstraction_level` | string | No | "simple", "intermediate", "advanced" (default: intermediate) | | `preserve_state` | boolean | Yes | Whether to maintain state compatibility | | `target_registry` | string | No | Target module registry (local, private, public) |
Execution Steps
1. Analysis Phase
**Identify Refactoring Candidates** - Group resources by logical function - Identify repeated patterns - Map resource dependencies - Detect configuration coupling - Analyze variable usage patterns **Complexity Assessment** - Count resource relationships - Measure variable propagation depth - Identify cross-resource references - Evaluate state migration complexity
2. Module Design
Interface Design
# Define clear input contract
variable "network_config" {
description = "Network configuration parameters"
type = object({
cidr_block = string
availability_zones = list(string)
enable_nat = bool
})
validation {
condition = can(cidrhost(var.network_config.cidr_block, 0))
error_message = "CIDR block must be valid IPv4 CIDR."
}
}
# Define output contract
output "vpc_id" {
description = "ID of the created VPC"
value = aws_vpc.main.id
}
output "private_subnet_ids" {
description = "List of private subnet IDs"
value = { for k, v in aws_subnet.private : k => v.id }
}Encapsulation Strategy
**What to Include in Module:** - Tightly coupled resources (VPC + subnets) - Resources with shared lifecycle - Configuration with clear boundaries **What to Keep Separate:** - Cross-cutting concerns (monitoring, tagging) - Resources with different lifecycles - Provider-specific configurations
3. Code Transformation
Before: Monolithic Configuration
# main.tf (monolithic)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "production-vpc"
Environment = "prod"
}
}
resource "aws_subnet" "public_1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
tags = {
Name = "public-subnet-1"
Type = "public"
}
}
resource "aws_subnet" "public_2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
tags = {
Name = "public-subnet-2"
Type = "public"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "production-igw"
}
}
# ... more repetitive subnet and routing resourcesAfter: Modular Structure
# modules/vpc/main.tf
locals {
subnet_count = length(var.availability_zones)
}
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
tags = merge(
var.tags,
{
Name = var.name
}
)
}
resource "aws_subnet" "public" {
for_each = var.create_public_subnets ? toset(var.availability_zones) : []
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.cidr_block, 8, index(var.availability_zones, each.value))
availability_zone = each.value
map_public_ip_on_launch = true
tags = merge(
var.tags,
{
Name = "${var.name}-public-${each.value}"
Type = "public"
}
)
}
resource "aws_internet_gateway" "main" {
count = var.create_public_subnets ? 1 : 0
vpc_id = aws_vpc.main.id
tags = merge(
var.tags,
{
Name = "${var.name}-igw"
}
)
}
# modules/vpc/variables.tf
variable "name" {
description = "Name prefix for all resources"
type = string
}
variable "cidr_block" {
description = "CIDR block for the VPC"
type = string
validation {
condition = can(cidrhost(var.cidr_block, 0))
error_message = "Must be a valid IPv4 CIDR block."
}
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
}
variable "create_public_subnets" {
description = "Whether to create public subnets"
type = bool
default = true
}
variable "enable_dns_hostnames" {
description = "Enable DNS hostnames in the VPC"
type = bool
default = true
}
variable "enable_dns_support" {
description = "Enable DNS support in the VPC"
type = bool
default = true
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
# modules/vpc/outputs.tf
output "vpc_id" {
description = "ID of the VPC"
value = aws_vpc.main.id
}
output "vpc_cidr_block" {
description = "CIDR block of the VPC"
value = aws_vpc.mA collection of Agent skills and Claude Code plugins for HashiCorp products. Legal Note: Your use of a third party MCP Client/LLM is subject solely to the terms of use for such MCP/LLM, and IBM is not responsible for the performance of such third party tools.
Repo: hashicorp/agent-skills
Other skills on hashicorp-agent-skills.
- /aws-ami-builder
Build Amazon Machine Images (AMIs) with Packer using the amazon-ebs builder. Use when creating custom AMIs for EC2 instances.
Open skill - /azure-image-builder
Build Azure managed images and Azure Compute Gallery images with Packer. Use when creating custom images for Azure VMs.
Open skill - /windows-builder
Build Windows images with Packer using WinRM communicator and PowerShell provisioners. Use when creating Windows AMIs, Azure images, or VMware templates.
Open skill - /push-to-registry
Push Packer build metadata to HCP Packer registry for tracking and managing image lifecycle. Use when integrating Packer builds with HCP Packer for version control and governance.
Open skill - /azure-verified-modules
Azure Verified Modules (AVM) requirements and best practices for developing certified Azure Terraform modules. Use when creating or reviewing Azure modules that need AVM certification.
Open skill - /terraform-search-import
Discover existing cloud resources using Terraform Search queries and bulk import them into Terraform management. Use when bringing unmanaged infrastructure under Terraform control, auditing cloud resources, or migrating to IaC.
Open skill

