AWS Builder Center
Cómo Construir un Agente Autónomo de Despliegue con Amazon Bedrock, MCP y AWS CDK 🛠️☁️

Cómo Construir un Agente Autónomo de Despliegue con Amazon Bedrock, MCP y AWS CDK 🛠️☁️

¿Cómo pasar de un requerimiento en lenguaje natural a una infraestructura lista para producción sin escribir cientos de líneas de CloudFormation? En esta guía técnica paso a paso construimos un agente autónomo de infraestructura con Amazon Bedrock (Tool Use), Model Context Protocol (MCP) y AWS CDK, implementando guardrails de FinOps y políticas de mínimos privilegios.

Cloud & AI Solutions Architect • GenAI • Founder Iztack • AWS SBG Leader at ONMEX
La infraestructura como código (IaC) con herramientas como AWS CDK o Terraform es el estándar indiscutible para garantizar reproducibilidad y gobernanza en la nube. Sin embargo, para equipos de desarrollo rápido, agencias o Startups que buscan validar productos sin fricción, el costo cognitivo de orquestar VPCs, subnets, tablas de ruteo, certificados SSL en ACM y balanceadores ALB suele convertirse en un cuello de botella crítico.
Con la maduración de los modelos fundacionales con soporte para llamadas a funciones (Tool Use) y estándares como Model Context Protocol (MCP), hoy podemos cerrar esa brecha.
En esta guía técnica construiremos un Agente Autónomo de Infraestructura: un sistema capaz de interpretar un requerimiento en lenguaje natural, sintetizar un stack tipado en AWS CDK, verificar límites de presupuesto en tiempo real y ejecutar el despliegue de manera determinista y segura.

1. Arquitectura de Referencia

A diferencia de un chatbot convencional que solo escupe código estático, un agente de infraestructura opera dentro de un ciclo cerrado de ejecución y retroalimentación (Agentic Loop).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[ Desarrollador / CLI ]
│
│ Requerimiento ("Stack web SSR con base de datos gestionada")
▼
┌──────────────────────────────────────────────────────────────┐
│ Agente Orquestador (Amazon Bedrock - Converse API) │
│ • Modelo: Anthropic Claude 3.5 Sonnet / Amazon Nova Pro │
│ • Tarea: Planificación de topología y selección de herramientas│
└──────────────────────────────┬───────────────────────────────┘
│
┌──────────────────┴──────────────────┐
│ Invocación de Herramientas (Tool Use)│
▼ ▼
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ Servidor MCP: CDK Core │ │ Servidor MCP: FinOps Guard │
│ • generate_cdk_construct() │ │ • estimate_monthly_cost() │
│ • cdk_synth() │ │ • validate_budget_limit() │
└──────────────┬───────────────┘ └──────────────┬───────────────┘
│ │
│ Template Validado │ Costo < Límite
└──────────────────┬───────────────────┘
▼
┌──────────────────────────────────────┐
│ Motor de Despliegue (AWS CDK CLI) │
│ • cdk deploy --require-approval never│
└──────────────────┬───────────────────┘
▼
┌──────────────────────────────────────┐
│ AWS CloudFormation │
│ • ECS / Fargate / RDS / S3 / ACM │
└──────────────────────────────────────┘

Componentes Clave:

  1. Orquestador (Amazon Bedrock): Ejecuta el razonamiento algorítmico y determina qué herramientas ejecutar en función del prompt.
  2. Servidor MCP (Model Context Protocol): Expone un protocolo estandarizado de herramientas locales que interactúan con el sistema de archivos y el AWS CLI.
  3. FinOps Guardrail: Una función de validación que calcula el costo mensual proyectado antes de permitir cualquier llamada a cdk deploy.

2. Mapa Mental del Flujo Operativo

Antes de escribir código, definamos los estados finitos por los que transita el agente:
1
2
3
4
5
6
7
8
9
10
11
12
Entrada de Usuario
└── 1. Extracción de Entidades (Framework, Tráfico, Persistencia)
└── 2. Consulta al Servidor FinOps
├── ¿Costo Proyectado > Límite ($30 USD/mes)?
│ └── [ABORTAR] Reportar alternativas serverless al usuario
└── ¿Costo Proyectado <= Límite?
└── 3. Generación y Síntesis de CDK
├── Error de Sintaxis / Tipado
│ └── Realimentar error a Bedrock para autocorrección
└── Síntesis Exitosa (cdk.out validado)
└── 4. Despliegue en CloudFormation
└── 5. Retorno de Endpoints y Secretos al Usuario
3. Implementación Práctica
Requisitos Previos
  • Python 3.11+
  • AWS CLI configurado con permisos de administrador en entorno Sandbox.
  • Node.js 20+ y AWS CDK v2 instalado globalmente (npm install -g aws-cdk).
  • Modelo habilitado en Amazon Bedrock (ej. anthropic.claude-3-5-sonnet-20240620-v1:0).
Paso 1: Definición del Servidor de Herramientas (Tool Specs)
Definimos el esquema en JSON que le enseña a Bedrock qué capacidades tiene a su disposición.
Guardar como tool_definitions.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
TOOLS_SCHEMA = [
{
"toolSpec": {
"name": "estimate_monthly_cost",
"description": "Calcula el costo proyectado en USD/mes según los tipos de instancia y servicios solicitados.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"compute_type": {
"type": "string",
"enum": ["FARGATE_SPOT", "FARGATE_ON_DEMAND", "LAMBDA", "EC2_T3_MICRO"],
"description": "El tipo de cómputo seleccionado."
},
"has_relational_db": {
"type": "boolean",
"description": "Indica si el stack requiere Aurora Serverless o RDS."
}
},
"required": ["compute_type", "has_relational_db"]
}
}
}
},
{
"toolSpec": {
"name": "deploy_cdk_stack",
"description": "Compila y despliega un stack de CDK predefinido pasando los parámetros validados.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"stack_name": {"type": "string"},
"environment": {"type": "string", "enum": ["dev", "prod"]},
"compute_type": {"type": "string"}
},
"required": ["stack_name", "environment", "compute_type"]
}
}
}
}
]

Paso 2: Implementación de la Lógica Local (MCP Mock / Handlers)

Estas funciones son las que efectivamente ejecutan acciones en el sistema operativo del host.
Guardar como tool_handlers.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import subprocess
import json

BUDGET_HARD_LIMIT_USD = 50.0 # Límite estricto de FinOps

def handle_cost_estimation(compute_type: str, has_relational_db: bool) -> dict:
costs = {
"LAMBDA": 2.0,
"FARGATE_SPOT": 12.0,
"FARGATE_ON_DEMAND": 28.0,
"EC2_T3_MICRO": 9.5
}
base_cost = costs.get(compute_type, 30.0)
db_cost = 25.0 if has_relational_db else 0.0
total = base_cost + db_cost

approved = total <= BUDGET_HARD_LIMIT_USD
return {
"projected_cost_usd": total,
"budget_limit_usd": BUDGET_HARD_LIMIT_USD,
"approved": approved,
"policy_violation": None if approved else "El costo proyectado excede el límite máximo de FinOps."
}

def handle_cdk_deployment(stack_name: str, environment: str, compute_type: str) -> dict:
# Comando determinista de despliegue
cmd = [
"cdk", "deploy", stack_name,
"--context", f"env={environment}",
"--context", f"compute={compute_type}",
"--require-approval", "never"
]

try:
# Simulamos la llamada CLI para fines de auditoría controlada
process = subprocess.run(
["echo", f"Simulando: {' '.join(cmd)}"],
capture_output=True,
text=True,
check=True
)
return {
"status": "SUCCESS",
"output": process.stdout.strip(),
"stack_id": f"arn:aws:cloudformation:us-east-1:123456789012:stack/{stack_name}"
}
except subprocess.CalledProcessError as e:
return {"status": "FAILED", "error": e.stderr}

Paso 3: El Orquestador Agentivo (Bedrock Converse API)

Este script conecta el modelo fundacional con las herramientas y gestiona el bucle de realimentación.
Guardar como agent_orchestrator.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import boto3
import json
from tool_definitions import TOOLS_SCHEMA
from tool_handlers import handle_cost_estimation, handle_cdk_deployment

bedrock_client = boto3.client(service_name="bedrock-runtime", region_name="us-east-1")
MODEL_ID = "anthropic.claude-3-5-sonnet-20240620-v1:0"

SYSTEM_PROMPT = """Eres un Arquitecto de Infraestructura Autónomo en AWS.
Tu labor es aprovisionar stacks en la nube siguiendo estrictamente estas reglas:
1. NUNCA despliegues infraestructura sin antes estimar su costo mensual con 'estimate_monthly_cost'.
2. Si el costo excede el límite permitido, debes detenerte y sugerir una arquitectura más económica (ej. Serverless Lambda en lugar de Fargate).
3. Solo si la estimación es aprobada, procede con 'deploy_cdk_stack'.
"""


