Part 7: Deploying to AgentCore¶
Deploy Script Overview¶
scripts/deploy.sh handles the full deployment lifecycle:
scripts/deploy.sh # First deploy: IAM + ECR + build + push + create runtime
scripts/deploy.sh --update # Subsequent: build + push + update runtime
The script is idempotent for infrastructure (IAM, ECR) and linear for the deploy itself.
First Deploy¶
Run the deploy script with no arguments:
This executes five steps:
Step 1: IAM Role¶
Creates BedrockAgentCoreRecipeAgent with all required policies (covered in Part 6).
Step 2: ECR Repository¶
Creates the recipe-extraction-agent ECR repository.
Step 3: Build & Push¶
# Compile TypeScript
npm run build
# Build ARM64 Docker image
docker build --platform linux/arm64 -t recipe-extraction-agent .
# Tag and push to ECR
docker tag recipe-extraction-agent:latest \
${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/recipe-extraction-agent:latest
aws ecr get-login-password --region ${REGION} | \
docker login --username AWS --password-stdin \
${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com
docker push ${ECR_URI}:latest
Step 4: Create AgentCore Runtime¶
aws bedrock-agentcore-control create-agent-runtime \
--agent-runtime-name recipe_extraction_agent \
--agent-runtime-artifact '{"containerConfiguration":{"containerUri":"ECR_URI:latest"}}' \
--role-arn "${ROLE_ARN}" \
--network-configuration '{"networkMode":"PUBLIC"}' \
--protocol-configuration '{"serverProtocol":"HTTP"}' \
--environment-variables '{"AWS_REGION":"us-west-2","AWS_ACCOUNT_ID":"..."}' \
--region us-west-2
Key parameters:
| Parameter | Value | Purpose |
|---|---|---|
--agent-runtime-name |
recipe_extraction_agent |
Display name in the console |
--agent-runtime-artifact |
Container URI in ECR | Points to your Docker image |
--role-arn |
IAM execution role ARN | Permissions for the container |
--network-configuration |
PUBLIC |
Container has internet access (needed for recipe URLs) |
--protocol-configuration |
HTTP |
Fastify HTTP server (not WebSocket) |
--environment-variables |
JSON object | Env vars injected into the container |
The command returns the runtime ID:
Runtime ID: abc123-def456-...
Save this as AGENTCORE_RUNTIME_ID and BEDROCK_AGENT_ID for future deploys.
Important: The first deploy does not set
BEDROCK_AGENT_IDin the container's environment (because we don't know the runtime ID until after creation). Run--updateimmediately after to inject it.
Step 5: Poll for READY¶
for i in $(seq 1 30); do
STATUS=$(aws bedrock-agentcore-control get-agent-runtime \
--agent-runtime-id "${RUNTIME_ID}" \
--region us-west-2 \
--query 'status' --output text)
echo "Status: ${STATUS} (attempt ${i}/30)"
if [[ "${STATUS}" == "READY" ]]; then
echo "Runtime is READY!"
exit 0
elif [[ "${STATUS}" == "FAILED" ]]; then
echo "Runtime FAILED" >&2
exit 1
fi
sleep 10
done
The script polls every 10 seconds for up to 5 minutes. AgentCore typically takes 1-3 minutes to pull the image and start the container.
Save the Runtime ID¶
After the first deploy, save the runtime ID in your .env:
Then immediately run an update to inject BEDROCK_AGENT_ID:
Subsequent Deploys¶
With AGENTCORE_RUNTIME_ID set:
This skips IAM/ECR creation and goes straight to: 1. Build TypeScript 2. Build Docker image 3. Push to ECR 4. Update the runtime
The update command:
aws bedrock-agentcore-control update-agent-runtime \
--agent-runtime-id "${AGENTCORE_RUNTIME_ID}" \
--agent-runtime-artifact '{"containerConfiguration":{"containerUri":"ECR_URI:latest"}}' \
--role-arn "${ROLE_ARN}" \
--network-configuration '{"networkMode":"PUBLIC"}' \
--protocol-configuration '{"serverProtocol":"HTTP"}' \
--environment-variables '{"AWS_REGION":"...","BEDROCK_AGENT_ID":"...","PRISMA_AIRS_PROFILE_NAME":"..."}' \
--region us-west-2
On updates, the environment variables include BEDROCK_AGENT_ID (set to the runtime ID), which enables:
- CloudWatch log shipping (see Part 4)
- Agent metadata in AIRS scans (see Part 3)
Testing the Deployment¶
Once the runtime is READY, invoke it via the AWS CLI:
aws bedrock-agentcore invoke-agent-runtime \
--agent-runtime-id "${AGENTCORE_RUNTIME_ID}" \
--payload '{"url": "https://pinchofyum.com/chicken-wontons-in-spicy-chili-sauce"}' \
--region us-west-2 \
output.json
cat output.json | jq .
Expected response:
{
"title": "Chicken Wontons in Spicy Chili Sauce",
"ingredients": [...],
"preparationSteps": [...],
"cookingSteps": [...],
"notes": {
"servings": "4 servings",
"cookTime": "10 minutes",
"prepTime": "30 minutes"
}
}
Troubleshooting¶
Runtime stuck in CREATING¶
AgentCore pulls the image from ECR and starts the container. This typically takes 1-3 minutes. If it's been more than 5 minutes:
aws bedrock-agentcore-control get-agent-runtime \
--agent-runtime-id "${AGENTCORE_RUNTIME_ID}" \
--region us-west-2
Check the status and statusReasons fields.
Runtime enters FAILED¶
Common causes:
| Issue | Fix |
|---|---|
| Wrong architecture | Ensure --platform linux/arm64 in your Docker build |
| Missing IAM permissions | Check the execution role has all four policies |
| Container crash | Test locally first: docker run -p 8080:8080 --env-file .env recipe-extraction-agent |
| Port mismatch | The container must listen on port 8080 |
| Health check timeout | /ping must respond within 30 seconds of container start |
Inference profile ARNs¶
If you see "access denied" errors when invoking Bedrock models, check that the IAM role includes inference-profile/* in its resource ARNs:
"Resource": [
"arn:aws:bedrock:*::foundation-model/*",
"arn:aws:bedrock:*:ACCOUNT_ID:inference-profile/*"
]
The us. prefix in us.anthropic.claude-haiku-4-5-20251001-v1:0 uses cross-region inference profiles, which require the second ARN pattern.
Debugging with logs¶
If the container starts but invocations fail, check CloudWatch: