
infrastructure-as-code
Use when writing Terraform for OCI, troubleshooting provider errors, managing state files, or implementing Resource Manager stacks. Covers terraform-provider-oci gotchas, resource lifecycle anti-patterns, state management mistakes, authentication issues, and OCI Landing Zones.
- Installs
- 99
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/acedergren/oci-agent-skills --skill infrastructure-as-code- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads infrastructure-as-code automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
OCI Infrastructure as Code - Expert Knowledge
🏗️ IMPORTANT: Use OCI Landing Zone Terraform Modules
Do NOT Reinvent the Wheel
❌ WRONG Approach:
# Writing Terraform from scratch for every resource
resource "oci_identity_compartment" "prod" { ... }
resource "oci_core_vcn" "main" { ... }
resource "oci_identity_policy" "policies" { ... }
# Result: Unmaintainable, inconsistent, no governance
✅ RIGHT Approach: Use Official OCI Landing Zone Terraform Modules
# Use official OCI Landing Zone modules
module "landing_zone" {
source = "oracle-terraform-modules/landing-zone/oci"
version = "~> 2.0"
# Infrastructure configuration
compartments_configuration = { ... }
network_configuration = { ... }
security_configuration = { ... }
}
Why Use Landing Zone Modules:
- ✅ Battle-tested: Thousands of OCI customers
- ✅ Compliant: CIS OCI Foundations Benchmark aligned
- ✅ Maintained: Oracle updates for API changes
- ✅ Comprehensive: Includes IAM, networking, security, logging
- ✅ Reusable: Consistent patterns across environments
Official Resources:
When to Write Custom Terraform (this skill's guidance):
- Application-specific resources not covered by landing zone
- Extending landing zone modules
- Special requirements not in reference architecture
⚠️ OCI CLI/API Knowledge Gap
You don't know OCI CLI commands or OCI API structure.
Your training data has limited and outdated knowledge of:
- OCI Terraform provider syntax (updates frequently)
- OCI API endpoints and resource schemas
- terraform-provider-oci specific arguments and data sources
- Resource Manager stack operations
- Latest provider features and breaking changes
When OCI operations are needed:
- Use exact Terraform examples from this skill's references
- Do NOT guess OCI provider resource arguments
- Do NOT assume AWS/Azure Terraform patterns work in OCI
- Reference landing-zones skill for module usage
What you DO know:
- General Terraform concepts and HCL syntax
- State management principles
- Infrastructure as Code best practices
This skill bridges the gap by providing current OCI-specific Terraform patterns and gotchas.
You are an OCI Terraform expert. This skill provides knowledge Claude lacks: provider-specific gotchas, state management anti-patterns, resource lifecycle traps, and OCI-specific IaC operational knowledge.
NEVER Do This
❌ NEVER hardcode OCIDs in Terraform (breaks portability)
# WRONG - breaks when moving between regions/compartments
resource "oci_core_instance" "web" {
compartment_id = "ocid1.compartment.oc1..aaaaaa..." # Hardcoded!
subnet_id = "ocid1.subnet.oc1.phx.bbbbbb..." # Hardcoded!
}
# RIGHT - use variables or data sources
resource "oci_core_instance" "web" {
compartment_id = var.compartment_ocid
subnet_id = data.oci_core_subnet.existing.id
}
❌ NEVER use preserve_boot_volume = true in dev/test (cost trap)
# WRONG - orphans boot volumes when instance destroyed ($50+/month per instance)
resource "oci_core_instance" "dev" {
preserve_boot_volume = true # Default behavior!
}
# RIGHT - explicit cleanup in dev/test
resource "oci_core_instance" "dev" {
preserve_boot_volume = false
}
Cost impact: Dev team with 10 test instances × $5/volume/month = $50/month wasted on orphaned volumes
❌ NEVER forget lifecycle blocks for critical resources
# WRONG - accidental destroy can delete production database
resource "oci_database_autonomous_database" "prod" {
# No protection!
}
# RIGHT - prevent accidental destruction
resource "oci_database_autonomous_database" "prod" {
lifecycle {
prevent_destroy = true
ignore_changes = [defined_tags] # Ignore tag changes from console
}
}
❌ NEVER mix regional and AD-specific resources (portability trap)
# WRONG - hardcoded AD breaks multi-region deployment
resource "oci_core_instance" "web" {
availability_domain = "fMgC:US-ASHBURN-AD-1" # Tenant-specific!
}
# RIGHT - query AD dynamically
data "oci_identity_availability_domains" "ads" {
compartment_id = var.tenancy_ocid
}
resource "oci_core_instance" "web" {
availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
}
❌ NEVER store state file in local filesystem for teams
# WRONG - no locking, no collaboration
terraform {
backend "local" {}
}
# RIGHT - use OCI Object Storage with locking
terraform {
backend "s3" {
bucket = "terraform-state"
key = "prod/terraform.tfstate"
region = "us-phoenix-1"
endpoint = "https://namespace.compat.objectstorage.us-phoenix-1.oraclecloud.com"
skip_region_validation = true
skip_credentials_validation = true
skip_metadata_api_check = true
use_path_style = true
}
}
❌ NEVER use count for resources that shouldn't be replaced on reorder
# WRONG - reordering list recreates ALL resources
resource "oci_core_instance" "web" {
count = length(var.instance_names)
display_name = var.instance_names[count.index]
}
# If instance_names changes from ["web1", "web2", "web3"] to ["web0", "web1", "web2", "web3"]
# Terraform RECREATES all instances!
# RIGHT - use for_each with stable keys
resource "oci_core_instance" "web" {
for_each = toset(var.instance_names)
display_name = each.value
}
OCI Provider Gotchas
Authentication Hierarchy (Often Confusing)
Provider authentication precedence:
- Explicit provider block credentials
TF_VAR_*environment variables~/.oci/configfile (DEFAULT profile)- Instance Principal (if
auth = "InstancePrincipal")
Common mistake: Setting environment variables but provider block overrides them silently.
Instance Principal for Terraform on OCI Compute
# In provider.tf
provider "oci" {
auth = "InstancePrincipal"
region = var.region
}
# Dynamic group matching rule:
# "ALL {instance.compartment.id = '<compartment-ocid>'}"
# IAM policy:
# "Allow dynamic-group terraform-instances to manage all-resources in tenancy"
Critical: Instance must be in dynamic group BEFORE Terraform runs, or authentication fails with cryptic error: "authorization failed or requested resource not found"
Resource Already Exists Errors
Error: 409-Conflict, Resource already exists
Cause: Resource exists in OCI but not in state file.
Solution:
# Import existing resource into state
terraform import oci_core_vcn.main ocid1.vcn.oc1.phx.xxxxx
# Then run plan/apply as normal
terraform plan
Prevention: Always use terraform import for existing infrastructure before managing with Terraform.
State Management Anti-Patterns
Problem: State Drift
Symptoms: Terraform wants to change/destroy resources that were modified outside Terraform (console, API, CLI).
Detection:
terraform plan # Shows unexpected changes
terraform show # Compare state to actual infrastructure
Solutions:
Option 1: Refresh state (safe)
terraform refresh # Updates state to match reality
Option 2: Import changes (if new resources)
terraform import <resource_type>.<name> <ocid>
Option 3: Ignore changes in lifecycle
lifecycle {
ignore_changes = [defined_tags, freeform_tags] # Ignore console tag edits
}
Problem: State File Corruption
Symptoms: terraform plan fails with "state file corrupted" or "version mismatch"
Recovery:
# 1. Make backup
cp terraform.tfstate terraform.tfstate.backup
# 2. Try state repair
terraform state pull > recovered.tfstate
mv recovered.tfstate terraform.tfstate
# 3. If that fails, restore from Object Storage versioning
# Or reconstruct with imports (last resort)
Prevention: Use Object Storage backend with versioning enabled
Resource Lifecycle Traps
Destroy Failures (Common with Dependencies)
Error: Resource still in use
Example: Can't destroy VCN because subnet still exists, can't destroy subnet because instances still attached.
Solution:
# 1. Visualize dependencies
terraform graph | dot -Tpng > graph.png
# 2. Destroy in reverse order
terraform destroy -target=oci_core_instance.web
terraform destroy -target=oci_core_subnet.private
terraform destroy -target=oci_core_vcn.main
# Or use depends_on explicitly:
resource "oci_core_vcn" "main" {
# ...
}
resource "oci_core_subnet" "private" {
vcn_id = oci_core_vcn.main.id
# depends_on is implicit via vcn_id reference
}
Timeouts for Long-Running Resources
# Database provisioning takes 15-30 minutes
resource "oci_database_autonomous_database" "prod" {
# ... configuration ...
timeouts {
create = "60m" # Default 20m often not enough
update = "60m"
delete = "30m"
}
}
# Compute instance usually fast, but can timeout on capacity issues
resource "oci_core_instance" "web" {
# ... configuration ...
timeouts {
create = "30m" # Allow retries on "out of capacity"
}
}
OCI Landing Zones
What: Pre-built Terraform templates for enterprise OCI architectures
Repository: github.com/oracle-quickstart/oci-landing-zones
Use when:
- Starting new OCI tenancy (greenfield)
- Need CIS OCI Foundations Benchmark compliance
- Want security-hardened baseline
- Multi-environment (dev/test/prod) setup
DON'T use when:
- Brownfield (existing infrastructure) - too opinionated
- Simple single-app deployment - overkill
Key patterns:
- Hub-and-spoke networking
- Centralized logging/monitoring
- Security zones and bastion hosts
- IAM baseline with groups/policies
Cost Optimization for IaC
Use Flex Shapes (50% savings)
# EXPENSIVE - fixed shape
resource "oci_core_instance" "web" {
shape = "VM.Standard2.4" # 4 OCPUs, 60GB RAM, $218/month
}
# CHEAPER - flexible shape
resource "oci_core_instance" "web" {
shape = "VM.Standard.E4.Flex"
shape_config {
ocpus = 4
memory_in_gbs = 60
}
# Cost: (4 × $0.03 + 60 × $0.0015) × 730 = $153/month (30% savings)
}
Tag Everything for Cost Tracking
# Define locals for consistent tagging
locals {
common_tags = {
"CostCenter" = "Engineering"
"Environment" = var.environment
"ManagedBy" = "Terraform"
"Project" = var.project_name
}
}
resource "oci_core_instance" "web" {
freeform_tags = merge(
local.common_tags,
{
"Component" = "WebServer"
}
)
}
Benefit: Cost reporting by CostCenter, Environment, Project in OCI Console
Progressive Loading References
OCI Terraform Patterns
WHEN TO LOAD oci-terraform-patterns.md:
- Setting up provider configuration (multi-region, auth methods)
- Resource Manager stack operations via CLI
- Common resource patterns (VCN, compute, ADB)
- State management with Object Storage backend
- Landing Zone module usage examples
Do NOT load for:
- Quick provider gotchas (NEVER list above)
- Understanding when to use Landing Zone (covered above)
- Lifecycle management patterns (covered above)
When to Use This Skill
- Writing Terraform: provider configuration, resource dependencies, lifecycle
- State management: drift, corruption, import/export
- Troubleshooting: authentication failures, "resource already exists", destroy failures
- OCI Landing Zones: when to use, how to customize
- Cost optimization: Flex shapes, tagging strategies
- Production: prevent_destroy, ignore_changes, timeouts
FAQ
What does the infrastructure-as-code skill do?
Use when writing Terraform for OCI, troubleshooting provider errors, managing state files, or implementing Resource Manager stacks. Covers terraform-provider-oci gotchas, resource lifecycle anti-patterns, state management mistakes, authentication issues, and OCI Landing Zones.
How do I install infrastructure-as-code?
Run npx skills add https://github.com/acedergren/oci-agent-skills --skill infrastructure-as-code in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/infrastructure-as-code/ (personal) or .claude/skills/infrastructure-as-code/ (project).
Which AI agents can use infrastructure-as-code?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is infrastructure-as-code safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains infrastructure-as-code?
It is published by acedergren in acedergren/oci-agent-skills. It has 99 recorded installs.
More from acedergren/oci-agent-skills
monitoring-operations
acedergren/oci-agent-skills
Use when setting up metrics, alarms, or troubleshooting missing data in OCI Monitoring. Covers metric namespace confusion, alarm threshold gotchas, log collection setup, and common monitoring gaps.
oracle-dba
acedergren/oci-agent-skills
Open the skill to read its SKILL.md instructions.
networking-management
acedergren/oci-agent-skills
Open the skill to read its SKILL.md instructions.
best-practices
acedergren/oci-agent-skills
Open the skill to read its SKILL.md instructions.
compute-management
acedergren/oci-agent-skills
Open the skill to read its SKILL.md instructions.
database-management
acedergren/oci-agent-skills
Open the skill to read its SKILL.md instructions.
Popular devops & cloud skills
microsoft-foundry
microsoft/azure-skills
Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent create, managed harness agent create, GitHub Copilot harness agent, create agent, update agent, add tool to agent, invoke agent, agent insights, evaluate agent, batch eval, continuous eval, continuous monitoring, agent CI/CD, optimize prompt, improve prompt, optimize agent instructions, Agent Optimizer scaffold, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure
azure-diagnostics
microsoft/azure-skills
Debug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe triage. WHEN: debug production issues, troubleshoot app service, app service high CPU, app service deployment failure, troubleshoot container apps, container app 503 or target port mismatch, troubleshoot functions, function telemetry missing or stopped after a config/connection-string change, troubleshoot AKS, VM RDP, Linux SSH, VM black screen, can't connect to VM, reset VM password, NSG or firewall blocking, kubectl cannot connect, kube-system/CoreDNS failures, pod pending, crashloop, node not ready, upgrade failures, analyze logs, KQL, insights, image pull failures, cold start issues, health probe failures, resource health, root cause of errors, troubleshoot event hubs, troubleshoot service bus, messaging SDK error, AMQP connection failure, message lock lost, lock renewal during long-running processing, service bus dead letter.
azure-prepare
microsoft/azure-skills
Prepare azd-based Azure projects for deployment: generates azure.yaml, infrastructure (Bicep/Terraform), and Dockerfiles for the Azure Developer CLI (azd) workflow. USE ONLY when the user explicitly wants to use azd as the deployment tool, or the project already has an azure.yaml file. DO NOT USE FOR: non-azd deployments, Python App Service code-only deploys (use python-appservice-deploy), or cross-cloud migration (use azure-cloud-migrate). WHEN: prepare app for azd, create azure.yaml, set up azd infrastructure, modernize app for Azure with azd, deploy with azd, function app, timer trigger, service bus trigger, event-driven function, managed identity, generate Bicep, generate Terraform, create and deploy to Azure.
azure-ai
microsoft/azure-skills
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
azure-deploy
microsoft/azure-skills
Execute Azure deployments for ALREADY-PREPARED applications that have existing .azure/deployment-plan.md and infrastructure files. DO NOT use this skill when the user asks to CREATE a new application — use azure-prepare instead. This skill runs azd up, azd deploy, terraform apply, and az deployment commands with built-in error recovery. Requires .azure/deployment-plan.md from azure-prepare and validated status from azure-validate. WHEN: "run azd up", "run azd deploy", "execute deployment", "push to production", "push to cloud", "go live", "ship it", "bicep deploy", "terraform apply", "publish to Azure", "launch on Azure". DO NOT USE WHEN: "create and deploy", "build and deploy", "create a new app", "set up infrastructure", "create and deploy to Azure using Terraform" — use azure-prepare for these.
azure-validate
microsoft/azure-skills
Pre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure (Bicep or Terraform), RBAC role assignments, managed identity permissions, and prerequisites before deploying. WHEN: validate my app, check deployment readiness, run preflight checks, verify configuration, check if ready to deploy, validate azure.yaml, validate Bicep, test before deploying, troubleshoot deployment errors, validate Azure Functions, validate function app, validate serverless deployment, verify RBAC roles, check role assignments, review managed identity permissions, what-if analysis, validate Container Apps deployment.