def execute_agent_loop(user_prompt: str):
messages = [{"role": "user", "content": [{"text": user_prompt}]}]
print(f"\n[USER]: {user_prompt}\n")

while True:
response = bedrock_client.converse(
modelId=MODEL_ID,
messages=messages,
system=[{"text": SYSTEM_PROMPT}],
toolConfig={"tools": TOOLS_SCHEMA}
)

message_output = response["output"]["message"]
messages.append(message_output)
stop_reason = response["stopReason"]

# Si el modelo solo responde con texto, terminamos
if stop_reason == "end_turn":
for block in message_output["content"]:
if "text" in block:
print(f"[AGENTE]: {block['text']}")
break

# Si el modelo solicita ejecutar una herramienta (Tool Use)
elif stop_reason == "tool_use":
tool_results = []
for block in message_output["content"]:
if "toolUse" in block:
tool_call = block["toolUse"]
tool_name = tool_call["name"]
tool_args = tool_call["input"]
tool_id = tool_call["toolUseId"]

print(f"-> [EJECUTANDO TOOL]: {tool_name} con parámetros: {tool_args}")

if tool_name == "estimate_monthly_cost":
result_data = handle_cost_estimation(**tool_args)
elif tool_name == "deploy_cdk_stack":
result_data = handle_cdk_deployment(**tool_args)
else:
result_data = {"error": "Herramienta desconocida"}

tool_results.append({
"toolResult": {
"toolUseId": tool_id,
"content": [{"json": result_data}]
}
})

messages.append({"role": "user", "content": tool_results})

if __name__ == "__main__":
prompt = "Necesito montar una API en producción usando Fargate On-Demand con una base de datos relacional."
execute_agent_loop(prompt)
4. Ejecución y Auditoría en la Terminal
Al ejecutar el orquestador con un stack costoso:
1
python agent_orchestrator.py
Salida esperada en terminal:
1
2
3
4
5
6
7
8
9
10
11
12
[USER]: Necesito montar una API en producción usando Fargate On-Demand con una base de datos relacional.

-> [EJECUTANDO TOOL]: estimate_monthly_cost con parámetros: {'compute_type': 'FARGATE_ON_DEMAND', 'has_relational_db': True}

[AGENTE]: He calculado el costo proyectado para tu solicitud:
- Cómputo (Fargate On-Demand): $28.00 USD/mes
- Base de Datos Relacional: $25.00 USD/mes
- Costo Total Estimado: $53.00 USD/mes

El presupuesto máximo establecido por las políticas de FinOps es de $50.00 USD/mes. La operación ha sido bloqueada para prevenir sobrecostos no autorizados.

¿Deseas que reconfiguremos la arquitectura usando **FARGATE_SPOT** ($12.00/mes) o **AWS Lambda** ($2.00/mes) para mantenernos dentro del límite?
El modelo respeta la regla de negocio y no procede a la llamada de despliegue. Si el usuario acepta la alternativa Spot, el agente encadena automáticamente la ejecución de deploy_cdk_stack.

5. Patrones de Seguridad para Entornos de Producción

  1. Principio de Mínimo Privilegio en IAM: El rol de IAM que ejecuta el script no debe tener AdministratorAccess. Debe restringirse exclusivamente a las acciones cloudformation:*, iam:PassRole, y a los namespaces de recursos específicos declarados en el CDK.
  2. Idempotencia: Todas las funciones expuestas vía MCP deben ser seguras frente a fallos de red. Si se interrumpe la conexión durante la síntesis, reintentar no debe duplicar recursos.
  3. Aislamiento en Contenedores: En arquitecturas empresariales, el servidor MCP no debe ejecutarse en la máquina local del desarrollador sin restricciones, sino dentro de una tarea aislada de AWS Fargate con credenciales temporales otorgadas vía AWS STS.
El verdadero valor de la Inteligencia Artificial en la nube no reside en generar código que debamos inspeccionar manualmente línea por línea, sino en construir sistemas gobernados y auditables donde los modelos tomen decisiones acotadas dentro de marcos estrictos de arquitectura y costo.
¿Qué herramientas o políticas de validación añadirías al servidor MCP antes de autorizar un pase a producción? Déjame tus comentarios y continuemos el debate técnico.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article