Your agent wants to run npm test on a PR branch before it proposes a merge. You already have ephemeral ECS Fargate sandboxes for arbitrary tool execution — and they are the right hammer for long-lived interactive shells. For CI-shaped tool calls (lint, unit tests, typecheck, build artifacts), standing up another Fargate task family per language is sprawl. The unfair advantage is a CodeBuild project as a sandbox: buildspec-driven, privilegedMode: false by default, artifacts to S3, IAM scoped to one repo bucket, billed per build-minute.
⚡ TL;DR: Use CodeBuild when the agent tool is “run this buildspec on commit SHA X.” Keep ECS Fargate for interactive / custom sandboxes covered in Secure AI Sandboxes and LLM Coding Agents Lambda Sandboxes. Gate hallucinated AWS changes with Cursor Background Agents CI Gates. Never
privileged: trueunless you truly need Docker-in-Docker — and even then prefer CodeBuild’s managed images carefully.
When CodeBuild beats ECS for agent tools
| Signal | Prefer CodeBuild | Prefer ECS Fargate |
|---|---|---|
| Work is lint/test/build | ✅ | |
| Need interactive shell / RDP-like session | ✅ | |
| Want buildspec + CloudWatch Logs groups for free | ✅ | |
| Custom long-running sidecar mesh | ✅ | |
| Cost for 2–10 min CI-like bursts | ✅ often cheaper | cold start + task overhead |
| Already covered Fargate patterns elsewhere | Use this post | See sandbox post |
CodeBuild is build-centric: source in, commands, artifacts out. That matches how coding agents validate patches.
Project shape: buildspec, not a snowflake container
# buildspec.yml — checked into the repo the agent is patching
version: 0.2
env:
variables:
NODE_OPTIONS: "--max-old-space-size=2048"
# ❌ Do not put SaaS tokens in plaintext env here — use Secrets Manager
# secrets-manager:
# GITHUB_TOKEN: agent/$TENANT/github_pr_read:token
phases:
install:
runtime-versions:
nodejs: 20
commands:
- npm ci --ignore-scripts
pre_build:
commands:
- npm run lint
build:
commands:
- npm test -- --ci
- npm run typecheck
artifacts:
files:
- "coverage/**/*"
- "junit.xml"
name: agent-build-$(date +%Y%m%d%H%M%S)
✅ Agent tool submits sourceVersion = commit SHA or PR ref; it does not invent shell scripts ad hoc when a buildspec already defines the contract.
Start builds from the agent tool (TypeScript)
import {
CodeBuildClient,
StartBuildCommand,
BatchGetBuildsCommand,
} from "@aws-sdk/client-codebuild";
const cb = new CodeBuildClient({});
export async function runPrSandboxBuild(input: {
projectName: string;
sourceVersion: string; // commit SHA
tenantId: string;
idempotencyKey: string;
}) {
// ✅ Idempotency: if you already started this key, return prior build id
const start = await cb.send(
new StartBuildCommand({
projectName: input.projectName,
sourceVersion: input.sourceVersion,
environmentVariablesOverride: [
{ name: "TENANT_ID", value: input.tenantId, type: "PLAINTEXT" },
{
name: "IDEMPOTENCY_KEY",
value: input.idempotencyKey,
type: "PLAINTEXT",
},
],
// Optional: buildspec override only for allowlisted extra steps
})
);
const buildId = start.build?.id;
if (!buildId) throw new Error("no_build_id");
// Poll with timeout — do not hold a Bedrock turn open forever;
// prefer async tool + EventBridge like agent async tools pattern
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const got = await cb.send(
new BatchGetBuildsCommand({ ids: [buildId] })
);
const build = got.builds?.[0];
const status = build?.buildStatus;
if (status && status !== "IN_PROGRESS") {
return {
buildId,
status,
logLink: build?.logs?.deepLink,
artifacts: build?.artifacts?.location,
};
}
}
return { buildId, status: "TIMEOUT_WAITING", artifacts: null };
}
For multi-turn agents, prefer async: StartBuild → EventBridge rule on CodeBuild state change → resume agent session (same idea as Bedrock Agents + EventBridge async tools).
IAM role scoped to the repo bucket
The CodeBuild service role should not be the agent runtime role.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOnlySourceBucket",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:GetObjectVersion"],
"Resource": "arn:aws:s3:::acme-agent-src/tenant-${tenant}/*"
},
{
"Sid": "WriteArtifactsPrefix",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::acme-agent-artifacts/tenant-${tenant}/*"
},
{
"Sid": "Logs",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:log-group:/aws/codebuild/agent-*"
},
{
"Sid": "DenyPrivilegeEscalation",
"Effect": "Deny",
"Action": [
"iam:PassRole",
"sts:AssumeRole",
"ec2:Create*",
"lambda:Create*",
"sagemaker:*"
],
"Resource": "*"
}
]
}
Agent runtime IAM may only codebuild:StartBuild / BatchGetBuilds on the specific project ARN, with tags — see IAM Condition Keys for Agent Runtimes.
Privileged false, VPC optional
// CDK-ish environment block
environment: {
buildImage: codebuild.LinuxBuildImage.STANDARD_7_0,
privileged: false, // ✅ default for agent sandboxes
computeType: codebuild.ComputeType.SMALL,
// vpc: optional — only if tests need private RDS / internal npm
}
❌ Patterns:
privileged: true“because npm might need Docker” — use a prebuilt image or CodeBuild’s Docker support only with a dedicated project and tighter controls- Agent-supplied
buildspecOverridethat runscurl | bashfrom a model-generated URL - Shared project across tenants without prefix isolation on source/artifact paths
✅ Allowlist buildspec overrides to a few static snippets you own; prefer repo buildspec at the commit SHA the agent is testing.
Compare briefly to ECS Fargate sandboxes
ECS Fargate sandboxes shine when the agent needs a mutable workspace, package installs outside a fixed buildspec, or binary tools you do not want in CodeBuild images. They cost more operational surface (task defs, networking, teardown watchdogs). CodeBuild gives you:
- Managed images and log streaming
- Native artifact export
- Per-build isolation without a task-def zoo
Use Lambda sandboxes for tiny ephemeral snippets; CodeBuild for repo-scale CI; ECS for interactive/custom. Do not collapse all three into one “agent runner.”
Debugging agent-triggered builds
- Always return
logs.deepLinkto the agent tool result (redact secrets in build logs separately). - On
FAULT/TIMED_OUT, surfacebuildStatus+ phase failure — models otherwise retry forever. - Cap concurrent builds per tenant (CodeBuild account limits + your own DynamoDB semaphore).
- Store junit/coverage artifacts and let a second tool summarize — do not dump megabyte logs into the Bedrock context.
// ✅ Tool result stays small
return {
status: "FAILED",
failedPhase: "BUILD",
summary: "3 tests failed in auth.test.ts",
logLink,
artifactUri,
};
Checklist
- [ ] CI-like agent tools use CodeBuild; interactive shells stay on ECS
- [ ]
privilegedMode: falseunless a dedicated hardened project requires otherwise - [ ] Service role scoped to tenant-prefixed source + artifact buckets
- [ ] Agent role can StartBuild only on named projects (tag conditions)
- [ ] No model-controlled arbitrary buildspec from untrusted URLs
- [ ] Prefer async StartBuild + EventBridge resume over long polling in a Converse turn
- [ ] Idempotency key per (tenant, SHA, suite) to prevent build storms
- [ ] Tool results return status + log link + short summary, not full logs
CodeBuild will not replace every sandbox. It will replace the expensive habit of launching Fargate every time an agent only needed npm test on a SHA.
Most viewed
- Day 1: Tokens, Context Windows, and Why Models Forget Mid-Task
- Python Type Hints Complete Guide: Write Self-Documenting, Bug-Free Code
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- System Design Interview Cheat Sheet: The Framework That Gets You Hired at FAANG
- Day 9: Eval Harness Day One
Newly added
- API Gateway WebSockets for Multi-Turn Coding Agents: Connection State Without Sticky Myths
- CodeBuild Spec Sandboxes for AI Coding Agents: Ephemeral Builds Without ECS Sprawl
- KMS Decrypt Grants for Agent Tools: Least Privilege Without Env Keys
- EventBridge Scheduler: Overnight Agent Batches Without Cron Drift
- Lambda Recursive Loop Protection: Stop Agent Self-Invokes From Burning Quotas
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.