VPC e ISO27001: cómo convertir la red de AWS en un control de seguridad auditable
Uno de los puntos más delicados en una auditoría de ISO 27001 es demostrar que los controles técnicos no son intenciones, sino decisiones de diseño.
En entornos cloud, la VPC es una de las piezas que más peso tiene en esa demostración.
Mientras participaba en una auditoria, cuando tuve la bien diseñada la VPC aceleró la prueba, pero anteriormente, la arquitectura de red fue la causa de 8+ no conformidades mayores.
Este artículo hace algo muy concreto: mapear controles del Anexo A con decisiones reales de diseño en una VPC de AWS, para que el SGSI sea coherente, defendible y sostenible en el tiempo.
Importante: ISO 27001 no certifica AWS. Certifica cómo TÚ usas AWS.
Esta distinción es fundamental:
Certificación ISO 27001:
AWS (infraestructura):
- Ya tiene ISO 27001, SOC 2, PCI-DSS, etc.
- Certifica: datacenters, hardware, procesos internos
- TU responsabilidad: CERO sobre esto
Tu organización (uso de AWS):
- Certifica: cómo diseñas, configuras, operas
- Controles: arquitectura VPC, IAM, cifrado, logging
- TU responsabilidad: 100% sobre esto
Modelo de responsabilidad compartida:
┌─────────────────────────────────────┐
│ AWS: Seguridad DE la nube │
│ (hardware, red física, zonas) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ TÚ: Seguridad EN la nube │
│ (VPC, SGs, IAM, datos, apps) │ ← ISO 27001 audita ESTO
└─────────────────────────────────────┘
Un auditor no pregunta si AWS es seguro. Pregunta si TÚ sabes usarlo de forma segura.
La VPC como columna vertebral del SGSI técnico
Una VPC bien diseñada es la manifestación técnica de múltiples controles ISO 27001:
VPC como control técnico:
Qué demuestra una VPC conforme:
✅ Segmentación de red (A.13)
✅ Control de acceso (A.9)
✅ Aislamiento de activos (A.8)
✅ Separación de entornos (A.14)
✅ Protección de comunicaciones (A.13)
✅ Reducción de superficie de ataque (A.12)
✅ Política de seguridad aplicada (A.5)
✅ Gestión de cambios controlada (A.14)
Qué NO demuestra una VPC mal diseñada:
❌ Reglas de Security Groups "allow all"
❌ Subredes públicas sin justificación
❌ Rutas a Internet Gateway desde subredes privadas
❌ Mezcla de entornos dev/prod
❌ Sin documentación de arquitectura
❌ Cambios no trazables (sin IaC)
❌ Sin Flow Logs
❌ Sin revisión periódica
La diferencia entre pasar y no pasar la auditoría puede estar en cómo diseñaste la red.
A.5 – Políticas de seguridad de la información
La VPC como materialización de la política
Aunque A.5 es organizativo, la VPC actúa como traducción técnica de la política de seguridad.
Control A.5.1.1 - Políticas de seguridad de la información:
Política de seguridad (documento):
"Los sistemas críticos deben estar aislados de Internet
y solo accesibles desde la red corporativa."
Implementación técnica (VPC):
✅ Sistemas críticos en subredes privadas
✅ Sin ruta a Internet Gateway
✅ Acceso solo vía VPN/Direct Connect
✅ Security Groups restrictivos
✅ NACLs como capa adicional
Evidencia auditable:
- Diagrama de arquitectura VPC
- Route tables sin 0.0.0.0/0 → igw-xxx
- Export de Security Groups
- Configuración VPN/Direct Connect
Ejemplo práctico - Política convertida en diseño:
# Terraform: Materialización de política de seguridad
# Política: "Bases de datos nunca accesibles desde Internet"
resource "aws_subnet" "database" {
count = 3
vpc_id = aws_vpc.production.id
cidr_block = cidrsubnet(aws_vpc.production.cidr_block, 4, count.index + 8)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = false # CRÍTICO: no IPs públicas
tags = {
Name = "database-private-${count.index + 1}"
Tier = "data"
ISO27001Control = "A.5.1.1,A.13.1.1"
InternetAccessible = "false"
Justification = "Política de seguridad corporativa"
}
}
# Route table sin Internet
resource "aws_route_table" "database" {
vpc_id = aws_vpc.production.id
# Solo rutas internas, NO hay default route a Internet
tags = {
Name = "database-route-table"
ISO27001Control = "A.5.1.1"
Purpose = "Enforce no Internet access policy"
}
}
resource "aws_route_table_association" "database" {
count = 3
subnet_id = aws_subnet.database[count.index].id
route_table_id = aws_route_table.database.id
}
# Security Group ultra restrictivo
resource "aws_security_group" "database" {
name = "database-sg"
description = "DB tier - only from application tier (ISO27001 A.5)"
vpc_id = aws_vpc.production.id
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.application.id]
description = "PostgreSQL from App tier only"
}
# Sin egress a Internet
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [aws_vpc.production.cidr_block]
description = "HTTPS interno para patching"
}
tags = {
Name = "database-security-group"
ISO27001Control = "A.5.1.1,A.9.1.2"
Policy = "No Internet, App tier only"
}
}
Aquí la VPC convierte una política en una imposibilidad técnica de incumplirla. Esto reduce riesgo operativo y dependencia del factor humano.
A.8 – Gestión de activos
Del inventario al aislamiento
Control A.8.1.1 exige inventario de activos. A.8.2.1 exige clasificación. La VPC permite ambos.
Registro de activos materializado en VPC:
Ficha de activo - Subnet Database:
Identificación:
ID AWS: subnet-0a1b2c3d4e5f6g7h8
Nombre: database-private-1
CIDR: 10.16.32.0/24
AZ: us-east-1a
VPC: vpc-production (10.16.0.0/16)
Clasificación:
Tier: Data (nivel más crítico)
Tipo de datos: Confidencial (PII, datos financieros)
Criticidad: Alta
Control ISO27001: A.8.1.1, A.8.2.1
Propietario:
Business Owner: CFO
Technical Owner: Database Team Lead
Custodian: Cloud Platform Team
Controles aplicados:
✅ Sin acceso a Internet
✅ Security Groups restrictivos
✅ Encryption at rest (RDS)
✅ Encryption in transit (TLS)
✅ Backups automáticos
✅ Flow Logs activos
✅ Monitoring con CloudWatch
Revisión:
Frecuencia: Trimestral
Última revisión: 15/12/2025
Próxima revisión: 15/03/2026
Responsable: Security Team
Implementación con tags auditables:
# Terraform: Tags para gestión de activos conforme ISO27001
locals {
asset_tags = {
# Gestión de activos (A.8)
AssetID = "ASSET-VPC-SUBNET-DB-001"
Owner = "database-team"
BusinessOwner = "CFO"
TechnicalCustodian = "platform-team"
# Clasificación (A.8.2)
DataClassification = "CONFIDENTIAL"
DataType = "PII,Financial"
Criticality = "HIGH"
# Compliance
ISO27001Control = "A.8.1.1,A.8.2.1,A.8.2.3"
ComplianceScope = "ISO27001,GDPR,SOC2"
RetentionPeriod = "7-years"
# Operacional
Environment = "production"
ManagedBy = "terraform"
CostCenter = "engineering"
# Auditoría
LastReview = "2025-12-15"
NextReview = "2026-03-15"
ReviewFrequency = "quarterly"
}
}
resource "aws_subnet" "database" {
count = 3
vpc_id = aws_vpc.production.id
cidr_block = cidrsubnet(aws_vpc.production.cidr_block, 4, count.index + 8)
tags = merge(
local.asset_tags,
{
Name = "database-private-${count.index + 1}"
AZ = data.aws_availability_zones.available.names[count.index]
}
)
}
Separación física de activos por clasificación:
Arquitectura VPC por clasificación de activos:
VPC Production (10.16.0.0/16):
Subnets Públicas (10.16.0.0/20):
Clasificación: Pública
Activos: ALB, CloudFront Origins
Internet: Sí (justificado)
ISO27001: A.8.2.1
Subnets Aplicación (10.16.16.0/20):
Clasificación: Interna
Activos: EC2, ECS, Lambda
Internet: Vía NAT Gateway (salida)
ISO27001: A.8.2.1, A.13.1.1
Subnets Base de Datos (10.16.32.0/20):
Clasificación: Confidencial
Activos: RDS, ElastiCache, DocumentDB
Internet: No (nunca)
ISO27001: A.8.2.1, A.8.2.3
Subnets Management (10.16.48.0/24):
Clasificación: Restringido
Activos: Bastion (deprecated), Systems Manager
Internet: Controlado
ISO27001: A.8.2.1, A.9.2.1
Resultado auditable:
✅ Activos clasificados físicamente separados
✅ No hay mezcla por conveniencia
✅ Controles diferentes por clasificación
✅ Evidencia: diagrama + configuración
En AWS, los activos no solo se inventarían: se aíslan por diseño.
A.9 – Control de acceso
Security Groups como control técnico primario
Este es uno de los mapeos más fuertes entre ISO 27001 y VPC.
Control A.9.1.2 - Acceso a redes y servicios de red:
Requisito ISO 27001:
"Los usuarios solo deben tener acceso a la red
y a los servicios de red que han sido autorizados."
Implementación VPC:
Security Groups = Firewall stateful
NACLs = Firewall stateless
Principio: deny by default, allow by exception
Ejemplo completo - Architecture 3-tier conforme:
# Terraform: Security Groups siguiendo ISO27001 A.9
# Tier 1: Load Balancer (punto de entrada)
resource "aws_security_group" "alb" {
name = "alb-public-sg"
description = "ALB public facing - ISO27001 A.9.1.2"
vpc_id = aws_vpc.production.id
# Solo HTTPS desde Internet
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS from Internet (justified: public service)"
}
# Redirect HTTP a HTTPS
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTP redirect to HTTPS"
}
# Salida solo a app tier
egress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.application.id]
description = "To application tier"
}
tags = {
Name = "alb-public-sg"
Tier = "load-balancer"
ISO27001Control = "A.9.1.2"
Justification = "Public facing service - business requirement"
}
}
# Tier 2: Application (backend lógico)
resource "aws_security_group" "application" {
name = "application-private-sg"
description = "Application tier - only from ALB (ISO27001 A.9.1.2)"
vpc_id = aws_vpc.production.id
# Solo desde ALB
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
description = "HTTP from ALB only"
}
# Salida a DB tier
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.database.id]
description = "PostgreSQL to database tier"
}
# Salida a Internet para APIs externas (vía NAT)
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS to external APIs"
}
tags = {
Name = "application-private-sg"
Tier = "application"
ISO27001Control = "A.9.1.2,A.9.4.1"
MinimumPrivilege = "true"
}
}
# Tier 3: Database (datos sensibles)
resource "aws_security_group" "database" {
name = "database-private-sg"
description = "Database tier - only from App (ISO27001 A.9.1.2)"
vpc_id = aws_vpc.production.id
# Solo desde App tier
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.application.id]
description = "PostgreSQL from application tier only"
}
# Egress mínimo (patching, backups a S3)
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [aws_vpc.production.cidr_block]
description = "HTTPS interno para AWS services (S3 via endpoint)"
}
tags = {
Name = "database-private-sg"
Tier = "data"
ISO27001Control = "A.9.1.2,A.9.4.1"
InternetAccess = "none"
Justification = "Data tier - no Internet access required"
}
}
# Security Group para VPC Endpoints
resource "aws_security_group" "vpc_endpoints" {
name = "vpc-endpoints-sg"
description = "Interface endpoints - ISO27001 A.9.1.2"
vpc_id = aws_vpc.production.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [aws_vpc.production.cidr_block]
description = "HTTPS from VPC CIDR"
}
tags = {
Name = "vpc-endpoints-sg"
Purpose = "Private access to AWS services"
ISO27001Control = "A.9.1.2,A.13.1.1"
}
}
Matriz de control de acceso documentada:
Matriz RACI - Seguridad de Red (ISO27001 A.9):
Security Group: alb-public-sg
Justificación: "Servicio público - requisito de negocio"
Reglas entrantes:
- 0.0.0.0/0:443 → ALB (HTTPS público)
- 0.0.0.0/0:80 → ALB (redirect a HTTPS)
Reglas salientes:
- ALB → application-sg:8080
Aprobado por: CISO + CTO
Revisión: Trimestral
Última revisión: 15/12/2025
Estado: COMPLIANT
Security Group: application-private-sg
Justificación: "Backend privado - mínimo privilegio"
Reglas entrantes:
- alb-sg:* → App:8080
Reglas salientes:
- App → database-sg:5432
- App → 0.0.0.0/0:443 (APIs externas)
Aprobado por: CTO + Lead Architect
Revisión: Trimestral
Última revisión: 15/12/2025
Estado: COMPLIANT
Security Group: database-private-sg
Justificación: "Datos sensibles - zero Internet"
Reglas entrantes:
- application-sg:* → DB:5432
Reglas salientes:
- DB → VPC CIDR:443 (S3 endpoint)
Aprobado por: CISO + DPO + CTO
Revisión: Mensual
Última revisión: 01/01/2026
Estado: COMPLIANT
Proceso de cambio:
1. Solicitud vía ticket (Jira/ServiceNow)
2. Justificación de negocio
3. Aprobación según matriz RACI
4. Implementación vía Terraform
5. Peer review obligatorio
6. Merge a main tras aprobación
7. Auditoría automática (AWS Config)
8. Registro en change log
Buenas prácticas alineadas con A.9:
Checklist Security Groups ISO27001:
✅ Reglas específicas por rol (frontend, backend, DB)
✅ Principio de mínimo privilegio
✅ Descripción en cada regla (justificación)
✅ Tags de compliance
✅ Gestión mediante IaC (trazabilidad)
✅ Sin 0.0.0.0/0 salvo justificación aprobada
✅ Revisión periódica documentada
✅ Naming convention consistente
✅ Separación por tiers
✅ Sin reglas "temporales" olvidadas
❌ Anti-patterns a evitar:
❌ Reglas genéricas sin justificación
❌ "allow all" por comodidad
❌ Cambios manuales (sin IaC)
❌ Sin revisión periódica
❌ Descripciones vacías
❌ Mezcla de entornos
❌ SGs compartidos entre tiers
Aquí puedes demostrar quién puede comunicarse con qué, sin ambigüedad.
A.10 – Criptografía
La VPC como canal seguro
Aunque el cifrado suele asociarse a datos, la VPC ayuda a garantizar protección en tránsito.
Control A.10.1.1 - Política de uso de controles criptográficos:
Política de cifrado en VPC:
Tráfico interno VPC:
- Por defecto: sin cifrado (confianza en red AWS)
- Decisión: TLS entre servicios críticos
- Justificación documentada
Tráfico a/desde Internet:
- Obligatorio: TLS 1.2+ (ALB, CloudFront)
- Enforcement: Security policies
Tráfico a servicios AWS:
- Preferencia: VPC Endpoints (tráfico privado)
- Si no hay endpoint: HTTPS obligatorio
- Sin tráfico HTTP sin cifrar
Tráfico híbrido (VPN/Direct Connect):
- VPN: IPsec obligatorio
- Direct Connect: MACsec o VPN over DX
Implementación - VPC Endpoints para cifrado sin Internet:
# Terraform: VPC Endpoints para tráfico cifrado privado
# Gateway Endpoint S3 (gratis, tráfico privado)
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.production.id
service_name = "com.amazonaws.us-east-1.s3"
route_table_ids = [
aws_route_table.application.id,
aws_route_table.database.id
]
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "EnforceTLS"
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = "*"
Condition = {
Bool = {
"aws:SecureTransport" = "false"
}
}
}
]
})
tags = {
Name = "s3-gateway-endpoint"
ISO27001Control = "A.10.1.1,A.13.2.1"
Purpose = "Private encrypted access to S3"
}
}
# Interface Endpoint Secrets Manager (tráfico cifrado privado)
resource "aws_vpc_endpoint" "secrets_manager" {
vpc_id = aws_vpc.production.id
service_name = "com.amazonaws.us-east-1.secretsmanager"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.application[*].id
security_group_ids = [aws_security_group.vpc_endpoints.id]
private_dns_enabled = true
tags = {
Name = "secretsmanager-interface-endpoint"
ISO27001Control = "A.10.1.1,A.10.1.2"
Purpose = "Private access to secrets without Internet"
}
}
# Endpoint policy: solo TLS
resource "aws_vpc_endpoint_policy" "secrets_manager" {
vpc_endpoint_id = aws_vpc_endpoint.secrets_manager.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Deny"
Principal = "*"
Action = "*"
Resource = "*"
Condition = {
Bool = {
"aws:SecureTransport" = "false"
}
}
}
]
})
}
ALB con TLS enforcement:
# Application Load Balancer con cifrado obligatorio
resource "aws_lb" "application" {
name = "production-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id
drop_invalid_header_fields = true # Seguridad adicional
tags = {
Name = "production-alb"
ISO27001Control = "A.10.1.1,A.13.2.1"
}
}
# Listener HTTPS con TLS 1.2+
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.application.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS-1-2-2017-01" # TLS 1.2+
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.application.arn
}
}
# Redirect HTTP a HTTPS (no tráfico sin cifrar)
resource "aws_lb_listener" "http_redirect" {
load_balancer_arn = aws_lb.application.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
El uso de VPC Endpoints y PrivateLink refuerza este control al eliminar rutas públicas innecesarias.
A.12 – Seguridad en las operaciones
Reducción de superficie de ataque
La VPC contribuye directamente a A.12 cuando está diseñada defensivamente.
Control A.12.6.1 - Gestión de las vulnerabilidades técnicas:
VPC como reductor de superficie de ataque:
Sin VPC bien diseñada:
❌ Sistemas expuestos innecesariamente
❌ Tráfico sin filtrar
❌ Rutas abiertas "por si acaso"
❌ Patching complejo (muchos puntos)
Con VPC bien diseñada:
✅ Solo ALB expuesto a Internet
✅ App tier sin IP pública
✅ DB tier totalmente privado
✅ Patching centralizado (Systems Manager)
✅ Actualizaciones vía VPC Endpoints
Implementación - Arquitectura defensiva:
# Terraform: VPC con mínima superficie de ataque
# NAT Gateway solo en subnets específicas (salida controlada)
resource "aws_eip" "nat" {
count = var.enable_nat ? 3 : 0
domain = "vpc"
tags = {
Name = "nat-gateway-eip-${count.index + 1}"
ISO27001Control = "A.12.6.1"
Purpose = "Controlled egress to Internet"
}
}
resource "aws_nat_gateway" "main" {
count = var.enable_nat ? 3 : 0
allocation_id = aws_eip.nat[count.index].id
subnet_id = aws_subnet.public[count.index].id
tags = {
Name = "nat-gateway-${count.index + 1}"
ISO27001Control = "A.12.6.1"
}
}
# Route table con egress controlado
resource "aws_route_table" "application_private" {
vpc_id = aws_vpc.production.id
# Default route SOLO si NAT habilitado
dynamic "route" {
for_each = var.enable_nat ? [1] : []
content {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main[0].id
}
}
# Rutas específicas a VPC Endpoints (sin Internet)
route {
cidr_block = data.aws_prefix_list.s3.cidr_blocks[0]
vpc_endpoint_id = aws_vpc_endpoint.s3.id
}
tags = {
Name = "application-private-route-table"
ISO27001Control = "A.12.6.1"
InternetAccess = var.enable_nat ? "via-nat" : "none"
}
}
# NACLs como defensa adicional
resource "aws_network_acl" "database" {
vpc_id = aws_vpc.production.id
subnet_ids = aws_subnet.database[*].id
# Deny explícito para rangos sospechosos
ingress {
rule_no = 100
action = "deny"
protocol = -1
cidr_block = "0.0.0.0/0" # Deny all por defecto
from_port = 0
to_port = 0
}
# Allow solo desde app tier
ingress {
rule_no = 110
action = "allow"
protocol = "tcp"
cidr_block = aws_subnet.application[0].cidr_block
from_port = 5432
to_port = 5432
}
egress {
rule_no = 100
action = "allow"
protocol = -1
cidr_block = "0.0.0.0/0"
from_port = 0
to_port = 0
}
tags = {
Name = "database-nacl"
ISO27001Control = "A.12.6.1,A.13.1.1"
Purpose = "Additional layer of defense"
}
}
Desde ISO, esto es prevención técnica, no reacción operativa.
A.13 – Seguridad en las comunicaciones
Segmentación y control del flujo de red
Este es el dominio donde la VPC brilla más en auditorías ISO 27001.
Control A.13.1.1 - Controles de red:
ISO 27001 A.13.1.1 - Requisitos:
"Las redes deben ser gestionadas y controladas
para proteger la información en sistemas y aplicaciones."
VPC como implementación técnica:
✅ Segmentación en subredes (públicas/privadas/datos)
✅ Route tables diferenciadas por tier
✅ Security Groups como firewall stateful
✅ NACLs como firewall stateless
✅ Flow Logs para visibilidad completa
✅ VPC Endpoints para tráfico privado
✅ Transit Gateway para multi-VPC
Diagrama de segmentación auditable:
Arquitectura de segmentación VPC (ISO27001 A.13):
┌─────────────────────────────────────────────────────────┐
│ Internet │
└──────────────────────┬──────────────────────────────────┘
│
┌───────────▼────────────┐
│ Internet Gateway │
│ (1 por VPC) │
└───────────┬────────────┘
│
┌──────────────────▼─────────────────────┐
│ Public Subnets (10.16.0.0/20) │
│ - ALB (punto de entrada único) │
│ - NAT Gateways (salida controlada) │
│ - CloudFront Origins │
│ ISO27001: A.13.1.1, A.13.1.3 │
└──────────────────┬─────────────────────┘
│
┌──────────────────▼─────────────────────┐
│ Private Subnets - App (10.16.16.0/20) │
│ - EC2, ECS, EKS workloads │
│ - Sin IP pública │
│ - Egress vía NAT Gateway │
│ ISO27001: A.13.1.1, A.13.1.2 │
└──────────────────┬─────────────────────┘
│
┌──────────────────▼─────────────────────┐
│ Private Subnets - Data (10.16.32.0/20)│
│ - RDS, DynamoDB, ElastiCache │
│ - Sin Internet (nunca) │
│ - Solo acceso desde App tier │
│ ISO27001: A.13.1.1, A.13.2.1 │
└────────────────────────────────────────┘
Flujos de tráfico documentados:
1. Internet → ALB (HTTPS:443)
2. ALB → App tier (HTTP:8080)
3. App tier → DB tier (PostgreSQL:5432)
4. App tier → Internet (HTTPS:443 vía NAT)
5. App tier → AWS Services (vía VPC Endpoints)
Evidencia auditable:
✅ Diagrama actualizado
✅ Route tables exportadas
✅ Security Groups documentados
✅ Flow Logs activos
✅ Revisión trimestral
Control A.13.1.3 - Segregación en redes:
# Terraform: Segregación completa por función
# VPC dedicada por entorno (aislamiento total)
resource "aws_vpc" "production" {
cidr_block = "10.16.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "production-vpc"
Environment = "production"
ISO27001Control = "A.13.1.3"
Segregation = "environment-based"
}
}
resource "aws_vpc" "development" {
cidr_block = "10.17.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "development-vpc"
Environment = "development"
ISO27001Control = "A.13.1.3"
Segregation = "environment-based"
}
}
# Sin VPC Peering entre Prod y Dev (aislamiento estricto)
# Comunicación solo vía Shared Services si necesario
Flow Logs para auditoría (A.12.4.1):
# VPC Flow Logs - evidencia de tráfico
resource "aws_flow_log" "production" {
log_destination_type = "cloud-watch-logs"
log_destination = aws_cloudwatch_log_group.vpc_flow_logs.arn
traffic_type = "ALL" # ACCEPT + REJECT
vpc_id = aws_vpc.production.id
iam_role_arn = aws_iam_role.flow_logs.arn
tags = {
Name = "production-vpc-flow-logs"
ISO27001Control = "A.12.4.1,A.13.1.1"
Purpose = "Network traffic audit trail"
}
}
# Retención según política
resource "aws_cloudwatch_log_group" "vpc_flow_logs" {
name = "/aws/vpc/production/flow-logs"
retention_in_days = 90 # 3 meses para análisis
tags = {
ISO27001Control = "A.12.4.1"
RetentionPolicy = "90-days-operational"
}
}
# Export a S3 para largo plazo (7 años compliance)
resource "aws_flow_log" "production_s3" {
log_destination_type = "s3"
log_destination = "${aws_s3_bucket.compliance_logs.arn}/vpc-flow-logs/"
traffic_type = "ALL"
vpc_id = aws_vpc.production.id
destination_options {
file_format = "parquet"
per_hour_partition = true
}
tags = {
Name = "production-vpc-flow-logs-archive"
ISO27001Control = "A.12.4.1,A.18.1.3"
Purpose = "Long-term compliance archive"
}
}
Un auditor puede entender fácilmente: qué sistemas están expuestos, cuáles no, qué caminos existen entre ellos. Eso es exactamente lo que exige A.13.
A.14 – Adquisición, desarrollo y mantenimiento
Entornos separados por diseño
Control A.14.2.6 exige separación de entornos de desarrollo, testing y producción.
Implementación conforme:
Separación de entornos ISO27001:
Opción 1 - VPCs separadas (recomendado):
VPC Development (10.17.0.0/16)
VPC Testing (10.18.0.0/16)
VPC Production (10.16.0.0/16)
Ventajas:
✅ Aislamiento total
✅ Blast radius contenido
✅ IAM policies diferentes
✅ Sin riesgo de acceso cruzado
✅ Auditoría simplificada
Opción 2 - Cuentas AWS separadas (ideal):
Account Development (123456789012)
Account Testing (234567890123)
Account Production (345678901234)
Ventajas:
✅ Aislamiento máximo
✅ Límites de servicio independientes
✅ Costes separados
✅ Compliance más claro
✅ Eliminación de riesgo técnico
Opción 3 - Subnets separadas (NO recomendado):
❌ Mismo VPC, diferentes subnets
❌ Riesgo de error humano
❌ Complejidad de Security Groups
❌ No aceptable para auditoría estricta
Implementación multi-cuenta con Organizations:
# Terraform: AWS Organizations para separación de entornos
# Organization principal
resource "aws_organizations_organization" "main" {
aws_service_access_principals = [
"cloudtrail.amazonaws.com",
"config.amazonaws.com",
"sso.amazonaws.com"
]
feature_set = "ALL"
enabled_policy_types = [
"SERVICE_CONTROL_POLICY",
"TAG_POLICY"
]
}
# OU Development
resource "aws_organizations_organizational_unit" "development" {
name = "Development"
parent_id = aws_organizations_organization.main.roots[0].id
tags = {
Environment = "development"
ISO27001Control = "A.14.2.6"
Purpose = "Development workloads isolation"
}
}
# OU Production
resource "aws_organizations_organizational_unit" "production" {
name = "Production"
parent_id = aws_organizations_organization.main.roots[0].id
tags = {
Environment = "production"
ISO27001Control = "A.14.2.6"
Purpose = "Production workloads isolation"
}
}
# SCP: Development no puede acceder a Production
resource "aws_organizations_policy" "deny_prod_access_from_dev" {
name = "DenyProductionAccessFromDevelopment"
description = "ISO27001 A.14.2.6 - Prevent dev access to prod"
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "DenyAssumeRoleToProd"
Effect = "Deny"
Action = "sts:AssumeRole"
Resource = "arn:aws:iam::${var.production_account_id}:role/*"
}
]
})
}
resource "aws_organizations_policy_attachment" "deny_prod_dev" {
policy_id = aws_organizations_policy.deny_prod_access_from_dev.id
target_id = aws_organizations_organizational_unit.development.id
}
La VPC permite aislar entornos por VPC o cuenta, evitar accesos cruzados accidentales, limitar el impacto de errores humanos. Aquí la red actúa como barrera de contención, algo muy valorado en auditoría.
A.15 – Relación con proveedores
AWS bajo responsabilidad compartida
Control A.15.1.1 exige gestión de proveedores. Con AWS, esto se materializa en entender el Shared Responsibility Model.
Documentación para auditoría:
Modelo de Responsabilidad Compartida - VPC:
AWS es responsable de:
✅ Infraestructura física de red
✅ Hipervisor y virtualización
✅ Aislamiento entre clientes
✅ Hardware de red (routers, switches)
✅ Zonas de disponibilidad
✅ Certificaciones: ISO 27001, SOC 2, PCI-DSS
Tu organización es responsable de:
✅ Diseño de VPC (CIDR, subnets)
✅ Route tables y routing
✅ Security Groups y NACLs
✅ VPC Endpoints y PrivateLink
✅ VPN y Direct Connect
✅ Flow Logs y monitoring
✅ IAM policies de red
✅ Segregación de entornos
✅ Compliance de configuración
Evidencia para auditoría:
✅ AWS Artifact (certificados AWS)
✅ Diagrama de arquitectura VPC
✅ Terraform/IaC (configuración tuya)
✅ AWS Config Rules (compliance)
✅ Auditoría de cambios (CloudTrail)
Registro de proveedor AWS:
Ficha de proveedor - Amazon Web Services:
Datos del proveedor:
Nombre: Amazon Web Services, Inc.
Servicio: Cloud Infrastructure (VPC)
Clasificación: Crítico
Datos procesados: Todos (infraestructura)
Certificaciones verificadas:
✅ ISO 27001:2013
✅ ISO 27017 (cloud security)
✅ ISO 27018 (privacy)
✅ SOC 2 Type II
✅ PCI-DSS Level 1
✅ GDPR compliance
Documentos compliance:
- AWS Artifact: certificados descargados
- Shared Responsibility Model: revisado
- Security whitepaper: analizado
Due diligence realizada:
Fecha: Q4 2025
Responsable: CISO
Resultado: APROBADO
Próxima revisión: Q4 2026
Contratos:
- AWS Customer Agreement
- AWS GDPR DPA (firmado)
- BAA si aplica (HIPAA)
Controles implementados:
✅ VPC configurada según best practices
✅ Encryption at rest habilitado
✅ Encryption in transit forzado
✅ Logging completo activo
✅ Multi-factor authentication
✅ Least privilege IAM
La VPC ayuda a demostrar que AWS gestiona la infraestructura física, tú gestionas el diseño, el acceso y el aislamiento. Este punto es clave para explicar el modelo de responsabilidad compartida sin ambigüedades.
A.18 – Cumplimiento
Evidencias claras y repetibles
Control A.18.1.1 exige identificar requisitos legales. A.18.2.2 exige revisión de compliance.
Checklist de cumplimiento VPC:
Checklist ISO 27001 - VPC Compliance:
□ Gestión de activos (A.8):
□ VPC registrada en inventario
□ Subnets clasificadas y etiquetadas
□ Owners asignados
□ Revisión trimestral ejecutada
□ Documentación actualizada
□ Control de acceso (A.9):
□ Security Groups con mínimo privilegio
□ NACLs configuradas
□ Sin reglas 0.0.0.0/0 injustificadas
□ Matriz de acceso documentada
□ Revisión mensual de permisos
□ Criptografía (A.10):
□ TLS enforcement en ALB
□ VPC Endpoints con TLS
□ Endpoint policies configuradas
□ Sin tráfico HTTP sin cifrar
□ Operaciones seguras (A.12):
□ Flow Logs activos
□ CloudTrail monitoreando cambios
□ NAT Gateway configurado
□ Patching vía Systems Manager
□ Sin bastion hosts (usar SSM)
□ Seguridad comunicaciones (A.13):
□ Segmentación implementada
□ Route tables documentadas
□ Diagrama de red actualizado
□ Tráfico filtrado por SGs
□ Aislamiento de tiers verificado
□ Separación entornos (A.14):
□ Prod/Dev en VPCs separadas
□ O en cuentas separadas
□ Sin acceso cruzado
□ SCPs aplicadas (si multi-cuenta)
□ Compliance continuo (A.18):
□ AWS Config Rules activas
□ Alertas de no conformidad
□ Remediation automática
□ Reportes mensuales generados
AWS Config para compliance continuo:
# Terraform: AWS Config Rules para VPC compliance
resource "aws_config_config_rule" "vpc_flow_logs_enabled" {
name = "vpc-flow-logs-enabled-iso27001"
source {
owner = "AWS"
source_identifier = "VPC_FLOW_LOGS_ENABLED"
}
scope {
compliance_resource_types = ["AWS::EC2::VPC"]
}
tags = {
ISO27001Control = "A.12.4.1,A.13.1.1"
Compliance = "required"
}
}
resource "aws_config_config_rule" "vpc_default_security_group_closed" {
name = "vpc-default-sg-closed-iso27001"
source {
owner = "AWS"
source_identifier = "VPC_DEFAULT_SECURITY_GROUP_CLOSED"
}
tags = {
ISO27001Control = "A.9.1.2"
Compliance = "required"
}
}
resource "aws_config_config_rule" "vpc_sg_open_only_to_authorized_ports" {
name = "vpc-sg-restricted-common-ports-iso27001"
source {
owner = "AWS"
source_identifier = "VPC_SG_OPEN_ONLY_TO_AUTHORIZED_PORTS"
}
input_parameters = jsonencode({
authorizedTcpPorts = "443" # Solo HTTPS autorizado desde Internet
})
tags = {
ISO27001Control = "A.9.1.2,A.13.1.1"
Compliance = "required"
}
}
# Dashboard de compliance
resource "aws_config_configuration_aggregator" "iso27001" {
name = "iso27001-compliance-aggregator"
account_aggregation_source {
account_ids = [
data.aws_caller_identity.current.account_id
]
all_regions = true
}
tags = {
Purpose = "ISO27001 compliance monitoring"
ISO27001Control = "A.18.2.2"
}
}
Una VPC bien diseñada facilita el cumplimiento porque: los diagramas son evidencia, las reglas son exportables, el diseño es consistente en el tiempo. No dependes de explicaciones verbales. La arquitectura habla por ti.
Tabla resumen: VPC ↔ Anexo A
| Control ISO 27001 | Elemento VPC | Evidencia típica | Implementación |
|---|---|---|---|
| A.5 - Políticas | Diseño de subredes | Diagrama de red + justificación | Subnets privadas sin IGW |
| A.8 - Activos | Aislamiento por subnet/VPC | Tags + inventario | VPCs separadas por entorno |
| A.9 - Acceso | Security Groups | Reglas exportadas + matriz RACI | SGs con mínimo privilegio |
| A.10 - Cifrado | VPC Endpoints + TLS | Endpoint policies + ALB config | TLS enforcement |
| A.12 - Operaciones | Routing + NAT + Flow Logs | Route tables + logs S3 | NAT controlado + logging |
| A.13 - Comunicaciones | Segmentación | Diagrama + Flow Logs | Public/Private/Data tiers |
| A.14 - Desarrollo | Separación entornos | Cuentas/VPCs separadas | Multi-account structure |
| A.15 - Proveedores | Shared Responsibility | AWS Artifact + docs | Modelo documentado |
| A.18 - Compliance | Todo lo anterior | IaC + Config Rules | Terraform + AWS Config |
Documentación para auditoría
Paquete de evidencias VPC:
Evidencias entregables auditoría ISO27001:
1. Arquitectura VPC:
✅ Diagrama actualizado (Lucidchart/draw.io)
✅ Descripción de cada componente
✅ Justificación de decisiones de diseño
✅ Changelog de arquitectura
2. Configuración técnica:
✅ Export Terraform completo
✅ VPC CIDR allocation plan
✅ Subnet allocation table
✅ Route tables documentadas
✅ Security Groups exportados
✅ NACLs configuradas
3. Controles de acceso:
✅ Matriz RACI de accesos
✅ IAM policies de red
✅ Registro de revisiones
✅ Procedimiento de cambios
4. Logging y monitoreo:
✅ VPC Flow Logs activos (screenshot)
✅ CloudTrail para cambios VPC
✅ Config Rules compliance report
✅ Security Hub findings
5. Separación de entornos:
✅ Multi-account structure
✅ SCPs aplicadas
✅ Evidencia de aislamiento
✅ Proceso de promoción code
6. Compliance continuo:
✅ AWS Config dashboard
✅ Reportes mensuales
✅ No conformidades y remediación
✅ Mejoras implementadas
7. Procedimientos:
✅ Runbook creación VPC
✅ Procedimiento cambio Security Groups
✅ Proceso de revisión trimestral
✅ Plan de respuesta a incidentes red
Conclusión: cuando el SGSI se apoya en arquitectura
El mejor SGSI es el que no depende de la buena voluntad de las personas. Depende de decisiones técnicas que hacen difícil equivocarse.
Comparativa de madurez:
Organización inmadura (VPC como requisito):
❌ VPC creada "porque AWS lo pide"
❌ Configuración manual sin documentar
❌ Cambios ad-hoc sin proceso
❌ Sin revisión periódica
❌ Documentación desactualizada
❌ Evidencias improvisadas en auditoría
Resultado:
- 5-10 no conformidades
- Plan de acción correctiva extenso
- Revisión en 3-6 meses
- Certificación en riesgo
Organización madura (VPC como control):
✅ VPC diseñada conscientemente
✅ IaC (Terraform) para todo
✅ Cambios vía pull request + review
✅ Revisión trimestral documentada
✅ Arquitectura actualizada
✅ Evidencias listas permanentemente
Resultado:
- 0-1 no conformidades menores
- Auditoría fluida y rápida
- Auditor satisfecho
- Certificación sin observaciones
Una VPC bien diseñada:
- ✅ Reduce riesgos estructurales (blast radius contenido)
- ✅ Simplifica auditorías (evidencias claras)
- ✅ Refuerza el discurso ISO (controles técnicos verificables)
- ✅ Hace el cumplimiento sostenible (automatización)
La realidad que nadie te cuenta:
ISO 27001 no se pasa con:
❌ Documentos PDF brillantes
❌ Políticas copiadas de Internet
❌ PowerPoints impresionantes
❌ Promesas de mejora futura
ISO 27001 se pasa con:
✅ Arquitecturas aburridas y claras
✅ Controles técnicos verificables
✅ Procesos sostenibles en el tiempo
✅ Evidencias objetivas y repetibles
✅ Diseño que previene errores
Cuando tu VPC está bien pensada, la auditoría es una conversación técnica, no un examen sorpresa.
Y eso, al final, es exactamente lo que busca ISO 27001: demostrar control real, no intenciones documentadas.