Aprovisionamiento de Recursos en la Nube
Aprovisionar recursos en la nube significa crear y actualizar primitivas de AWS (u otra nube) de una manera repetible y revisable. Los equipos de Python combinan herramientas de IaC con boto3 para la convergencia, importaciones y tareas operativas que no pertenecen a una plantilla estática.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
import boto3
def provision_queue(sqs, name: str) -> str:
try:
resp = sqs.get_queue_url(QueueName=name)
return resp["QueueUrl"]
except sqs.exceptions.QueueDoesNotExist:
resp = sqs.create_queue(
QueueName=name,
Attributes={"VisibilityTimeout": "60"},
)
return resp["QueueUrl"]Cuándo usar esto:
- Arranque (Bootstrapping) de cuentas antes de la adopción completa de IaC
- Ayudantes Idempotentes de aseguramiento llamados desde pipelines de despliegue
- Flujos de trabajo de importación/adopción que envuelven APIs de la nube
- Runbooks operativos codificados como CLIs de Python
- Emparejamiento con Pulumi/Terraform para recursos fuera de los módulos actuales
Ejemplo de Trabajo
Una pequeña CLI de aprovisionamiento que asegura adjuntos de políticas IAM, SQS y S3 con registro estructurado.
"""provision.py - arranque idempotente de recursos AWS."""
from __future__ import annotations
import json
import logging
from dataclasses import dataclass
import boto3
from botocore.exceptions import ClientError
logging.basicConfig(level=logging.INFO, format="%(message)s")
log = logging.getLogger("provision")
@dataclass(frozen=True)
class ProvisionSpec:
bucket: str
queue: str
tags: dict[str, str]
def ensure_bucket(s3, name: str, tags: dict[str, str]) -> str:
buckets = {b["Name"] for b in s3.list_buckets().get("Buckets", [])}
if name not in buckets:
s3.create_bucket(Bucket=name)
log.info(json.dumps({"action": "create", "resource": "s3", "name": name}))
s3.put_bucket_tagging(Bucket=name, Tagging={"TagSet": [{"Key": k, "Value": v} for k, v in tags.items()]})
return name
def ensure_queue(sqs, name: str) -> str:
try:
return sqs.get_queue_url(QueueName=name)["QueueUrl"]
except ClientError as exc:
if exc.response["Error"]["Code"] != "AWS.SimpleQueueService.NonExistentQueue":
raise
url = sqs.create_queue(QueueName=name)["QueueUrl"]
log.info(json.dumps({"action": "create", "resource": "sqs", "name": name}))
return url
def main() -> None:
spec = ProvisionSpec(
bucket="company-events-dev",
queue="company-events-dev",
tags={"Environment": "dev", "Owner": "platform"},
)
session = boto3.Session()
s3 = session.client("s3")
sqs = session.client("sqs")
ensure_bucket(s3, spec.bucket, spec.tags)
ensure_queue(sqs, spec.queue)
log.info(json.dumps({"status": "ok", "bucket": spec.bucket, "queue": spec.queue}))
if __name__ == "__main__":
main()Lo que esto demuestra:
get_queue_url+ manejo de excepciones implementa el aseguramiento idempotente de colas- Etiquetado aplicado en cada ejecución para converger metadatos
- Registros estructurados en JSON adecuados para artefactos de CI
- Sesión por ejecución respeta las credenciales de rol IAM y
AWS_PROFILE
Inmersión Profunda
Cómo Funciona
- Declarar recursos deseados en código, clases de datos o programas de IaC
- Planificar con herramientas de vista previa (
pulumi preview,terraform plan) al usar IaC - Aplicar crea/actualiza; los backends de estado rastrean lo que existe
- Verificar con APIs de descripción/obtención y pruebas de integración
- Documentar cada ruta de aprovisionamiento en git con revisión de PR
Capas de Aprovisionamiento
| Capa | Herramientas | Mejor para |
|---|---|---|
| IaC Declarativo | Pulumi, Terraform | VPCs, líneas base de IAM, almacenes de datos |
| Aseguramiento Imperativo | Scripts de boto3 | Adopción única, pegamento de pipeline |
| APIs de Plano de Control | CloudFormation | Equipos nativos de AWS |
| Configuración en instancias | Ansible | Paquetes del sistema operativo después de que la instancia existe |
Notas de Python
from botocore.config import Config
retry_config = Config(retries={"max_attempts": 10, "mode": "standard"})
s3 = boto3.client("s3", config=retry_config)Errores Comunes
- Scripts solo de creación - la segunda ejecución falla con
BucketAlreadyExists. Solución: verificar existencia o usar IaC con estado. - Sin etiquetas en los recursos - la asignación de costos y las auditorías de políticas fallan. Solución: conjunto de etiquetas obligatorio validado en la política de CI.
- Credenciales compartidas en portátiles - aprovisionamiento desde máquinas de desarrollo con claves de administrador. Solución: roles OIDC de CI con ámbito por entorno.
- Regiones codificadas - los recursos aterrizan en la partición/región incorrecta. Solución:
AWS_REGIONo configuración de sesión del spec del entorno. - Fallo parcial silencioso - se creó la cola, falló el bucket, el script aún sale con 0. Solución: agregar errores y códigos de salida distintos de cero.
Alternativas
| Alternativa | Usar Cuándo | No Usar Cuándo |
|---|---|---|
| Solo Pulumi/Terraform | Ciclo de vida completo del entorno | Necesidad de adopción imperativa rápida |
| AWS CloudFormation | Solo AWS, las políticas de control de servicios imponen CFN | Equipo estandarizado en IaC de Python en otro lugar |
| Click CLI + boto3 | Los operadores ejecutan comandos verificados | Notebooks ad-hoc de boto3 sin revisión |
| Clics en la consola | Solo para emergencias de último recurso | Entornos repetibles |
Preguntas Frecuentes
¿Cuándo es suficiente el aprovisionamiento con boto3?
Pequeños aseguramientos y código de pegamento. Los entornos completos con muchos recursos interdependientes deben estar en IaC con plan/aplicar.
¿Cómo hago que el aprovisionamiento sea revisable?
Cada cambio a través de PR de git, artefactos de plan/vista previa de CI y aprobaciones requeridas para cuentas de producción.
¿Qué etiquetas son obligatorias?
Como mínimo Environment, Owner y CostCenter - extender según la política de la organización y validar antes de aplicar.
¿Cómo manejo los recursos existentes?
Importar en el estado de Terraform/Pulumi o escribir scripts de adopción que detecten y alineen en lugar de crear ciegamente.
¿Puedo aprovisionar desde Lambda?
Sí, para aseguramientos pequeños; preste atención a los permisos de IAM, los tiempos de espera y la idempotencia cuando se activen las reintentos de Lambda.
¿Cómo interactúan los reintentos con el aprovisionamiento?
Use los reintentos de Config de botocore para el throttling. La creación en sí debe seguir siendo idempotente para sobrevivir a llamadas duplicadas.
¿Qué pasa con AWS multi-cuenta?
Asuma roles por cuenta con sts:AssumeRole, backends de estado separados y barreras de protección que impidan la aplicación en producción desde CI de desarrollo.
¿Cómo pruebo sin AWS?
Use moto para pruebas unitarias de funciones de aseguramiento, y LocalStack para pruebas de integración selectivas; aún así ejecute pruebas de humo en una cuenta sandbox.
¿Quién es el propietario del código de aprovisionamiento?
Plataforma/SRE es propietario de los módulos compartidos; los equipos de producto consumen módulos etiquetados en lugar de copiar fragmentos de boto3.
¿Cómo se relaciona esto con el despliegue?
El aprovisionamiento crea infraestructura compartida (colas, buckets); los pipelines de despliegue publican artefactos de aplicaciones que consumen esos recursos.
Relacionado
- Fundamentos de Automatización de Infraestructura - mentalidad idempotente
- Pulumi (IaC de Python) - aprovisionamiento declarativo
- Fundamentos de boto3 - sesiones y clientes
- S3 - operaciones de almacenamiento de objetos
- SQS y SNS - primitivas de mensajería
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.