Files
pos-system/.agent/rules/infrastructure-as-code.md

416 lines
9.1 KiB
Markdown

---
trigger: always_on
---
# Infrastructure as Code Patterns
## When to Use This Skill
Use this skill when:
- Managing infrastructure with code
- Implementing Terraform modules
- Setting up GitOps workflows
- Creating Kubernetes operators
- Testing infrastructure changes
- Managing multi-environment infrastructure
- Versioning infrastructure
- Automating infrastructure provisioning
## Core Concepts
### Infrastructure as Code Benefits
1. **Version Control**: Track infrastructure changes
2. **Reproducibility**: Consistent environments
3. **Automation**: Reduce manual errors
4. **Testing**: Test infrastructure changes
5. **Collaboration**: Team can review changes
### IaC Tools
- **Terraform**: Infrastructure provisioning
- **Kubernetes Manifests**: K8s resource definitions
- **Helm**: K8s package manager
- **ArgoCD/Flux**: GitOps tools
## Terraform Patterns
### Module Structure
```
infra/terraform/
├── modules/
│ ├── kubernetes-cluster/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── postgresql/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── redis/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── staging/
│ │ ├── main.tf
│ │ └── terraform.tfvars
│ └── production/
│ ├── main.tf
│ └── terraform.tfvars
└── shared/
└── backend.tf
```
### Terraform Module Example
```hcl
# infra/terraform/modules/postgresql/main.tf
# EN: PostgreSQL module
# VI: Module PostgreSQL
variable "database_name" {
description = "Database name"
type = string
}
variable "environment" {
description = "Environment name"
type = string
}
resource "google_sql_database_instance" "postgres" {
name = "${var.database_name}-${var.environment}"
database_version = "POSTGRES_15"
region = "us-central1"
settings {
tier = "db-f1-micro"
backup_configuration {
enabled = true
start_time = "03:00"
}
}
}
resource "google_sql_database" "database" {
name = var.database_name
instance = google_sql_database_instance.postgres.name
}
output "connection_name" {
value = google_sql_database_instance.postgres.connection_name
}
output "database_url" {
value = "postgresql://user:pass@${google_sql_database_instance.postgres.ip_address}/${var.database_name}"
sensitive = true
}
```
### Using Modules
```hcl
# infra/terraform/environments/staging/main.tf
# EN: Use PostgreSQL module
# VI: Sử dụng module PostgreSQL
module "postgresql" {
source = "../../modules/postgresql"
database_name = "goodgo_staging"
environment = "staging"
}
output "database_url" {
value = module.postgresql.database_url
sensitive = true
}
```
## GitOps Patterns
### ArgoCD Setup
```yaml
# infra/gitops/argocd/applications/user-service.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: user-service
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/goodgo/platform
targetRevision: main
path: deployments/production/kubernetes/user-service
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
```
### Flux Setup
```yaml
# infra/gitops/flux/kustomizations/user-service.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: user-service
namespace: flux-system
spec:
interval: 5m
path: ./deployments/production/kubernetes/user-service
prune: true
sourceRef:
kind: GitRepository
name: platform-repo
validation: client
```
## Infrastructure Testing
### Terraform Testing
```bash
#!/bin/bash
# scripts/infra/test-terraform.sh
# EN: Test Terraform changes
# VI: Test các thay đổi Terraform
cd infra/terraform/environments/staging
# EN: Validate Terraform
# VI: Validate Terraform
terraform init
terraform validate
# EN: Plan changes
# VI: Plan changes
terraform plan -out=tfplan
# EN: Review plan
# VI: Review plan
terraform show tfplan
```
### Infrastructure Validation
```typescript
// scripts/infra/validate-k8s.ts
// EN: Validate Kubernetes manifests
// VI: Validate Kubernetes manifests
import { execSync } from 'child_process';
function validateKubernetesManifests(path: string): boolean {
try {
execSync(`kubectl apply --dry-run=client -f ${path}`, {
stdio: 'inherit',
});
console.log('Kubernetes manifests are valid');
return true;
} catch (error) {
console.error('Kubernetes validation failed', error);
return false;
}
}
```
## Environment Management
### Environment Configuration
```hcl
# infra/terraform/environments/staging/terraform.tfvars
environment = "staging"
cluster_name = "goodgo-staging"
node_count = 3
instance_type = "t3.medium"
# infra/terraform/environments/production/terraform.tfvars
environment = "production"
cluster_name = "goodgo-production"
node_count = 5
instance_type = "t3.large"
```
### Multi-Environment Module
```hcl
# infra/terraform/modules/service/main.tf
variable "environment" {
type = string
}
variable "replicas" {
type = map(number)
default = {
staging = 2
production = 5
}
}
resource "kubernetes_deployment" "service" {
metadata {
name = "${var.service_name}-${var.environment}"
}
spec {
replicas = var.replicas[var.environment]
# ...
}
}
```
## Kubernetes Operators
### Custom Resource Definition
```yaml
# infra/operators/database-operator/crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: databases.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
databaseName:
type: string
environment:
type: string
```
## Best Practices
1. **Version Control**: Keep all infrastructure in version control
2. **Modules**: Create reusable Terraform modules
3. **Testing**: Test infrastructure changes before applying
4. **GitOps**: Use GitOps for Kubernetes deployments
5. **Environment Isolation**: Separate environments completely
6. **State Management**: Use remote state backends
7. **Secrets**: Never commit secrets, use secrets managers
## Common Mistakes
1. **Committing Secrets**: Exposed credentials
```hcl
# ❌ BAD: Hardcoded secrets
password = "my-secret-password"
# ✅ GOOD: Use variables + secrets manager
password = var.db_password # From env or secrets manager
```
2. **No Remote State**: State conflicts in team
```hcl
# ❌ BAD: Local state
# (no backend config)
# ✅ GOOD: Remote state
terraform {
backend "s3" {
bucket = "terraform-state"
key = "staging/terraform.tfstate"
}
}
```
3. **No State Locking**: Concurrent modifications
```hcl
# ✅ Enable state locking
backend "s3" {
dynamodb_table = "terraform-locks"
}
```
4. **Applying Without Plan Review**: Unexpected changes
```bash
# ❌ BAD: Direct apply
terraform apply
# ✅ GOOD: Plan first, review, then apply
terraform plan -out=tfplan
terraform show tfplan # Review
terraform apply tfplan
```
## Quick Reference
| Tool | Purpose | State |
|------|---------|-------|
| **Terraform** | Cloud resources | Stateful |
| **Kubernetes** | Container orchestration | Declarative |
| **Helm** | K8s package manager | Template |
| **ArgoCD/Flux** | GitOps deployment | Git-synced |
**Terraform Commands:**
```bash
terraform init # Initialize
terraform validate # Validate syntax
terraform plan # Preview changes
terraform apply # Apply changes
terraform destroy # Remove resources
terraform state list # List state resources
```
**Module Structure:**
```
modules/service/
├── main.tf # Resources
├── variables.tf # Input variables
├── outputs.tf # Output values
└── README.md # Documentation
```
**Environment Pattern:**
```
environments/
├── staging/
│ ├── main.tf
│ └── terraform.tfvars
└── production/
├── main.tf
└── terraform.tfvars
```
**GitOps Workflow:**
```
Git Push → CI Validates → ArgoCD Syncs → K8s Applied
Auto-heal if drift
```
**Best Practices Checklist:**
- [ ] Remote state backend configured
- [ ] State locking enabled
- [ ] No secrets in code
- [ ] Modules for reusable components
- [ ] Environment-specific tfvars
- [ ] PR review for all changes
## Resources
- [Terraform Documentation](https://www.terraform.io/docs)
- [ArgoCD Documentation](https://argo-cd.readthedocs.io/)
- [Flux Documentation](https://fluxcd.io/docs/)
- [Deployment Kubernetes](../deployment-kubernetes/SKILL.md) - K8s patterns
- [Project Rules](../project-rules/SKILL.md) - GoodGo standards