Gestionando Políticas de Servicio (SCP) en AWS Organizations con Terraform: Control Centralizado de Permisos
Este tutorial te guiará a través de la gestión de Políticas de Control de Servicio (SCP) en AWS Organizations utilizando Terraform. Aprenderás a crear, adjuntar y actualizar SCPs para imponer restricciones de permisos a nivel de cuenta o unidad organizativa, fortaleciendo la seguridad y el cumplimiento en tu infraestructura en la nube.
🚀 Introducción: Centralizando el Control con AWS Organizations y Terraform
En entornos de nube complejos y escalables, la gestión de permisos se convierte en un desafío. AWS Organizations ofrece una solución robusta para consolidar múltiples cuentas de AWS en una única organización, facilitando la gestión centralizada de facturación, acceso y cumplimiento. Una característica clave de AWS Organizations son las Políticas de Control de Servicio (SCPs), que te permiten definir permisos máximos para todas las cuentas dentro de una Unidad Organizativa (OU) o para cuentas individuales.
Sin embargo, gestionar estas SCPs manualmente puede ser propenso a errores y poco escalable. Aquí es donde Terraform, una herramienta de Infraestructura como Código (IaC), brilla. Al codificar tus SCPs en Terraform, puedes versionar, revisar y desplegar tus políticas de forma consistente y automatizada.
Este tutorial te mostrará cómo aprovechar la potencia de Terraform para gestionar tus SCPs, garantizando que tu arquitectura de seguridad sea robusta, auditable y fácil de mantener.
🎯 ¿Qué son las Políticas de Control de Servicio (SCPs)?
Las SCPs son un tipo de política de AWS Organizations que especifican los permisos máximos para todas las cuentas que están bajo su influencia. Actúan como un "filtro de permisos" global, lo que significa que ninguna entidad (usuario o rol de IAM) en una cuenta afectada puede realizar una acción si esa acción está explícitamente denegada por una SCP, incluso si una política de IAM adjunta a esa entidad la permite.
Características Clave de las SCPs:
- Guardias de Permisos: Establecen los límites máximos para los permisos dentro de una organización.
- Denegación Explícita: Son más poderosas cuando deniegan explícitamente acciones, ya que una denegación explícita anula cualquier permiso.
- No otorgan permisos: Las SCPs nunca otorgan permisos; solo restringen lo que otras políticas (como las de IAM) pueden otorgar.
- Aplicación a nivel de OU/Cuenta: Se pueden adjuntar a la raíz de la organización, a unidades organizativas (OUs) o a cuentas individuales.
SCPs vs. Políticas de IAM
Es fundamental entender la diferencia entre SCPs y las políticas de IAM. Piensa en las SCPs como la "constitución" de tu organización de AWS, mientras que las políticas de IAM son las "leyes" específicas dentro de cada "estado" (cuenta).
| Característica | SCP (Service Control Policy) | Política de IAM (Identity and Access Management) |
|---|---|---|
| --- | --- | --- |
| Propósito | Establece permisos máximos a nivel de organización/OU/cuenta. Restringe. | Otorga o deniega permisos específicos a identidades (usuarios/roles). |
| Ámbito | Cuentas AWS dentro de una Organización. | Entidades IAM (usuarios, roles, grupos) dentro de una cuenta. |
| --- | --- | --- |
| Otorgan Permisos | ❌ No otorgan permisos. | ✅ Sí, otorgan permisos. |
| Denegación | La denegación explícita anula todo. | La denegación explícita anula todo dentro de la cuenta. |
| --- | --- | --- |
| Herencia | Se heredan de la raíz a las OUs y a las cuentas. | No se heredan entre cuentas. |
| Uso Principal | Control de gobernanza, cumplimiento, seguridad preventiva. | Control de acceso granular para usuarios y aplicaciones. |
🛠️ Requisitos Previos
Antes de empezar, asegúrate de tener lo siguiente:
- AWS CLI configurado: Acceso programático a tu cuenta de gestión de AWS Organizations.
- Terraform instalado: Versión 1.0 o superior.
- AWS Organizations habilitado: Y con todas las características activadas.
- Permisos adecuados: Tu usuario o rol de IAM debe tener permisos para crear, adjuntar y eliminar SCPs en AWS Organizations, así como para leer información de OUs y cuentas. Ejemplos de permisos:
organizations:CreatePolicyorganizations:AttachPolicyorganizations:DetachPolicyorganizations:DeletePolicyorganizations:ListPoliciesorganizations:ListRootsorganizations:ListOrganizationalUnitsForParentorganizations:ListAccountsForParent
⚙️ Estructura del Proyecto Terraform
Para este tutorial, utilizaremos una estructura de directorios simple para organizar nuestros archivos Terraform:
.
├── main.tf
├── variables.tf
├── providers.tf
├── scp_policies.tf
└── outputs.tf
✍️ Configurando Terraform para AWS Organizations
Primero, definiremos el proveedor de AWS y el backend de Terraform. Usaremos un backend S3 para almacenar el estado de Terraform de forma remota, lo cual es una buena práctica para equipos y para mantener la resiliencia.
providers.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "tu-bucket-tfstate-organizations"
key = "organizations/scp/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "tu-dynamodb-lock-table"
}
}
provider "aws" {
region = "us-east-1"
# Asegúrate de que tus credenciales estén configuradas correctamente
# a través de variables de entorno, archivo ~/.aws/credentials o roles de IAM.
}
variables.tf
variable "organization_root_id" {
description = "ID de la raíz de la organización de AWS."
type = string
# Puedes obtener esto con `aws organizations list-roots`
}
variable "ou_dev_id" {
description = "ID de la unidad organizativa de Desarrollo."
type = string
# Puedes obtener esto con `aws organizations list-organizational-units-for-parent --parent-id <root_id>`
}
variable "ou_prod_id" {
description = "ID de la unidad organizativa de Producción."
type = string
}
variable "account_sandbox_id" {
description = "ID de la cuenta Sandbox específica."
type = string
}
📝 Definiendo nuestras SCPs
Ahora, vamos a definir algunas SCPs comunes en el archivo scp_policies.tf. Cada SCP es un recurso aws_organizations_policy con un tipo SERVICE_CONTROL_POLICY.
scp_policies.tf
# SCP 1: Denegar el abandono de la organización
resource "aws_organizations_policy" "prevent_leave_organization" {
name = "PreventLeaveOrganization"
description = "Deniega la capacidad de las cuentas para abandonar la organización."
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Deny",
Action = "organizations:LeaveOrganization",
Resource = "*"
}
]
})
}
# SCP 2: Denegar el acceso a la región de us-east-1 (ejemplo de restricción geográfica)
# Este es un ejemplo. En un escenario real, denegarías regiones no permitidas para tu negocio.
resource "aws_organizations_policy" "deny_us_east_1_region" {
name = "DenyUsEast1Region"
description = "Deniega todas las acciones en la región us-east-1."
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Deny",
NotAction = [
"s3:*", # Excluir S3 para permitir acceso a buckets globales como logs de CloudTrail
"cloudfront:*",
"iam:*",
"sts:*",
"route53:*",
"organizations:*",
"support:*",
"health:*",
"directconnect:*",
"waf:*"
],
Resource = "*",
Condition = {
"StringNotEquals" = {
"aws:RequestedRegion" = [
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2"
] # Regiones permitidas (ejemplo, ajusta según tu necesidad)
}
}
},
{
# Permitir acciones globales que no tienen región específica
Effect = "Allow",
Action = [
"s3:*",
"cloudfront:*",
"iam:*",
"sts:*",
"route53:*",
"organizations:*",
"support:*",
"health:*",
"directconnect:*",
"waf:*"
],
Resource = "*"
}
]
})
}
# SCP 3: Denegar el uso de servicios específicos (ej. Amazon EC2 y S3) para cuentas de desarrollo
# Este ejemplo es más restrictivo y podría ser útil para entornos de pruebas muy controlados.
resource "aws_organizations_policy" "deny_ec2_s3_dev" {
name = "DenyEC2S3Dev"
description = "Deniega el uso de EC2 y S3 para cuentas en la OU de Desarrollo."
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Deny",
Action = [
"ec2:*",
"s3:*"
],
Resource = "*"
}
]
})
}
# SCP 4: Requerir MFA para acciones sensibles (ejemplo)
resource "aws_organizations_policy" "require_mfa_for_sensitive_actions" {
name = "RequireMFAForSensitiveActions"
description = "Requiere MFA para acciones administrativas sensibles."
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Deny",
Action = [
"iam:*",
"organizations:*"
],
Resource = "*",
Condition = {
"BoolIfExists" = {
"aws:MultiFactorAuthPresent" = "false"
}
}
}
]
})
}
Entendiendo la SCP de Denegación de Región (DenyUsEast1Region)
La SCP `deny_us_east_1_region` es un ejemplo avanzado. Su objetivo es denegar cualquier acción en una región específica (en este caso, `us-east-1` por simplicidad, pero se puede extender a cualquier región que *no* quieras permitir). Sin embargo, hay servicios globales de AWS (como IAM, S3, CloudFront, Route 53, Organizations, etc.) que no están asociados a una región específica, o que tienen endpoints globales pero se gestionan desde `us-east-1` de forma predeterminada, o que son necesarios para el funcionamiento básico.La política usa NotAction para excluir los servicios globales de la denegación y un Condition con StringNotEquals en aws:RequestedRegion para aplicar la denegación solo si la región solicitada no está en la lista de regiones permitidas. La segunda declaración Allow es crucial para permitir explícitamente las acciones globales que fueron excluidas de la primera denegación, evitando interrupciones en servicios como IAM.
Es un ejemplo complejo y requiere un ajuste cuidadoso según las regiones que quieras permitir y los servicios globales que uses.
🔗 Adjuntando SCPs a la Organización, OUs y Cuentas
Para aplicar las SCPs, necesitamos adjuntarlas a los objetivos deseados. En este ejemplo, adjuntaremos algunas a la raíz de la organización, otras a una OU y una a una cuenta específica. Usaremos bloques aws_organizations_policy_attachment.
main.tf
# Obtener el ID de la raíz de la organización dinámicamente
data "aws_organizations_organization" "current" {}
resource "aws_organizations_policy_attachment" "attach_prevent_leave_root" {
policy_id = aws_organizations_policy.prevent_leave_organization.id
target_id = data.aws_organizations_organization.current.id
}
# Adjuntar la política de denegación de región a la raíz de la organización
resource "aws_organizations_policy_attachment" "attach_deny_us_east_1_root" {
policy_id = aws_organizations_policy.deny_us_east_1_region.id
target_id = data.aws_organizations_organization.current.id
}
# Adjuntar la política de denegar EC2/S3 a la OU de Desarrollo
resource "aws_organizations_policy_attachment" "attach_deny_ec2_s3_dev_ou" {
policy_id = aws_organizations_policy.deny_ec2_s3_dev.id
target_id = var.ou_dev_id
}
# Adjuntar la política de requerir MFA a una cuenta específica (Sandbox)
resource "aws_organizations_policy_attachment" "attach_require_mfa_sandbox_account" {
policy_id = aws_organizations_policy.require_mfa_for_sensitive_actions.id
target_id = var.account_sandbox_id
}
outputs.tf
Para verificar que nuestras políticas se han creado y adjuntado, podemos definir algunas salidas:
output "prevent_leave_organization_policy_id" {
description = "ID de la política 'PreventLeaveOrganization'."
value = aws_organizations_policy.prevent_leave_organization.id
}
output "deny_us_east_1_region_policy_id" {
description = "ID de la política 'DenyUsEast1Region'."
value = aws_organizations_policy.deny_us_east_1_region.id
}
output "deny_ec2_s3_dev_policy_id" {
description = "ID de la política 'DenyEC2S3Dev'."
value = aws_organizations_policy.deny_ec2_s3_dev.id
}
output "require_mfa_for_sensitive_actions_policy_id" {
description = "ID de la política 'RequireMFAForSensitiveActions'."
value = aws_organizations_policy.require_mfa_for_sensitive_actions.id
}
🏃 Ejecutando Terraform
Con todos los archivos creados, es hora de ejecutar Terraform para aplicar nuestras SCPs.
Paso 1: Inicializar Terraform
Abre tu terminal en el directorio raíz de tu proyecto Terraform y ejecuta:
terraform init
Esto inicializará el backend S3 y descargará los plugins del proveedor de AWS.
Paso 2: Planificar los Cambios
Antes de aplicar, es crucial revisar el plan de ejecución. Esto te mostrará qué recursos creará, modificará o eliminará Terraform.
terraform plan \
-var 'organization_root_id="r-xxxx"' \
-var 'ou_dev_id="ou-xxxx-xxxxxxxx"' \
-var 'ou_prod_id="ou-xxxx-yyyyyyyy"' \
-var 'account_sandbox_id="123456789012"'
¡Importante! Reemplaza los valores de organization_root_id, ou_dev_id, ou_prod_id y account_sandbox_id con los IDs reales de tu organización, OUs y cuentas. Puedes obtener estos IDs desde la consola de AWS Organizations o usando el AWS CLI:
- ID de la raíz:
aws organizations list-roots - ID de las OUs:
aws organizations list-organizational-units-for-parent --parent-id <root_id> - ID de las cuentas:
aws organizations list-accounts
Revisa cuidadosamente la salida del plan para asegurarte de que Terraform va a crear y adjuntar las políticas esperadas.
Paso 3: Aplicar los Cambios
Si el plan es satisfactorio, procede a aplicar los cambios:
terraform apply \
-var 'organization_root_id="r-xxxx"' \
-var 'ou_dev_id="ou-xxxx-xxxxxxxx"' \
-var 'ou_prod_id="ou-xxxx-yyyyyyyy"' \
-var 'account_sandbox_id="123456789012"'
Terraform te pedirá confirmación. Escribe yes y presiona Enter para continuar.
Una vez que Terraform haya terminado, verás los IDs de las políticas en la sección de outputs.
✅ Verificación y Pruebas
Después de aplicar las SCPs, es crucial verificar que funcionan como se espera.
- Consola de AWS Organizations: Navega a la consola de AWS Organizations -> Políticas -> Políticas de control de servicio. Deberías ver tus políticas creadas. También puedes ir a la raíz de tu organización, a una OU o a una cuenta y ver las políticas adjuntas.
- Prueba de Denegación de Abandono: Intenta iniciar sesión en una de las cuentas miembro y, como usuario con permisos administrativos, intenta abandonar la organización. Deberías recibir un error de acceso denegado (
AccessDeniedException). - Prueba de Denegación de Región (si aplica): En una cuenta afectada por la SCP de denegación de región, intenta crear un recurso (por ejemplo, una instancia EC2 o un bucket S3) en la región denegada (
us-east-1en nuestro ejemplo). Deberías recibir un error de acceso denegado. - Prueba de Denegación EC2/S3 en OU Dev: En una cuenta de la OU de Desarrollo, intenta crear una instancia EC2 o un bucket S3. Debería ser denegado.
- Prueba de Requerir MFA: En la cuenta Sandbox, intenta realizar una acción sensible de IAM sin MFA. Debería ser denegada.
Ejemplo de prueba CLI para PreventLeaveOrganization
Desde una cuenta miembro afectada (asegúrate de que tu CLI esté configurado para esa cuenta):
aws organizations leave-organization
Deberías obtener un error similar a:
An error occurred (AccessDeniedException) when calling the LeaveOrganization operation: You are not authorized to perform this operation. You must have permissions for organizations:LeaveOrganization.
Este error, a pesar de tener quizás organizations:* en un rol de IAM, demuestra que la SCP está funcionando como un "guardián" de permisos.
🔄 Actualización y Eliminación de SCPs
Actualizar una SCP
Para actualizar una SCP, simplemente modifica el contenido jsonencode del recurso aws_organizations_policy en tu archivo scp_policies.tf. Luego, ejecuta terraform plan y terraform apply.
Terraform detectará el cambio en el content y actualizará la política existente en AWS Organizations.
Eliminar una SCP
- Desadjuntar la política: Elimina el recurso
aws_organizations_policy_attachmentasociado a la política que quieres eliminar demain.tf. Ejecutaterraform apply. Esto desadjuntará la política de sus objetivos. - Eliminar la política: Una vez desadjuntada, puedes eliminar el recurso
aws_organizations_policydescp_policies.tf. Ejecutaterraform applynuevamente. Esto eliminará la política de AWS Organizations.
💡 Buenas Prácticas y Consideraciones Avanzadas
- Principio de Privilegio Mínimo: Las SCPs deben seguir el principio de privilegio mínimo, denegando explícitamente solo lo que es absolutamente necesario.
- Pruebas Rigurosas: Siempre prueba las SCPs en entornos de desarrollo o en OUs de prueba dedicadas antes de desplegarlas en producción.
- Versión de Políticas: Utiliza el control de versiones de Git para tus archivos Terraform, incluyendo las definiciones de SCPs, para rastrear cambios y facilitar las reversiones.
- Organización de Políticas: Mantén tus SCPs organizadas y bien documentadas. Considera crear módulos Terraform para SCPs complejas o reutilizables.
- Herencia de SCPs: Recuerda que las SCPs se heredan. Una política adjunta a la raíz afecta a toda la organización. Las políticas en una OU afectan a esa OU y a todas las OUs anidadas y cuentas. Una denegación explícita en cualquier nivel anula los permisos superiores.
- Denegar todo por defecto: Una estrategia común para entornos de alta seguridad es crear una SCP que deniegue todo por defecto y luego adjuntar SCPs más permisivas a OUs o cuentas específicas. Esto asegura que solo lo explícitamente permitido puede ocurrir.
- Servicios Globales: Ten especial cuidado con las SCPs que deniegan regiones, ya que muchos servicios de AWS tienen endpoints globales o están controlados desde
us-east-1. Asegúrate de permitir las acciones necesarias para estos servicios (IAM, S3 global, CloudFront, Route 53, Health, Support, etc.) para evitar bloqueos accidentales.
🔚 Conclusión
La gestión de Políticas de Control de Servicio (SCPs) en AWS Organizations con Terraform es una práctica fundamental para cualquier organización que busque centralizar y automatizar su gobernanza de seguridad en la nube. Al codificar tus SCPs, obtienes los beneficios de la Infraestructura como Código: versionado, auditabilidad, consistencia y la capacidad de aplicar cambios de forma segura y repetible.
Recuerda siempre probar tus políticas en entornos controlados y comprender el impacto de las denegaciones explícitas. Con las SCPs bien configuradas, puedes establecer un límite superior de permisos, reducir la superficie de ataque y garantizar el cumplimiento en todo tu entorno de AWS.
Esperamos que este tutorial te haya proporcionado las herramientas y el conocimiento necesarios para comenzar a gestionar tus SCPs de manera efectiva con Terraform. ¡Feliz infraestructura como código!
Tutoriales relacionados
- Automatización de la Configuración de Kubernetes con Terraform: Un Enfoque Declarativointermediate15 min
- Migrando Infraestructura Existente a Terraform: Guía Completa de Importaciónintermediate18 min
- Gestionando Secretos Sensibles en Terraform con HashiCorp Vault: Un Enfoque Segurointermediate25 min
- Gestionando Servidores sin Estado con Terraform y AWS Auto Scaling Groupsintermediate20 min
- Gestionando Bases de Datos Relacionales con Terraform y AWS RDS: Un Enfoque Declarativointermediate18 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!