1 minute read

Introducción

La gestión eficiente del código de una Landing Zone es crucial para mantener una infraestructura escalable y segura. En este artículo, exploraremos cómo organizar y gestionar el código de una Landing Zone utilizando GitHub y Terraform.

Landing Zone Structure

Estructura del Repositorio

landing-zone/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── terraform.tfvars
│   ├── staging/
│   └── prod/
├── modules/
│   ├── networking/
│   ├── security/
│   ├── governance/
│   └── baseline/
└── pipelines/
    ├── terraform-plan.yml
    └── terraform-apply.yml

Módulo Base de Landing Zone

# modules/baseline/main.tf
module "resource_groups" {
  source = "../resource-groups"
  
  environment = var.environment
  location    = var.location
  tags        = var.tags
}

module "networking" {
  source = "../networking"
  
  resource_group_name = module.resource_groups.network_rg_name
  address_space      = var.address_space
  environment        = var.environment
}

module "security" {
  source = "../security"
  
  resource_group_name = module.resource_groups.security_rg_name
  environment        = var.environment
}

GitHub Actions Pipeline

# .github/workflows/terraform-apply.yml
name: 'Terraform Apply'

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  terraform:
    name: 'Terraform'
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: 1.0.0

    - name: Terraform Format
      run: terraform fmt -check

    - name: Terraform Init
      run: terraform init
      
    - name: Terraform Plan
      run: terraform plan -out=tfplan
      
    - name: Terraform Apply
      if: github.ref == 'refs/heads/main' && github.event_name == 'push'
      run: terraform apply -auto-approve tfplan

Control de Versiones y Branches

# Estructura de branches
main              # Producción
├── develop       # Desarrollo
├── feature/*     # Nuevas características
└── hotfix/*      # Correcciones urgentes

Gestión de Secretos

# .github/workflows/secrets.yml
name: 'Secrets Management'

env:
  ARM_CLIENT_ID: $
  ARM_CLIENT_SECRET: $
  ARM_SUBSCRIPTION_ID: $
  ARM_TENANT_ID: $

Módulo de Políticas

# modules/governance/policies.tf
resource "azurerm_policy_definition" "allowed_locations" {
  name         = "allowed-locations"
  policy_type  = "Custom"
  mode         = "All"
  display_name = "Allowed Locations"

  policy_rule = <<POLICY_RULE
{
  "if": {
    "not": {
      "field": "location",
      "in": "[parameters('allowedLocations')]"
    }
  },
  "then": {
    "effect": "deny"
  }
}
POLICY_RULE
}

Testing y Validación

# tests/main.tf
module "test_baseline" {
  source = "../modules/baseline"

  environment = "test"
  location    = "westeurope"
  
  tags = {
    Environment = "Test"
    ManagedBy   = "Terraform"
  }
}

Automatización de Documentación

# Documentation Generator
terraform-docs markdown table --output-file README.md ./modules/baseline

Control de Costos

# modules/governance/cost_management.tf
resource "azurerm_consumption_budget_subscription" "main" {
  name            = "subscription-budget"
  subscription_id = data.azurerm_subscription.current.id

  amount     = 1000
  time_grain = "Monthly"

  notification {
    enabled        = true
    threshold      = 90.0
    operator       = "GreaterThan"
    contact_emails = ["team@example.com"]
  }
}

Referencias