
Oma Tf Infra
- 124 installs
- 41 repo stars
- Updated August 4, 2026
- gracefullight/stock-checker
Provision and maintain stock-checker cloud resources with Terraform—modules, environments, IAM, networking, and safe plan/apply loops for oma-tf-infra layouts.
About
oma-tf-infra encodes gracefullight/stock-checker infrastructure as code: VPC and compute, databases, secrets, CI deploy hooks, and environment-specific variables. Agents use it to propose scoped Terraform changes, validate plans, and document blast radius before production applies.
- Terraform module conventions
- Per-environment workspaces
- IAM least-privilege patterns
- Plan/apply safety checks
- State backend and drift handling
Oma Tf Infra by the numbers
- 124 all-time installs (skills.sh)
- Ranked #531 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/gracefullight/stock-checker --skill oma-tf-infraAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 124 |
|---|---|
| repo stars | ★ 41 |
| Last updated | August 4, 2026 |
| Repository | gracefullight/stock-checker ↗ |
What it does
Provision and maintain stock-checker cloud resources with Terraform—modules, environments, IAM, networking, and safe plan/apply loops for oma-tf-infra layouts.
Files
TF Infra Agent - Infrastructure-as-Code Specialist
Scheduling
Goal
Design, implement, review, and document Terraform-based infrastructure across cloud providers with secure state, least privilege, cost awareness, continuity, and policy/testing controls.
Intent signature
- User asks for Terraform, IaC, cloud provisioning, state, IAM/OIDC, networking, storage, compute, databases, CDN, policy-as-code, cost optimization, drift, or terraform plan review.
- User needs infrastructure controls for AI systems, continuity, or architecture documentation.
When to use
- Provisioning infrastructure on any cloud provider (AWS, GCP, Azure, OCI)
- Creating or modifying Terraform configurations for compute, databases, storage, networking
- Configuring CI/CD authentication (OIDC, workload identity, IAM roles)
- Setting up CDN, load balancers, object storage, message queues
- Reviewing terraform plan output before apply
- Troubleshooting Terraform state or resource issues
- Migrating from manual console changes to Terraform
- Implementing infrastructure controls for AI systems (ISO/IEC 42001)
- Designing continuity-oriented infrastructure (ISO 22301)
- Producing architecture documentation (ISO/IEC/IEEE 42010)
When NOT to use
- Database schema design or query tuning -> use DB Agent
- Backend API implementation -> use Backend Agent
- CI/CD pipeline code (non-infrastructure) -> use Dev Workflow
- Security/compliance audit -> use QA Agent
Expected inputs
- Cloud provider, environment, Terraform scope, desired resources, and state/backend context
- Existing
.tf,.tfvars, modules, provider versions, CI/CD auth, plan output, or drift symptoms - Security, cost, continuity, policy, tagging, and documentation constraints
Expected outputs
- Terraform code, module changes, review findings, plan analysis, or architecture/control documentation
- Validation, formatting, plan, and policy/security scan results when applicable
- Explicit risks around state, secrets, drift, destructive changes, and cost
Dependencies
- Terraform CLI, provider CLIs/config, remote state backend, and policy/security scanners
resources/multi-cloud-examples.md, cost guide, policy/testing examples, ISO infra guide, and checklist
Control-flow features
- Branches by provider, environment, state backend, destructive risk, policy scan result, and plan/apply intent
- Reads and writes Terraform files; may run local Terraform/process commands
- Must not apply/destroy production infrastructure without explicit confirmation and backup awareness
Structural Flow
Entry
1. Detect provider and environment from project context. 2. Identify state backend, module boundaries, resources, and risk level. 3. Determine whether task is design, implementation, review, plan analysis, or remediation.
Scenes
1. PREPARE: Load Terraform scope, provider, environment, and constraints. 2. ACQUIRE: Read HCL, modules, state/backend config, CI/CD auth, and plan output. 3. REASON: Design resources, IAM, networking, state, cost, and continuity tradeoffs. 4. ACT: Write or review HCL, modules, variables, outputs, and docs. 5. VERIFY: Run fmt, validate, plan, scans, and policy checks when available. 6. FINALIZE: Report diff, plan risk, validation status, and next apply steps.
Transitions
- If provider is unclear, detect from HCL before writing.
- If state is local or unprotected, prioritize remote state guidance.
- If plan includes destructive changes, stop for explicit review.
- If production apply/destroy is requested, require confirmation and backup/rollback notes.
Failure and recovery
- If credentials are unavailable, produce static review or code changes only.
- If plan cannot run, report the missing provider/backend/credential blocker.
- If policy/security scan fails, fix or report concrete remediation.
Exit
- Success: Terraform change or review is validated and risk-scoped.
- Partial success: unavailable credentials/tools or unreviewed apply risk is explicit.
Logical Operations
Actions
| Action | SSL primitive | Evidence |
|---|---|---|
| Detect provider and scope | READ | HCL, providers, modules |
| Select cloud/resource mapping | SELECT | Multi-cloud mapping |
| Write Terraform | WRITE | .tf, .tfvars, modules |
| Validate HCL | CALL_TOOL | terraform fmt, validate, plan |
| Compare plan risk | COMPARE | Plan output and drift |
| Infer cost/security/continuity risks | INFER | Policy, ISO, cost guides |
| Report result | NOTIFY | Final infra summary |
Tools and instruments
- Terraform CLI and provider ecosystem
- Checkov, tfsec, OPA/Sentinel, Terratest when applicable
- Cost, policy, multi-cloud, and ISO resource guides
Canonical command path
terraform fmt -recursive
terraform validate
terraform plan -out=tfplanRun scanners when available before any apply:
checkov -d .
tfsec .Resource scope
| Scope | Resource target |
|---|---|
CODEBASE | Terraform modules, variables, outputs, CI config |
LOCAL_FS | Plans, state config, documentation |
PROCESS | Terraform, scanner, and policy commands |
CREDENTIALS | Cloud provider auth and state backend credentials |
NETWORK | Cloud APIs and remote state backends |
Preconditions
- Terraform scope and provider can be determined.
- Required credentials are present for live plan/apply, or static mode is acceptable.
Effects and side effects
- Mutates infrastructure code and documentation.
- May produce plans that imply cloud resource creation, mutation, or destruction.
- Should not directly apply/destroy without explicit user authorization.
Guardrails
1. Provider-Agnostic: Always detect cloud provider from project context before writing any HCL 2. Remote State: Store Terraform state in remote backend (S3, GCS, Azure Blob) with versioning and locking 3. OIDC First: Use OIDC/IAM roles for CI/CD authentication instead of long-lived credentials 4. Plan Before Apply: Always run terraform validate, terraform fmt, terraform plan before apply 5. Least Privilege: IAM policies must follow least privilege; never use overly permissive policies 6. Tag Everything: Apply Environment, Project, Owner, CostCenter tags/labels to all taggable resources 7. No Secrets in Code: Never hardcode passwords, API keys, or tokens in .tf files; use provider secret management 8. Composable Modules: Design reusable modules with clear interfaces; avoid monolithic modules 9. Environment Sizing: Use environment-based sizing (smaller for dev/staging, production-grade for prod) 10. Policy as Code: Run OPA/Sentinel and security scanning (Checkov, tfsec) in CI/CD before apply 11. Version Pinning: Version pin all providers and modules; use for_each over count (never count with computed values) 12. Cost Awareness: Implement lifecycle policies, autoscaling schedules, and review cost estimates before apply 13. No Auto-Approve: Never use auto-approve in production; never terraform destroy without backup/confirmation 14. Drift Detection: Never skip drift detection in production; address deprecation warnings from providers 15. AI Systems: Document IAM, logging, encryption, monitoring, and retention controls; prefer private connectivity; limit to infrastructure controls (note when policy/process work belongs elsewhere) 16. Continuity: Document backup, failover, dependency visibility, and restore validation with target RTO/RPO (not backup-only) 17. Architecture Documentation: Capture stakeholders, concerns, views, interfaces, constraints, and decisions (not a compliance checkbox; improve communication and traceability)
Cloud Provider Detection
| Indicator | Provider |
|---|---|
provider "google" or google_* resources | GCP |
provider "aws" or aws_* resources | AWS |
provider "azurerm" or azurerm_* resources | Azure |
provider "oci" or oci_* resources | Oracle Cloud |
Multi-Cloud Resource Mapping
| Concept | AWS | GCP | Azure | Oracle (OCI) |
|---|---|---|---|---|
| Container Platform | ECS Fargate | Cloud Run | Container Apps | Container Instances |
| Managed Kubernetes | EKS | GKE | AKS | OKE |
| Managed Database | RDS | Cloud SQL | Azure SQL | Autonomous DB |
| Cache/In-Memory | ElastiCache | Memorystore | Azure Cache | OCI Cache |
| Object Storage | S3 | GCS | Blob Storage | Object Storage |
| Queue/Messaging | SQS/SNS | Pub/Sub | Service Bus | OCI Streaming |
| Task Queue | N/A | Cloud Tasks | Queue Storage | N/A |
| CDN | CloudFront | Cloud CDN | Front Door | OCI CDN |
| Load Balancer | ALB/NLB | Cloud Load Balancing | Load Balancer | OCI Load Balancer |
| IAM Role | IAM Role | Service Account | Managed Identity | Dynamic Group |
| Secrets | Secrets Manager | Secret Manager | Key Vault | OCI Vault |
| VPC | VPC | VPC | Virtual Network | VCN |
| Serverless Function | Lambda | Cloud Functions | Functions | OCI Functions |
References
Follow resources/execution-protocol.md step by step. See resources/examples.md for input/output examples. Use resources/multi-cloud-examples.md for provider-specific HCL patterns. Use resources/cost-optimization.md for cost reduction strategies. Use resources/policy-testing-examples.md for OPA, Sentinel, and Terratest patterns. Use resources/iso-42001-infra.md for AI governance, continuity, and architecture controls. Before submitting, run resources/checklist.md. Vendor-specific execution protocols are injected automatically by oma agent:spawn. Source files live under ../_shared/runtime/execution-protocols/{vendor}.md.
- Execution steps:
resources/execution-protocol.md - Self-check:
resources/checklist.md - Examples:
resources/examples.md - Multi-cloud HCL patterns:
resources/multi-cloud-examples.md - Cost optimization:
resources/cost-optimization.md - Policy & testing:
resources/policy-testing-examples.md - ISO controls:
resources/iso-42001-infra.md - Error recovery:
resources/error-playbook.md - Context loading:
../_shared/core/context-loading.md - Reasoning templates:
../_shared/core/reasoning-templates.md - Clarification:
../_shared/core/clarification-protocol.md - Context budget:
../_shared/core/context-budget.md - Difficulty assessment:
../_shared/core/difficulty-guide.md - Lessons learned:
../_shared/core/lessons-learned.md - Observability handoff:
../oma-observability/SKILL.md§Integrations — Collector topology, transport tuning, release metadata
Knowledge Reference
terraform, infrastructure-as-code, iac, cloud, aws, gcp, azure, oracle, oci, multi-cloud, devops, provisioning, infrastructure, compute, database, storage, networking, iam, oidc, workload identity, container, kubernetes, serverless, vpc, subnet, load balancer, cdn, secrets management, state management, backend, provider
TF Infra Agent: Self-Verification Checklist
Configuration
- [ ]
terraform validatepasses without errors - [ ]
terraform fmtapplied (consistent formatting) - [ ] Provider and module versions pinned in
versions.tf - [ ] Remote backend configured with state locking and encryption
Security
- [ ] No secrets, passwords, or API keys in .tf files
- [ ]
terraform.tfvarsexcluded from git - [ ] IAM policies follow least privilege
- [ ] OIDC/workload identity used for CI/CD (no long-lived credentials)
- [ ] Sensitive outputs marked with
sensitive = true - [ ] Encryption at rest enabled for storage and databases
- [ ] Network boundaries defined (security groups, firewall rules)
Naming & Tags
- [ ] Consistent naming convention using
localsblock - [ ] All taggable resources include: Environment, Project, Owner, CostCenter
- [ ] Resource names match project patterns
Resource Design
- [ ]
for_eachused overcountfor resource collections - [ ]
countnot used with computed values that could cause recreation - [ ]
depends_onset for explicit ordering where needed - [ ] Modules are composable with clear interfaces
- [ ] No monolithic modules doing too many things
- [ ] Environment-based sizing (smaller for dev/staging)
Operations Safety
- [ ] No
auto-approvein production environments - [ ] No
terraform destroywithout explicit backup/confirmation - [ ] Drift detection not skipped in production
- [ ] Provider deprecation warnings addressed
- [ ] State files not stored locally in team environments
Cost
- [ ] Cost impact reviewed via
terraform plan - [ ] Storage lifecycle rules configured
- [ ] Autoscaling schedules set for off-hours scaling
- [ ] Reserved Instances / Savings Plans considered for production
Policy & Testing
- [ ] Policy checks (OPA/Sentinel) pass
- [ ] Security scanning (Checkov/tfsec) clean
- [ ] Critical modules have integration tests
Compliance (when applicable)
- [ ] AI systems: IAM, logging, encryption, monitoring, retention controls documented
- [ ] Continuity: RTO/RPO, failover, backup, restore assumptions documented
- [ ] Architecture: stakeholders, concerns, views, rationale captured
Cost Optimization Examples
Terraform patterns for optimizing cloud infrastructure costs across AWS, GCP, and Azure.
Environment-Based Resource Sizing
Dynamically size resources based on environment to reduce non-production costs.
# locals.tf
locals {
# Instance sizing by environment
instance_sizes = {
production = "t3.large"
staging = "t3.medium"
development = "t3.micro"
}
# Database sizing by environment
db_instance_classes = {
production = "db.r5.xlarge"
staging = "db.t3.medium"
development = "db.t3.micro"
}
# Enable HA only in production
enable_multi_az = var.environment == "production" ? true : false
enable_backups = var.environment == "production" ? true : false
}
# Compute resource with environment-based sizing
resource "aws_instance" "app" {
instance_type = local.instance_sizes[var.environment]
# ...
}
# Database with environment-based sizing
resource "aws_db_instance" "main" {
instance_class = local.db_instance_classes[var.environment]
multi_az = local.enable_multi_az
# ...
}Reserved Instances & Savings Plans
AWS Reserved Instances
# Data source for Reserved Instance offerings
data "aws_ec2_instance_type_offerings" "available" {
filter {
name = "instance-type"
values = ["t3.medium", "t3.large"]
}
}
# Note: Reserved Instances are purchased via Console or API, not Terraform
# Use tags to track RI-eligible resources
resource "aws_instance" "app" {
instance_type = "t3.medium"
tags = {
Name = "app-server"
RIEligible = "true"
Environment = "production"
}
}GCP Committed Use Discounts (CUDs)
# Committed use discount for predictable workloads
resource "google_compute_resource_policy" "cud" {
name = "cud-policy"
region = var.region
group_placement_policy {
availability_domain_count = 1
}
}
# Note: CUDs are purchased in console, tag resources for tracking
resource "google_compute_instance" "app" {
machine_type = "n2-standard-4"
labels = {
cud_eligible = "true"
}
}Azure Reserved VM Instances
# Note: Reserved Instances are purchased separately
# Tag resources for RI tracking
resource "azurerm_linux_virtual_machine" "app" {
size = "Standard_D4s_v3"
tags = {
RIEligible = "true"
}
}Spot/Preemptible Instances
For fault-tolerant workloads, use spot instances for up to 90% savings.
AWS Spot Instances
resource "aws_launch_template" "spot" {
name_prefix = "spot-"
image_id = data.aws_ami.amazon_linux.id
instance_type = "t3.medium"
# Spot instance configuration
instance_market_options {
market_type = "spot"
spot_options {
max_price = "0.05" # Maximum spot price willing to pay
spot_instance_type = "one-time"
}
}
}
resource "aws_autoscaling_group" "spot" {
name = "spot-asg"
vpc_zone_identifier = var.private_subnets
target_group_arns = [aws_lb_target_group.app.arn]
health_check_type = "ELB"
min_size = 1
max_size = 10
desired_capacity = 3
launch_template {
id = aws_launch_template.spot.id
version = "$Latest"
}
# Mixed instances policy for spot diversification
mixed_instances_policy {
launch_template {
launch_template_specification {
launch_template_id = aws_launch_template.spot.id
}
override {
instance_type = "t3.medium"
}
override {
instance_type = "t3a.medium"
}
override {
instance_type = "m5.medium"
}
}
instances_distribution {
on_demand_base_capacity = 1
on_demand_percentage_above_base_capacity = 0
spot_allocation_strategy = "capacity-optimized"
}
}
}GCP Preemptible VMs
resource "google_compute_instance" "worker" {
name = "worker"
machine_type = "n2-standard-4"
zone = var.zone
scheduling {
preemptible = true
automatic_restart = false
}
# Spot VM (newer term for preemptible)
resource_policies = [google_compute_resource_policy.spot.id]
}
resource "google_compute_resource_policy" "spot" {
name = "spot-policy"
region = var.region
instance_schedule_policy {
vm_start_schedule {
schedule = "0 8 * * MON-FRI"
}
vm_stop_schedule {
schedule = "0 20 * * MON-FRI"
}
time_zone = "America/New_York"
}
}Azure Spot VMs
resource "azurerm_linux_virtual_machine" "spot" {
name = "spot-vm"
resource_group_name = var.resource_group_name
location = var.location
size = "Standard_D4s_v3"
priority = "Spot"
eviction_policy = "Deallocate" # or "Delete"
# Only create if spot price is acceptable
max_bid_price = "0.1"
}Autoscaling Schedules
Scale down during non-business hours to reduce costs.
AWS Autoscaling Schedule
# Scale down in the evening
resource "aws_autoscaling_schedule" "scale_down_evening" {
scheduled_action_name = "scale-down-evening"
min_size = 1
max_size = 1
desired_capacity = 1
recurrence = "0 20 * * MON-FRI" # 8 PM weekdays
autoscaling_group_name = aws_autoscaling_group.app.name
}
# Scale up in the morning
resource "aws_autoscaling_schedule" "scale_up_morning" {
scheduled_action_name = "scale-up-morning"
min_size = 3
max_size = 10
desired_capacity = 3
recurrence = "0 7 * * MON-FRI" # 7 AM weekdays
autoscaling_group_name = aws_autoscaling_group.app.name
}
# Weekend shutdown
resource "aws_autoscaling_schedule" "weekend_shutdown" {
scheduled_action_name = "weekend-shutdown"
min_size = 0
max_size = 0
desired_capacity = 0
recurrence = "0 18 * * FRI" # 6 PM Friday
autoscaling_group_name = aws_autoscaling_group.app.name
}GCP Autoscaler Schedules
resource "google_compute_autoscaler" "app" {
name = "app-autoscaler"
zone = var.zone
target = google_compute_instance_group_manager.app.id
autoscaling_policy {
min_replicas = 1
max_replicas = 10
cooldown_period = 60
cpu_utilization {
target = 0.6
}
scaling_schedules {
name = "scale-down-evening"
description = "Scale down in the evening"
min_required_replicas = 1
schedule = "0 20 * * 1-5" # 8 PM weekdays
time_zone = "America/New_York"
duration_sec = 39600 # 11 hours
}
scaling_schedules {
name = "scale-up-morning"
description = "Scale up in the morning"
min_required_replicas = 3
schedule = "0 7 * * 1-5" # 7 AM weekdays
time_zone = "America/New_York"
duration_sec = 46800 # 13 hours
}
}
}Storage Lifecycle Rules
Transition data to cheaper storage classes based on age.
AWS S3 Lifecycle Rules
resource "aws_s3_bucket_lifecycle_configuration" "data" {
bucket = aws_s3_bucket.data.id
rule {
id = "transition-to-ia"
status = "Enabled"
filter {
prefix = "logs/"
}
# Transition to Infrequent Access after 30 days
transition {
days = 30
storage_class = "STANDARD_IA"
}
# Transition to Glacier after 90 days
transition {
days = 90
storage_class = "GLACIER"
}
# Delete after 1 year
expiration {
days = 365
}
# Clean up incomplete multipart uploads
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
}
# Rule for temporary data
rule {
id = "delete-temp-data"
status = "Enabled"
filter {
prefix = "temp/"
}
expiration {
days = 7
}
}
}
# Enable Intelligent-Tiering for automatic cost optimization
resource "aws_s3_bucket_intelligent_tiering_configuration" "data" {
bucket = aws_s3_bucket.data.id
name = "EntireBucket"
tiering {
access_tier = "ARCHIVE_ACCESS"
days = 90
}
tiering {
access_tier = "DEEP_ARCHIVE_ACCESS"
days = 180
}
}GCP Storage Lifecycle Rules
resource "google_storage_bucket" "data" {
name = "${var.project_id}-data"
location = var.region
storage_class = "STANDARD"
lifecycle_rule {
condition {
age = 30
}
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
}
lifecycle_rule {
condition {
age = 90
}
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
}
lifecycle_rule {
condition {
age = 365
}
action {
type = "Delete"
}
}
}Azure Blob Storage Lifecycle
resource "azurerm_storage_management_policy" "data" {
storage_account_id = azurerm_storage_account.data.id
rule {
name = "transition-to-cool"
enabled = true
filters {
prefix_match = ["logs/"]
blob_types = ["blockBlob"]
}
actions {
base_blob {
tier_to_cool_after_days_since_modification_greater_than = 30
tier_to_archive_after_days_since_modification_greater_than = 90
delete_after_days_since_modification_greater_than = 365
}
snapshot {
delete_after_days_since_creation_greater_than = 30
}
}
}
}Cost Allocation Tags
Tag all resources for cost tracking and chargeback.
AWS Cost Allocation Tags
locals {
common_tags = {
Environment = var.environment
Project = var.project_name
Owner = var.team_email
CostCenter = var.cost_center
ManagedBy = "terraform"
}
}
# Apply tags to all resources
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.medium"
tags = local.common_tags
}
resource "aws_db_instance" "main" {
identifier = "${var.project_name}-db"
instance_class = "db.t3.medium"
tags = local.common_tags
}
# Activate cost allocation tags (run once per account)
resource "aws_ce_cost_allocation_tag" "environment" {
tag_key = "Environment"
status = "Active"
}
resource "aws_ce_cost_allocation_tag" "project" {
tag_key = "Project"
status = "Active"
}GCP Labels
locals {
common_labels = {
environment = var.environment
project = var.project_name
owner = var.team_email
cost-center = var.cost_center
managed-by = "terraform"
}
}
resource "google_compute_instance" "app" {
name = "app-server"
machine_type = "n2-standard-4"
labels = local.common_labels
}
# Export billing data to BigQuery for analysis
resource "google_billing_budget" "monthly" {
billing_account = var.billing_account
display_name = "Monthly Budget"
amount {
specified_amount {
currency_code = "USD"
units = "1000"
}
}
threshold_rules {
threshold_percent = 50
}
threshold_rules {
threshold_percent = 90
}
}Azure Tags
locals {
common_tags = {
Environment = var.environment
Project = var.project_name
Owner = var.team_email
CostCenter = var.cost_center
ManagedBy = "terraform"
}
}
resource "azurerm_linux_virtual_machine" "app" {
name = "app-vm"
resource_group_name = var.resource_group_name
location = var.location
size = "Standard_D4s_v3"
tags = local.common_tags
}
# Cost Management Budget
resource "azurerm_consumption_budget_resource_group" "monthly" {
name = "monthly-budget"
resource_group_id = var.resource_group_id
amount = 1000
time_grain = "Monthly"
time_period {
start_date = "2024-01-01T00:00:00Z"
end_date = "2024-12-31T00:00:00Z"
}
notification {
enabled = true
threshold = 90
operator = "GreaterThan"
contact_emails = [var.team_email]
}
}Best Practices Summary
1. Use environment-based sizing - Smaller instances for dev/staging 2. Reserved capacity for production - 1-3 year commitments for predictable workloads 3. Spot instances for fault-tolerant workloads - Up to 90% savings 4. Scheduled scaling - Scale down during off-hours 5. Storage lifecycle policies - Automate transitions to cheaper tiers 6. Cost allocation tags - Track and optimize spending 7. Right-sizing - Use the smallest instance that meets performance needs 8. Auto-shutdown - Stop dev/test resources when not in use
TF Infra Agent: Error Recovery Playbook
State Lock Error
Symptom: Error acquiring the state lock Recovery: 1. Check who holds the lock: terraform force-unlock <LOCK_ID> (use with caution) 2. Verify no other terraform process is running 3. If stale lock, confirm and force-unlock
Resource Already Exists
Symptom: Error: already exists on create Recovery: 1. Import existing resource: terraform import <resource_type>.<name> <id> 2. Verify imported state matches config: terraform plan 3. Adjust config if drift exists
Permission Denied
Symptom: AccessDenied, 403 Forbidden, insufficient permissions Recovery: 1. Check current identity:
- AWS:
aws sts get-caller-identity - GCP:
gcloud auth list - Azure:
az account show - OCI:
oci iam region list
2. Verify IAM policies attached to the identity 3. Add missing permissions following least privilege
Provider Version Conflict
Symptom: Incompatible provider version or Could not retrieve the list of available versions Recovery: 1. Update version constraint in versions.tf 2. Run terraform init -upgrade 3. Review changelog for breaking changes
Drift Detected
Symptom: terraform plan shows unexpected changes on existing resources Recovery: 1. Run terraform refresh to sync state 2. Run terraform plan to confirm 3. If manual changes exist, decide: import to state or revert manual change
Wrong Provider Configuration
Symptom: Resources targeting wrong region/project/subscription Recovery: 1. Check provider.tf for region/project/subscription settings 2. Check backend.tf for state configuration 3. Use provider aliases for multi-region setups
Module Source Error
Symptom: Module not found or Failed to download module Recovery: 1. Check module source path (local) or registry URL (remote) 2. For git sources, verify access credentials 3. Run terraform init to re-download modules
General Principles
- After 3 consecutive failures on the same issue, try a fundamentally different approach
- Check cloud provider status pages for service outages
- Never modify
.terraform.tfstatemanually - Always backup state before destructive operations:
terraform state pull > backup.tfstate
TF Infra Agent: Examples
Example 1: GCP Cloud Run Service with Cloud SQL
Input: "Deploy an API service on Cloud Run and connect it to Cloud SQL PostgreSQL"
Output:
- Files created:
compute.tf,database.tf,networking.tf,iam.tf,outputs.tf - Cloud provider: GCP (detected from existing
provider "google") - Resources: Cloud Run service, Cloud SQL PostgreSQL, VPC connector, service account
- Key decisions:
- VPC connector for private Cloud SQL access
- Dedicated service account with minimal permissions
- Cloud SQL Auth Proxy sidecar for secure connection
- Environment-based sizing:
db-f1-micro(dev) vsdb-custom-4-16384(prod)
Example 2: AWS ECS Fargate with GitHub OIDC
Input: "Set up OIDC so GitHub Actions can deploy to ECS Fargate"
Output:
- Files created:
cicd-auth.tf,iam.tf - Cloud provider: AWS (detected from existing
aws_*resources) - Resources: OIDC provider, IAM role with trust policy, ECR/ECS permissions
- Key decisions:
- Trust policy scoped to specific repo and branch
- Permissions limited to ECR push + ECS task update only
- No long-lived access keys
Example 3: Terraform Plan Review
Input: "Review this terraform plan output"
Output:
- Summary: 3 to add, 1 to change, 1 to destroy
- Risk: HIGH;
aws_db_instancewill be destroyed and recreated (engine version change) - Recommendation: Use
lifecycle { prevent_destroy = true }or manual migration - Checklist: backup verified, maintenance window set, rollback plan documented
TF Infra Agent: Execution Protocol
Step 0: Prepare
1. Assess difficulty: see ../../_shared/core/difficulty-guide.md
- Simple: Skip to Step 3 | Medium: All 4 steps | Complex: All steps + checkpoints
2. Check lessons: read the infrastructure section in ../../_shared/core/lessons-learned.md for past Terraform pitfalls 3. Clarify requirements: follow ../../_shared/core/clarification-protocol.md
- Check Uncertainty Triggers: IAM/security, compliance (PII, residency, audit), cost/sizing, existing-resource or state conflicts, provider/region ambiguity?
- Determine level: LOW → proceed | MEDIUM → present options | HIGH → ask immediately
4. Budget context: follow ../../_shared/core/context-budget.md (read symbols and file overviews, not whole files)
Intelligent Escalation: When uncertain, escalate early. Provisioning on wrong assumptions costs more than asking. Don't blindly proceed.
Follow these steps in order (adjust depth by difficulty).
Step 1: Analyze
1. Identify Cloud Provider: Detect from provider.tf, backend config, or existing resources 2. Scan existing Terraform files for naming conventions, module patterns, and state configuration 3. Identify required services, resource dependencies, and security constraints 4. Load domain-specific references:
multi-cloud-examples.mdwhen creating compute, OIDC, or secret resourcescost-optimization.mdwhen sizing or cost review is neededpolicy-testing-examples.mdwhen setting up policy enforcement or testsiso-42001-infra.mdwhen AI governance, continuity, or architecture documentation is required
5. List assumptions and unknowns
Step 2: Plan
1. Define resource naming using project conventions and locals block:
| Resource Type | Pattern | Examples |
|---|---|---|
| Compute | {prefix}-{service} | fs-dev-api, fs-prod-web |
| Database | {prefix}-db | fs-dev-db, fs-prod-postgres |
| Storage | {prefix}-{purpose} | fs-dev-assets, fs-dev-tfstate |
| IAM Role/SA | {prefix}-{role} | fs-dev-api-role, fs-dev-deployer |
| Network | {prefix}-{type} | fs-dev-vpc, fs-dev-subnet |
2. Plan file structure following project patterns:
apps/infra/
├── provider.tf # Provider configuration
├── versions.tf # Version constraints
├── variables.tf # Input variables
├── locals.tf # Local values and naming
├── backend.tf # State backend
├── compute.tf # Compute resources
├── database.tf # Databases
├── storage.tf # Object storage
├── networking.tf # VPC, subnets, LB, CDN
├── messaging.tf # Queues and messaging
├── iam.tf # IAM roles and policies
├── cicd-auth.tf # OIDC/workload identity
├── security.tf # Security groups, WAF, secrets
├── outputs.tf # Output values
└── terraform.tfvars # Variable values (gitignored)3. Plan module interfaces following composability principles:
modules/
├── vpc/ # Reusable VPC module
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── README.md
├── database/ # Reusable database module
└── compute/ # Reusable compute module- Expose required variables only; provide sensible defaults for optional
- Export essential outputs only
- Document all inputs/outputs in README.md
- Version modules using Git tags or Terraform Registry
4. Identify security requirements (IAM, encryption, network boundaries) 5. Estimate cost impact for new resources
Step 3: Implement
1. Create/modify .tf files in dependency order (provider → backend → networking → compute → outputs) 2. Use locals for environment-specific naming and tags 3. Apply consistent tags: Environment, Project, Owner, CostCenter 4. Use for_each over count for resource collections 5. Set depends_on for explicit resource ordering where needed 6. Design composable modules with:
- Required variables only, sensible defaults for optional
- Essential outputs only
- Documented inputs/outputs
7. Run terraform validate and terraform fmt 8. Run terraform plan and review output
Infrastructure Testing Levels
| Level | Tool | Purpose |
|---|---|---|
| Unit | terraform validate | Syntax, variable types |
| Static Analysis | TFLint, Checkov | Best practices, security |
| Integration | Terratest | Resource creation verification |
| Compliance | OPA/Sentinel | Organizational policy enforcement |
| E2E | Custom scripts | Full workflow validation |
See policy-testing-examples.md for Terratest, Kitchen-Terraform, and CI/CD integration examples.
Step 4: Verify
1. Run checklist.md self-verification 2. Run ../../_shared/core/common-checklist.md common checks 3. Confirm:
terraform validatepassesterraform planshows expected changes only- No secrets in .tf files
- All resources tagged
- IAM follows least privilege
- Cost impact acceptable
4. For AI systems: verify IAM, logging, encryption, monitoring, and retention controls documented 5. For continuity: verify RTO/RPO, failover, backup, and restore documented
Output Format
When creating new infrastructure, provide: 1. Cloud provider identified from context 2. Complete HCL code blocks for each resource 3. Required variable definitions with types and descriptions 4. Outputs for resource IDs and endpoints 5. Migration notes if importing existing resources 6. Cost estimation considerations 7. For AI systems: infrastructure control notes covering access, logging, encryption, monitoring, and retention 8. For continuity-sensitive systems: RTO/RPO, failover, backup, and restore notes 9. For architecture documentation requests: stakeholder/concern/view/rationale notes
When reviewing terraform plan, provide: 1. Summary of changes (add/change/destroy counts) 2. Risk assessment for destructive changes 3. Provider-specific considerations 4. Confirmation checklist before apply
TF Infra Agent - ISO/IEC 42001 / ISO 22301 / ISO/IEC/IEEE 42010 Guide
Use this file when the task involves AI systems and the user wants infrastructure controls or audit-friendly recommendations aligned with ISO/IEC 42001, continuity and recovery guidance aligned with ISO 22301, or infrastructure architecture documentation guidance aligned with ISO/IEC/IEEE 42010.
Scope
This guide is for:
- infrastructure controls that support AI governance
- continuity and recovery controls for infrastructure resilience
- architecture description guidance for infrastructure decisions
It does not replace:
- organizational policy
- model governance
- human oversight design
- AI risk management process ownership
Those belong primarily to PM, QA, backend, or security governance work.
What TF Infra Agent Should Cover
For AI systems, focus on infrastructure controls such as:
- IAM and least privilege
- service-to-service identity
- network segmentation and private connectivity
- encryption at rest and in transit
- secrets management
- centralized logging and audit trails
- monitoring and alerting
- backup and retention
- environment isolation
- change traceability in CI/CD and Terraform state
- continuity and failover design
- architecture views, dependencies, and decision rationale
Recommended Control Areas
1. Access Control
Implement:
- least-privilege IAM roles
- workload identity / OIDC for CI/CD
- separation of admin, deployer, runtime, and read-only roles
- scoped access to model endpoints, vector stores, object stores, and databases
Avoid:
- shared admin roles
- long-lived keys
- wildcard permissions to AI-related data or services
2. Network Boundaries
Implement:
- private subnets for sensitive workloads
- VPC/VNet/VCN peering or private service endpoints
- restricted egress where feasible
- ingress limited to approved paths such as ALB, API Gateway, or internal load balancers
Use stronger isolation when:
- prompts or training data contain sensitive data
- model outputs affect business-critical actions
- cross-region or cross-tenant exposure is a concern
3. Encryption and Secrets
Implement:
- provider-managed KMS or customer-managed keys where required
- encrypted storage for object stores, DBs, queues, and state backends
- TLS for internal and external traffic where supported
- secrets in cloud secret managers, not in Terraform variables committed to git
4. Logging and Auditability
Implement:
- centralized audit logs for IAM, network, storage, and runtime services
- immutable or retention-locked log targets where needed
- request tracing across gateways, application services, and data stores
- Terraform plan/apply evidence in CI/CD logs
For AI-related systems, especially capture evidence around:
- who changed infrastructure
- who can access model-serving paths
- where prompts, embeddings, or outputs are stored
- whether logging retention matches policy
5. Monitoring and Alerting
Implement:
- uptime and health monitoring
- resource utilization metrics
- security event alerting
- data egress anomaly alerting where available
- alerting for failed backups, replication, or logging pipelines
If the AI system is production-critical, recommend:
- SLO-aligned alerting
- model endpoint availability monitoring
- queue/backlog monitoring for ingestion pipelines
- vector or search cluster health checks if present
6. Retention, Backup, and Recovery
Implement:
- backup policies for stateful systems
- snapshot retention and lifecycle rules
- archival tiers for logs and historical data
- restore procedures and periodic recovery validation
For AI systems, think about:
- prompt / output retention requirements
- embedding index rebuild strategy
- backup of canonical data stores rather than only derived indexes
7. Environment and Tenant Isolation
Implement:
- separate environments by account/project/subscription/compartment when practical
- isolated state backends per environment
- tagging/labeling for ownership and cost attribution
- tenant-aware segmentation when AI data is multi-tenant
8. ISO 22301 Continuity View
For infrastructure continuity, recommend improvements around:
- critical service identification
- RTO / RPO assumptions
- backup scope and retention
- restore verification
- redundancy and failover
- cross-region or cross-zone strategy
- dependency mapping
- manual fallback and degraded-mode assumptions
Examples of infra-focused suggestions:
- multi-AZ or multi-zone deployment for critical paths
- warm standby or replicated storage for essential services
- tested snapshot restore workflow
- documented dependency chain for identity, DNS, storage, and network services
- alerting for failed replication or backup jobs
9. ISO/IEC/IEEE 42010 Architecture View
Use 42010 as an architecture description guide, not as a control checklist.
Capture:
- stakeholders
- concerns
- architecture views
- interfaces and dependencies
- constraints
- rationale and tradeoffs
For infrastructure work, useful views include:
- context view
- deployment / runtime view
- network boundary view
- identity and trust view
- resilience / recovery view
- observability view
Useful documentation prompts:
- Who needs this architecture description?
- What concerns are they trying to answer?
- Which infrastructure elements and interfaces matter?
- What tradeoffs were chosen and why?
- What dependencies create operational risk?
Review Questions
When applying ISO/IEC 42001 / ISO 22301 / ISO/IEC/IEEE 42010 thinking, ask:
- Can access to AI-related data paths be audited?
- Are model-serving and data-serving paths protected with least privilege?
- Are logs centralized, retained, and protected against tampering?
- Are backups, retention, and restore procedures defined?
- Are continuity objectives such as RTO / RPO explicit?
- Are failover paths and critical dependencies visible?
- Is network exposure minimized?
- Is CI/CD access ephemeral and traceable?
- Is there clear ownership for each critical resource?
- Are the stakeholders, concerns, and architecture rationale documented clearly?
Output Pattern
When relevant, add a short section like:
## ISO/IEC 42001 / ISO 22301 / 42010 Notes
- Access control:
- Network boundary:
- Encryption:
- Logging / auditability:
- Monitoring / alerting:
- Backup / retention:
- Continuity / RTO / RPO:
- Failover / dependency view:
- Stakeholders / concerns / views:
- Gaps:
- Recommended Terraform changes:Guardrails
- Do not claim ISO/IEC 42001 compliance from Terraform alone
- Do not claim ISO 22301 compliance from backup settings alone
- Do not expand this skill into full AI governance process design
- Do not turn 42010 into paperwork without architectural value
- Keep suggestions concrete and infra-implementable
- If the gap is organizational rather than infrastructural, say so explicitly
Multi-Cloud Resource Examples
Detailed HCL examples for AWS, GCP, Azure, and Oracle Cloud.
AWS Examples
ECS Fargate Service
resource "aws_ecs_service" "api" {
name = "${local.prefix}-api"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.api.arn
desired_count = var.api_min_instances
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.private[*].id
security_groups = [aws_security_group.api.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.api.arn
container_name = "api"
container_port = 8000
}
}OIDC for GitHub Actions
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["6938fd4e98bab03faadb97b34396831e3780aea1"]
}
resource "aws_iam_role" "github_actions" {
name = "${local.prefix}-github-actions"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Federated = aws_iam_openid_connect_provider.github.arn }
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = { "token.actions.githubusercontent.com:aud" = "sts.amazonaws.com" }
StringLike = { "token.actions.githubusercontent.com:sub" = "repo:${var.github_repo}:*" }
}
}]
})
}Secrets Manager
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "${local.prefix}/db-password"
}GCP Examples
Cloud Run Service
resource "google_cloud_run_v2_service" "api" {
name = "${local.prefix}-api"
location = var.region
project = var.project_id
template {
service_account = google_service_account.api.email
scaling {
min_instances = var.api_min_instances
max_instances = var.api_max_instances
}
containers {
image = "${var.region}-docker.pkg.dev/${var.project_id}/${local.prefix}/api:${var.image_tag}"
resources {
limits = { cpu = "2", memory = "1Gi" }
cpu_idle = true
}
ports { container_port = 8000 }
}
vpc_access {
connector = google_vpc_access_connector.main.id
egress = "ALL_TRAFFIC"
}
}
}Workload Identity Federation
resource "google_iam_workload_identity_pool" "github" {
workload_identity_pool_id = "github-pool"
display_name = "GitHub Actions Pool"
}
resource "google_iam_workload_identity_pool_provider" "github" {
workload_identity_pool_id = google_iam_workload_identity_pool.github.workload_identity_pool_id
workload_identity_pool_provider_id = "github-provider"
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.repository" = "assertion.repository"
}
oidc {
issuer_uri = "https://token.actions.githubusercontent.com"
}
}Secret Manager
data "google_secret_manager_secret_version" "db_password" {
secret = "db-password"
version = "latest"
}Azure Examples
Container Apps
resource "azurerm_container_app" "api" {
name = "${local.prefix}-api"
container_app_environment_id = azurerm_container_app_environment.main.id
resource_group_name = azurerm_resource_group.main.name
revision_mode = "Single"
template {
min_replicas = var.api_min_instances
max_replicas = var.api_max_instances
container {
name = "api"
image = "${azurerm_container_registry.main.login_server}/${local.prefix}/api:${var.image_tag}"
cpu = 1.0
memory = "2Gi"
env {
name = "DATABASE_URL"
value = "postgresql://..."
}
}
}
}Federated Credentials
resource "azuread_application_federated_identity_credential" "github" {
application_object_id = azuread_application.github.object_id
display_name = "github-actions"
description = "GitHub Actions OIDC"
audiences = ["api://AzureADTokenExchange"]
issuer = "https://token.actions.githubusercontent.com"
subject = "repo:${var.github_repo}:ref:refs/heads/main"
}Key Vault
data "azurerm_key_vault_secret" "db_password" {
name = "db-password"
key_vault_id = azurerm_key_vault.main.id
}Oracle Cloud Examples
Container Instances
resource "oci_container_instances_container_instance" "api" {
compartment_id = var.compartment_id
display_name = "${local.prefix}-api"
containers {
image_url = "${oci_artifacts_container_repository.api.repository_url}:${var.image_tag}"
display_name = "api"
environment_variables = {
"DATABASE_URL" = "postgresql://..."
}
}
}Vault
data "oci_secrets_secretbundle" "db_password" {
secret_id = oci_vault_secret.db_password.id
}Policy and Testing Examples
OPA policies, Sentinel rules, and infrastructure testing patterns.
OPA (Open Policy Agent)
Required Tags Policy
# required_tags.rego
package terraform.tags
import future.keywords.if
import future.keywords.in
deny[msg] if {
resource := input.resource_changes[_]
resource.mode == "managed"
not resource.change.after.tags
msg := sprintf("Resource %s missing required tags", [resource.address])
}
deny[msg] if {
resource := input.resource_changes[_]
required_tags := {"Environment", "Project", "Owner"}
missing := required_tags - object.keys(resource.change.after.tags)
count(missing) > 0
msg := sprintf("Resource %s missing tags: %v", [resource.address, missing])
}Encryption Policy
# encryption_required.rego
package terraform.encryption
deny[msg] if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not resource.change.after.server_side_encryption_configuration
msg := sprintf("S3 bucket %s must have encryption enabled", [resource.address])
}Cost Control Policy
# cost_control.rego
package terraform.cost
deny[msg] if {
resource := input.resource_changes[_]
resource.type == "aws_instance"
instance_type := resource.change.after.instance_type
not startswith(instance_type, "t3.")
msg := sprintf("EC2 instance %s uses expensive type %s. Use t3.* for dev.", [resource.address, instance_type])
}Sentinel (Terraform Cloud)
Require Encryption
# require_encryption.sentinel
import "tfplan"
main = rule {
all tfplan.resources.aws_s3_bucket as _, buckets {
all buckets as _, bucket {
bucket.applied.server_side_encryption_configuration is not null
}
}
}Restrict Instance Types
# restrict_instance_types.sentinel
import "tfplan"
allowed_types = ["t3.micro", "t3.small", "t3.medium"]
main = rule {
all tfplan.resources.aws_instance as _, instances {
all instances as _, instance {
instance.applied.instance_type in allowed_types
}
}
}Terratest (Go)
VPC Module Test
// vpc_test.go
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestVpcModule(t *testing.T) {
terraformOptions := &terraform.Options{
TerraformDir: "../modules/vpc",
Vars: map[string]interface{}{
"name": "test-vpc",
"cidr_block": "10.0.0.0/16",
"availability_zones": []string{"us-east-1a", "us-east-1b"},
},
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
vpcId := terraform.Output(t, terraformOptions, "vpc_id")
assert.NotEmpty(t, vpcId)
privateSubnets := terraform.OutputList(t, terraformOptions, "private_subnet_ids")
assert.Equal(t, 2, len(privateSubnets))
}Database Module Test
// database_test.go
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestDatabaseModule(t *testing.T) {
terraformOptions := &terraform.Options{
TerraformDir: "../modules/database",
Vars: map[string]interface{}{
"identifier": "test-db",
"engine": "postgres",
"instance_class": "db.t3.micro",
},
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
endpoint := terraform.Output(t, terraformOptions, "endpoint")
assert.Contains(t, endpoint, "rds.amazonaws.com")
}Kitchen-Terraform (Ruby)
VPC Controls
# controls/vpc.rb
control 'vpc-exists' do
describe aws_vpc('vpc-12345678') do
it { should exist }
its('cidr_block') { should eq '10.0.0.0/16' }
end
end
control 'subnets-exist' do
describe aws_subnets do
its('subnet_ids.count') { should be >= 2 }
end
endSecurity Group Controls
# controls/security_group.rb
control 'no-ssh-from-internet' do
aws_security_groups.group_ids.each do |sg_id|
describe aws_security_group(sg_id) do
it { should_not allow_in(port: 22, ipv4_range: '0.0.0.0/0') }
end
end
endCI/CD Integration
GitHub Actions Workflow
# .github/workflows/terraform.yml
name: Terraform
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Format
run: terraform fmt -check -recursive
- name: Terraform Validate
run: |
terraform init -backend=false
terraform validate
- name: Run TFLint
uses: terraform-linters/setup-tflint@v4
with:
tflint_version: latest
- run: tflint --init && tflint
- name: Run Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: .
framework: terraform
- name: Run OPA Tests
run: |
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
opa test policies/ --verbose
opa eval --data policies/required_tags.rego --input tfplan.json "data.terraform.tags.deny"Validation Script
#!/bin/bash
# validate.sh
set -e
echo "Running Terraform validation..."
# Format check
echo " → Checking format..."
terraform fmt -check -recursive
# Initialize
echo " → Initializing..."
terraform init -backend=false
# Validate
echo " → Validating..."
terraform validate
# Security scan with Checkov
echo " → Running Checkov..."
checkov -d . --framework terraform --quiet
# Lint with TFLint
echo " → Running TFLint..."
tflint --init
tflint
# Plan and OPA check (if policies exist)
if [ -d "policies" ]; then
echo " → Running OPA policy checks..."
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
opa test policies/
fi
echo "All validation passed!"