Back to skills
SKILL.md
Terraform Network
ASecurityExpert coverage of Terraform network infrastructure automation: network providers (ACI, Meraki, PAN-OS, FortiOS, F5 BIG-IP), state management, plan/apply workflow, modules, remote state, and CI/CD integration for network IaC. Use for \"Terraform network\", \"Terraform ACI\", \"Terraform Meraki\", \"Terraform PAN-OS\", \"Terraform FortiOS\", \"Terraform F5\", \"Terraform provider network\", \"HCL network\", \"terraform plan network\". Do NOT use for cross-vendor comparison, platform selection,...
- 4 stars
- 0 votes
- 0 copies
- 0 views
- Added September 24, 2026
Works with
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add chrishuffman5/domain-expert --skill terraform-network --agent claude-codeAre you the author of Terraform Network?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-terraform-network)---
name: terraform-network
description: "Expert coverage of Terraform network infrastructure automation: network providers (ACI, Meraki, PAN-OS, FortiOS, F5 BIG-IP), state management, plan/apply workflow, modules, remote state, and CI/CD integration for network IaC. Use for \"Terraform network\", \"Terraform ACI\", \"Terraform Meraki\", \"Terraform PAN-OS\", \"Terraform FortiOS\", \"Terraform F5\", \"Terraform provider network\", \"HCL network\", \"terraform plan network\". Do NOT use for cross-vendor comparison, platform selection, or category-wide architecture -- use the `network-automation` skill. Do NOT use for general-purpose Terraform (cloud infrastructure, state, modules, HCL language questions not targeting a network-device provider) -- that's the `terraform` skill (in the `devops` plugin)."
license: MIT
---
# Terraform Network Automation
This skill covers Terraform for network infrastructure automation across all supported provider versions. Areas of expertise include:
- Core Terraform workflow (init, plan, apply, destroy) applied to network infrastructure
- Network providers: CiscoDevNet/aci, cisco-open/meraki, paloaltonetworks/panos, fortiosapi/fortios, F5Networks/bigip
- State management for network resources (remote state, locking, state operations)
- Module design for reusable network infrastructure (VLAN modules, EPG modules, firewall rule modules)
- CI/CD integration (terraform plan in PR, terraform apply on merge)
- Drift detection via terraform plan
- Import of existing network resources into Terraform state
## How to Approach Tasks
1. **Classify** the request:
- **Provider usage** -- Identify the network platform and load provider documentation patterns
- **Architecture** -- Load `references/architecture.md` for provider details, state management, modules
- **State management** -- Apply remote state, locking, and state operation best practices
- **CI/CD** -- Design pipeline with plan/review/apply workflow
- **Migration** -- Import existing resources, or migrate between Terraform versions
2. **Identify the target platform** -- Which network provider (ACI, Meraki, PAN-OS, FortiOS, F5)? This determines the provider, resource types, and API interactions.
3. **Load context** -- Read the reference file for deep knowledge.
4. **Analyze** -- Apply Terraform network-specific reasoning. Network resources are stateful and often production-critical; plan/review/apply discipline is essential.
5. **Recommend** -- Provide complete, runnable HCL examples with provider configuration, resources, and variables.
6. **Verify** -- Suggest validation steps (terraform plan review, post-apply verification, state inspection).
## Core Workflow for Network
### Plan/Apply Discipline
Network infrastructure demands extra caution with Terraform:
```bash
terraform init # Download providers, initialize backend
terraform plan # Show what will change (ALWAYS review for network)
terraform apply # Apply after human review of plan
```
**Critical rule:** Never use `terraform apply -auto-approve` for production network changes without prior `terraform plan` review in CI.
### Destroy Caution
`terraform destroy` removes all managed resources. For network infrastructure:
- Destroying a tenant, VRF, or VLAN can cause production outages
- Use `terraform state rm` to stop managing a resource without deleting it
- Use `lifecycle { prevent_destroy = true }` on critical resources
- Never run `terraform destroy` on production without explicit change approval
## Provider Reference
### CiscoDevNet/aci (Cisco ACI)
Best suited for ACI fabric automation (tenants, VRFs, BDs, EPGs, contracts):
```hcl
provider "aci" {
username = var.aci_username
password = var.aci_password
url = "https://apic.example.com"
insecure = true # Skip TLS verify for lab; use certs in production
}
resource "aci_tenant" "prod" {
name = "PROD"
description = "Production Tenant"
}
resource "aci_vrf" "prod_vrf" {
tenant_dn = aci_tenant.prod.id
name = "PROD_VRF"
}
resource "aci_bridge_domain" "app_bd" {
tenant_dn = aci_tenant.prod.id
name = "APP_BD"
relation_fv_rs_ctx = aci_vrf.prod_vrf.id
}
resource "aci_application_profile" "app" {
tenant_dn = aci_tenant.prod.id
name = "APP_PROFILE"
}
resource "aci_application_epg" "web_epg" {
application_profile_dn = aci_application_profile.app.id
name = "WEB_EPG"
relation_fv_rs_bd = aci_bridge_domain.app_bd.id
}
```
### cisco-open/meraki (Cisco Meraki)
Cloud-managed network resources via Meraki Dashboard API:
```hcl
provider "meraki" {
api_key = var.meraki_api_key
}
resource "meraki_networks_vlans" "office_vlans" {
network_id = var.network_id
id = 10
name = "CORP_USERS"
subnet = "192.168.10.0/24"
appliance_ip = "192.168.10.1"
}
```
### paloaltonetworks/panos (Palo Alto PAN-OS)
Firewall policy, objects, NAT, and security profiles:
```hcl
provider "panos" {
hostname = var.panos_hostname
username = var.panos_username
password = var.panos_password
}
resource "panos_address_object" "web_servers" {
name = "WEB_SERVERS"
type = "ip-netmask"
value = "10.10.10.0/24"
}
resource "panos_security_policy" "allow_web" {
rule {
name = "ALLOW_WEB_OUT"
source_zones = ["trust"]
destination_zones = ["untrust"]
applications = ["web-browsing", "ssl"]
services = ["application-default"]
source_addresses = [panos_address_object.web_servers.name]
destination_addresses = ["any"]
action = "allow"
}
}
```
### fortiosapi/fortios (FortiGate FortiOS)
FortiGate firewall and SD-WAN configuration:
```hcl
provider "fortios" {
hostname = var.fortigate_ip
token = var.fortigate_api_token
insecure = false
}
resource "fortios_firewall_address" "internal_net" {
name = "INTERNAL_NET"
type = "ipmask"
subnet = "10.0.0.0 255.0.0.0"
comment = "Internal networks"
}
```
### F5Networks/bigip (F5 BIG-IP)
Load balancer nodes, pools, virtual servers:
```hcl
provider "bigip" {
address = "https://192.168.1.1"
username = "admin"
password = var.bigip_password
}
resource "bigip_ltm_node" "app_node" {
name = "/Common/app-server-1"
address = "192.168.10.11"
}
resource "bigip_ltm_pool" "app_pool" {
name = "/Common/APP_POOL"
load_balancing_mode = "least-connections-member"
monitors = ["/Common/http"]
}
resource "bigip_ltm_pool_attachment" "app_member" {
pool = bigip_ltm_pool.app_pool.name
node = "/Common/app-server-1:80"
}
```
## State Management
### Remote State (Required for Teams)
```hcl
terraform {
backend "s3" {
bucket = "network-terraform-state"
key = "production/aci/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
```
**State locking**: DynamoDB table prevents concurrent applies. Essential for team environments where multiple engineers might run Terraform simultaneously.
### State File Organization
Organize state per environment and per platform:
```
states/
├── production/
│ ├── aci/terraform.tfstate
│ ├── meraki/terraform.tfstate
│ ├── panos/terraform.tfstate
│ └── f5/terraform.tfstate
└── lab/
├── aci/terraform.tfstate
└── panos/terraform.tfstate
```
Each state file should contain related resources. Do not put all network resources in one state file (blast radius too large).
### State Operations
```bash
# List resources in state
terraform state list
# Show specific resource
terraform state show aci_tenant.prod
# Remove resource from state (stop managing, do not delete)
terraform state rm aci_application_epg.legacy_epg
# Import existing resource into state
terraform import aci_tenant.existing_tenant uni/tn-EXISTING
# Move resource between states (refactoring)
terraform state mv aci_vrf.prod aci_vrf.production
```
## Module Design
### Reusable Network Module Example
```hcl
# modules/aci_epg/main.tf
variable "tenant_name" { type = string }
variable "app_profile_name" { type = string }
variable "epg_name" { type = string }
variable "bd_name" { type = string }
variable "vrf_name" { type = string }
resource "aci_application_epg" "epg" {
application_profile_dn = "uni/tn-${var.tenant_name}/ap-${var.app_profile_name}"
name = var.epg_name
relation_fv_rs_bd = "uni/tn-${var.tenant_name}/BD-${var.bd_name}"
}
output "epg_dn" {
value = aci_application_epg.epg.id
}
```
Usage:
```hcl
module "web_epg" {
source = "./modules/aci_epg"
tenant_name = "PROD"
app_profile_name = "WEB_APP"
epg_name = "WEB_EPG"
bd_name = "WEB_BD"
vrf_name = "PROD_VRF"
}
```
### for_each for Bulk Resources
```hcl
variable "vlans" {
type = map(object({
name = string
subnet = string
}))
default = {
"10" = { name = "MGMT", subnet = "10.0.10.0/24" }
"20" = { name = "USERS", subnet = "10.0.20.0/24" }
"30" = { name = "VOICE", subnet = "10.0.30.0/24" }
}
}
resource "meraki_networks_vlans" "vlans" {
for_each = var.vlans
network_id = var.network_id
id = each.key
name = each.value.name
subnet = each.value.subnet
appliance_ip = cidrhost(each.value.subnet, 1)
}
```
## NetBox Integration
Query NetBox as source of truth and drive Terraform resources:
```hcl
data "http" "netbox_devices" {
url = "${var.netbox_url}/api/dcim/devices/?site=NYC&status=active"
request_headers = {
Authorization = "Token ${var.netbox_token}"
}
}
locals {
devices = jsondecode(data.http.netbox_devices.response_body).results
device_map = { for d in local.devices : d.name => d }
}
# Use NetBox data to drive resource creation
resource "aci_application_epg" "device_epgs" {
for_each = local.device_map
application_profile_dn = aci_application_profile.app.id
name = "${each.key}_EPG"
}
```
## Common Pitfalls
1. **terraform apply -auto-approve in production** -- Never auto-approve network changes. A bad plan applied automatically can disconnect production networks. Always review the plan.
2. **Single state file for everything** -- One massive state file means any `terraform apply` can affect any resource. Split by platform, environment, and functional area.
3. **Not using lifecycle prevent_destroy** -- Critical network resources (tenants, VRFs, core policies) should have `prevent_destroy = true` to prevent accidental deletion.
4. **Ignoring provider version pinning** -- Provider updates can change resource behavior. Pin provider versions in `required_providers` block.
5. **State file in Git** -- Never commit `terraform.tfstate` to Git. It contains sensitive data (API keys, passwords). Use remote state backends.
6. **Destroying before understanding dependencies** -- Network resources have dependencies (EPG depends on BD, BD depends on VRF). Terraform handles ordering, but understanding the dependency graph prevents surprises.
7. **Importing without planning** -- When importing existing resources, always `terraform plan` after import to verify Terraform's understanding matches reality. Adjust HCL until plan shows no changes.
8. **No remote state locking** -- Without locking, concurrent applies corrupt state. Always configure state locking (DynamoDB for S3, blob lease for Azure).
## Reference Files
Load these when you need deep knowledge:
- `references/architecture.md` -- Provider details, state management, plan/apply workflow, modules, NetBox integration patterns. Read for "how does X work" architecture questions.
Files in this skill
- SKILL.md
- references/architecture.md
Attribution
Comments
Loading comments…