Conecta Go a Postgres usando AWS Secrets
Clase 21 de 30 • Curso de Ciberseguridad para Desarrollo Web
Contenido del curso
Funciona en mi local
Introducción a DevSecOps
Seguridad en la arquitectura
- 11

Arquitectura AWS para métricas de Git
02:24 min - 12

Configuración de AWS CLI para Terraform
09:34 min - 13

Terraform IAM: roles y policies automáticos
17:44 min - 14

Modificando main.tf para enlazar módulos IAM en Terraform
06:02 min - 15

Bucket S3 para Lambdas con Terraform
16:44 min - 16

Configuración de Postgres RDS con VPC y seguridad
14:10 min - 17

Configurando VPC para AWS Lambda con Terraform
12:29 min - 18

Cómo configurar API Gateway para Lambdas
05:42 min
Evitando vulnerabilidades en el código
- 19

Configuración completa de Auth0 para tokens
07:14 min - 20

Authorizer Lambda con Auth0 y JWT
16:56 min - 21

Conecta Go a Postgres usando AWS Secrets
Viendo ahora - 22

Conexión segura de Lambdas a Secrets con VPC
11:27 min - 23

Validación de webhooks desde GitHub con user-agent
12:08 min - 24

Cómo validar integridad de webhooks con HMAC
14:32 min
Controles de seguridad sobre datos
Monitoring y alertas
CORS y cierre
Conecta tu backend en Go a una base de datos Postgres y entrega métricas limpias desde una lambda en API Gateway. Aquí verás cómo leer secretos desde AWS Secrets Manager, estructurar la respuesta de get metrics y manejar errores de forma clara, manteniendo las dependencias en orden y listas para despliegue.
¿Cómo conectar Go a Postgres con AWS Secrets Manager?
Para habilitar la conexión, se crea un paquete database con un archivo database.go y un método exportado Connect que recibe un context y devuelve la conexión SQL. Se usan variables de entorno para host, puerto, usuario, el identificador del secret con la contraseña y el nombre de la base. Además, se define en models una constante de region para el cliente de AWS y se usa un mecanismo de sincronización para inicializar la conexión solo una vez.
- Variables de entorno: host, port, user, password (como secret id), dbname, región de AWS.
- Cliente de Secrets Manager: se construye el client, se pasa el secret id y el stage actual, se obtiene el valor y se hace unmarshal de json a mapa string-string.
- DSN para Postgres: incluye host, port, user, password, dbname, uso de SSL y el search_path en public.
- Driver: se agrega el driver de Postgres a dependencias y se sincroniza con go get y go mod vendor.
// database/database.go
package database
import (
"context"
"database/sql"
// comentarios: importar AWS SDK, secrets manager, config, postgres driver.
)
// Connect: abre una sola conexión a Postgres leyendo secretos desde AWS.
func Connect(ctx context.Context) (*sql.DB, error) {
// 1) leer host, port, user, secret id de password y dbname desde variables de entorno.
// 2) usar models.region para crear el cliente de AWS Secrets Manager.
// 3) obtener el secret actual y hacer unmarshal a map[string]string.
// 4) armar el DSN con SSL requerido y search_path=public.
// 5) return sql.Open("postgres", dsn)
}
¿Qué variables de entorno necesitas?
- host, port y user del servidor de base de datos.
- secret id con la password en Secrets Manager.
- dbname de Postgres.
- region en models para el cliente de AWS.
¿Cómo se obtiene el password desde el secret?
- Crear el client de Secrets Manager con la región.
- Pasar el secret id y stage current.
- Hacer unmarshal del json a map[string]string.
- Leer la clave de password del mapa.
¿Qué dependencias se incorporan?
- Driver de Postgres.
- Paquetes de secrets manager y config de AWS.
- AWS SDK en Go.
- Comandos: go get, luego go mod vendor y validar con go mod dig.
¿Cómo responde la lambda get metrics en API Gateway?
La lambda de get metrics deja atrás el “Hello from Metrics” y pasa a construir una respuesta JSON con contador de commits y un arreglo de commits usando datos del repositorio. Se valida el parámetro de ruta auth_email, se abre la conexión con database.Connect, se consulta con get commits by author email y se transforma con parseResponse. Finalmente, se hace json marshal y se añade el header de content-type: application/json.
// Estructura y flujo de la lambda
type Commit struct {
ID string `json:"id"`
Repo string `json:"repo"`
Message string `json:"message"`
}
type Response struct {
AuthorCount int `json:"author_count"`
Commits []Commit `json:"commits"`
}
func parseResponse(email string, commits []Commit) Response {
// construir arreglo de commits con id, repo, message y contar.
// retornar Response con author_count y commits.
}
func HandleRequest(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
email := req.PathParameters["auth_email"]
if email == "" {
return events.APIGatewayProxyResponse{
StatusCode: http.StatusBadRequest,
Body: `{"message":"missing, auth_email param"}`,
}, fmt.Errorf("Missing path parameter auth_email")
}
db, err := database.Connect(ctx)
if err != nil {
return events.APIGatewayProxyResponse{
StatusCode: http.StatusInternalServerError,
Body: `{"message":"Error initializing database"}`,
}, err
}
repo := repository.NewCommit(db)
commits, err := repo.GetCommitsByAuthorEmail(ctx, email)
if err != nil {
// manejar "error getting commits".
}
resp := parseResponse(email, commits)
b, _ := json.Marshal(resp)
return events.APIGatewayProxyResponse{
StatusCode: http.StatusOK,
Headers: map[string]string{
"Content-Type": "application/json",
},
Body: string(b),
}, nil
}
¿Cómo validar el parámetro auth_email?
- Leerlo desde los path parameters del request.
- Si falta: responder 400 con mensaje "missing, auth_email param".
- Incluir error: "Missing path parameter auth_email".
¿Cómo construir y serializar la respuesta?
- Llamar a parseResponse(email, commits) para mapear a author_count y commits.
- Usar json marshal para convertir a cadena y ponerlo en Body.
- Agregar headers con content-type: application/json.
¿Qué patrón de errores aplica Go?
- Mentalidad de fallar rápido y retornar rápido.
- Error de conexión: 500 con "Error initializing database".
- Error al consultar commits: responder con mensaje explícito.
¿Cómo preparar y probar la base de datos?
Antes de probar, la tabla estaba vacía. Se abrió PGAdmin (o el gestor de tu preferencia) para insertar un registro de prueba con un comando SQL y verificar con un select que el commit quedó creado. Si aparecen problemas de acceso, revisar la IP en los security groups: un timeout silencioso suele indicar bloqueo por red, no un error de credenciales.
¿Cómo insertar datos de prueba?
- Conectarse al gestor y abrir el query tool.
- Ejecutar un insert de ejemplo en la tabla de commits.
- Validar con un select que el registro exista.
¿Qué hacer si hay timeouts al conectar?
- Revisar los security groups del motor.
- Confirmar si tu IP cambió y actualizar la regla.
- Reintentar la conexión y la consulta.
¿Qué permisos y configuración faltan?
- Conceder a la lambda permisos para acceder al API de Secrets Manager.
- Definir variables de entorno en Terraform para la conexión a base de datos.
¿Tienes dudas sobre la conexión, el manejo de secretos o la respuesta JSON? Comenta y cuéntame qué parte te gustaría que profundicemos.