Basic Usage Examples¶
This page provides practical examples of using TFOut in common scenarios.
Example 1: Simple Web Application¶
Let's say you have a Terraform configuration that creates infrastructure for a web application:
Terraform Configuration¶
# main.tf
resource "aws_db_instance" "webapp" {
identifier = "webapp-db"
engine = "postgres"
# ... other configuration
}
resource "aws_elasticache_cluster" "webapp" {
cluster_id = "webapp-cache"
engine = "redis"
# ... other configuration
}
output "database_endpoint" {
value = aws_db_instance.webapp.endpoint
description = "PostgreSQL database endpoint"
}
output "database_port" {
value = aws_db_instance.webapp.port
description = "PostgreSQL database port"
}
output "database_name" {
value = aws_db_instance.webapp.db_name
description = "PostgreSQL database name"
}
output "database_password" {
value = aws_db_instance.webapp.password
description = "PostgreSQL database password"
sensitive = true
}
output "cache_endpoint" {
value = aws_elasticache_cluster.webapp.cache_nodes[0].address
description = "Redis cache endpoint"
}
output "cache_port" {
value = aws_elasticache_cluster.webapp.port
description = "Redis cache port"
}
TFOut Configuration¶
# webapp-config.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: webapp-infrastructure
namespace: production
labels:
app: webapp
component: infrastructure
spec:
syncInterval: 5m
backends:
- s3:
bucket: my-terraform-state
key: webapp/production/terraform.tfstate
region: us-west-2
target:
namespace: production
configMapName: webapp-config
secretName: webapp-secrets
Application Deployment¶
# webapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: webapp:latest
env:
# Database configuration from ConfigMap
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: webapp-config
key: database_endpoint
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: webapp-config
key: database_port
- name: DB_NAME
valueFrom:
configMapKeyRef:
name: webapp-config
key: database_name
# Database password from Secret
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: webapp-secrets
key: database_password
# Cache configuration from ConfigMap
- name: CACHE_HOST
valueFrom:
configMapKeyRef:
name: webapp-config
key: cache_endpoint
- name: CACHE_PORT
valueFrom:
configMapKeyRef:
name: webapp-config
key: cache_port
Example 2: Multi-Service Application¶
For applications with multiple services that need different parts of the infrastructure:
Terraform Outputs¶
# Infrastructure outputs
output "vpc_id" {
value = aws_vpc.main.id
}
output "private_subnet_ids" {
value = aws_subnet.private[*].id
}
output "public_subnet_ids" {
value = aws_subnet.public[*].id
}
output "database_endpoint" {
value = aws_rds_instance.main.endpoint
}
output "database_password" {
value = aws_rds_instance.main.password
sensitive = true
}
output "api_gateway_url" {
value = aws_api_gateway_deployment.main.invoke_url
}
output "s3_bucket_name" {
value = aws_s3_bucket.uploads.bucket
}
output "cloudfront_domain" {
value = aws_cloudfront_distribution.main.domain_name
}
Shared Infrastructure Config¶
# shared-infrastructure.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: shared-infrastructure
namespace: infrastructure
spec:
syncInterval: 10m
backends:
- s3:
bucket: terraform-state-prod
key: infrastructure/shared/terraform.tfstate
region: us-west-2
target:
namespace: infrastructure
configMapName: shared-config
secretName: shared-secrets
API Service Config¶
# api-service.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: api-service-config
namespace: api
spec:
syncInterval: 5m
backends:
- s3:
bucket: terraform-state-prod
key: infrastructure/shared/terraform.tfstate
region: us-west-2
target:
namespace: api
configMapName: api-config
secretName: api-secrets
API Deployment¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
namespace: api
spec:
replicas: 2
selector:
matchLabels:
app: api-service
template:
spec:
containers:
- name: api
image: api-service:latest
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: api-config
key: database_endpoint
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: api-secrets
key: database_password
- name: S3_BUCKET
valueFrom:
configMapKeyRef:
name: api-config
key: s3_bucket_name
Frontend Service Config¶
# frontend-service.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: frontend-config
namespace: frontend
spec:
syncInterval: 5m
backends:
- s3:
bucket: terraform-state-prod
key: infrastructure/shared/terraform.tfstate
region: us-west-2
target:
namespace: frontend
configMapName: frontend-config
secretName: frontend-secrets
Frontend Deployment¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
spec:
containers:
- name: frontend
image: frontend:latest
env:
- name: REACT_APP_API_URL
valueFrom:
configMapKeyRef:
name: frontend-config
key: api_gateway_url
- name: REACT_APP_CDN_URL
valueFrom:
configMapKeyRef:
name: frontend-config
key: cloudfront_domain
Example 3: Environment-Specific Configuration¶
Managing different environments with environment-specific outputs:
Development Environment¶
# dev-config.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: app-config
namespace: development
labels:
environment: development
spec:
syncInterval: 2m # Faster sync for development
backends:
- s3:
bucket: terraform-state-dev
key: app/terraform.tfstate
region: us-west-2
target:
namespace: development
configMapName: app-config
secretName: app-secrets
Staging Environment¶
# staging-config.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: app-config
namespace: staging
labels:
environment: staging
spec:
syncInterval: 5m
backends:
- s3:
bucket: terraform-state-staging
key: app/terraform.tfstate
region: us-west-2
target:
namespace: staging
configMapName: app-config
secretName: app-secrets
Production Environment¶
# prod-config.yaml
apiVersion: tfout.wibrow.net/v1alpha1
kind: TerraformOutputs
metadata:
name: app-config
namespace: production
labels:
environment: production
spec:
syncInterval: 15m # Slower sync for production stability
backends:
- s3:
bucket: terraform-state-prod
key: app/terraform.tfstate
region: us-west-2
role: arn:aws:iam::123456789012:role/tfout-prod-reader
target:
namespace: production
configMapName: app-config
secretName: app-secrets
Example 4: ConfigMap and Secret Usage Patterns¶
Using envFrom for Bulk Configuration¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
image: app:latest
# Load all non-sensitive config as environment variables
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
# Override specific values if needed
env:
- name: LOG_LEVEL
value: "info"
Mounting as Files¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
image: app:latest
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
- name: secrets
mountPath: /etc/secrets
readOnly: true
volumes:
- name: config
configMap:
name: app-config
- name: secrets
secret:
secretName: app-secrets
Monitoring Your Configurations¶
Check TerraformOutputs Status¶
# List all TerraformOutputs resources
kubectl get terraformoutputs --all-namespaces
# Get detailed status
kubectl describe terraformoutputs webapp-infrastructure -n production
# Watch for changes
kubectl get terraformoutputs -w
Verify Created Resources¶
# Check ConfigMap
kubectl get configmap webapp-config -n production -o yaml
# Check Secret (decode values)
kubectl get secret webapp-secrets -n production -o jsonpath='{.data.database_password}' | base64 -d
# List all keys in ConfigMap
kubectl get configmap webapp-config -n production -o jsonpath='{.data}' | jq 'keys'
Monitor Sync Events¶
# View events related to TerraformOutputs
kubectl get events --field-selector involvedObject.kind=TerraformOutputs -n production
# Check operator logs
kubectl logs -n tfout deployment/tfout-controller-manager -f
Best Practices from Examples¶
- Use descriptive names that indicate the application and environment
- Set appropriate sync intervals based on environment needs
- Use labels for organization and filtering
- Separate sensitive and non-sensitive outputs appropriately
- Use namespace isolation for different environments
- Monitor the sync status regularly
- Test configuration changes in development first
Troubleshooting Common Issues¶
No Outputs Found¶
# Check if Terraform state has outputs
aws s3 cp s3://my-terraform-state/app/terraform.tfstate - | jq .outputs
# Verify backend configuration
kubectl describe terraformoutputs webapp-infrastructure -n production
Permission Errors¶
# Test S3 access manually
aws s3 ls s3://my-terraform-state/app/terraform.tfstate
# Check operator logs for detailed errors
kubectl logs -n tfout deployment/tfout-controller-manager --tail=50