Cómo conectar Django de forma segura a AWS S3 — Dos enfoques recomendados
Cuando despliegas aplicaciones Django en AWS, manejar el acceso a S3 de forma segura es fundamental. Dejar las credenciales expuestas en el código es un gran riesgo. Por suerte, AWS ofrece dos formas seguras y efectivas para autenticar tu backend cuando trabaja con S3:
🔐 Dos opciones seguras para acceder a S3 desde Django
Opción | Descripción | Ideal para | Seguridad |
---|---|---|---|
1. Variables de entorno en Elastic Beanstalk | Defines tus claves de AWS directamente como variables en EB | Configuración rápida, entornos de staging o desarrollo | Segura (si tu consola está protegida) |
2. IAM Role asignado a EC2 | EC2 recibe credenciales temporales automáticamente | Producción, cumplimiento normativo, escalabilidad | La mejor práctica |
Opción 1: Usar variables de entorno
1. El problema: Credenciales escritas en el código
Evita hacer esto en tu settings.py
:
AWS_ACCESS_KEY_ID = "AKIA123..."
AWS_SECRET_ACCESS_KEY = "abcd123..."
2. Cargar las credenciales desde variables de entorno
import os
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY")
AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_STORAGE_BUCKET_NAME")
3. Crear un script de carga: set_env.sh
#!/bin/bash
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="abcd..."
export AWS_STORAGE_BUCKET_NAME="nombre-de-tu-bucket"
Luego:
chmod +x set_env.sh
4. Agregarlo a .gitignore
# Secretos del entorno
set_env.sh
5. Automatizar la carga al activar el entorno virtual
# Al final del archivo envs/bin/activate
source /ruta/completa/a/tu/proyecto/set_env.sh
6. Prueba final
source envs/bin/activate
echo $AWS_ACCESS_KEY_ID
💡 ¿Por qué es importante?
Las variables de entorno mantienen tus claves fuera del código y evitan filtraciones accidentales. Es una excelente solución para desarrollo o staging.
Opción 2: Usar IAM Roles (recomendado para producción)
Con IAM Roles, AWS gestiona la autenticación automáticamente mediante credenciales temporales, sin necesidad de guardar nada.
Paso 1: Crear un IAM Role
- Ve a AWS Console > IAM > Roles
- Haz clic en Crear rol
- Selecciona: AWS Service → EC2
- Asocia la política
AmazonS3FullAccess
(o una personalizada) - Asigna un nombre como
DjangoStarsUp-InstanceRole-S3Only
- Haz clic en Crear rol
Paso 2: Asignar el rol a Elastic Beanstalk
- Ve a Elastic Beanstalk > tu entorno > Configuration
- Edita la sección Service access
- Selecciona el rol creado en EC2 instance profile
- Haz clic en Apply
Problema común: Falla en el health check
Elastic Beanstalk valida la salud de las instancias accediendo a /
. Si Django no responde con 200 OK, marcará la instancia como fallida.
Paso 3: Agregar un endpoint de health check en Django
from django.http import JsonResponse
from django.urls import path
urlpatterns += [
path("health/", lambda request: JsonResponse({"status": "ok"})),
]
Paso 4: Cambiar el health check path en EB
- Ve a Configuration > Instance traffic and scaling
- Edita el proceso llamado
default
- Cambia el campo
Health check path
a/health/
- Guarda los cambios
Paso 5: Ajustar settings.py
para usar IAM Role
import os
AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_STORAGE_BUCKET_NAME")
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", None)
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", None)
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_S3_REGION_NAME = 'us-east-1'
AWS_QUERYSTRING_AUTH = False
if not AWS_ACCESS_KEY_ID or not AWS_SECRET_ACCESS_KEY:
print("Usando IAM Role desde el perfil de instancia EC2")
Resultado final
Tu backend Django ahora se conecta a S3 de forma totalmente segura:
- Sin claves en el código ni en disco
- Con credenciales rotadas automáticamente
- Escalable y en línea con buenas prácticas de AWS
- Con un health check funcional para EB
Política personalizada de ejemplo
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::nombre-de-tu-bucket",
"arn:aws:s3:::nombre-de-tu-bucket/*"
]
}
]
}
¿Qué sigue?
En la Parte 3 te mostraremos cómo almacenar secretos y claves de forma segura usando AWS Secrets Manager en producción.