engineering-handbook/bedrock.md
Adam Moussa 651dff5dd3
Add Bedrock, dev-env, and Lambda template pages (#7)
Adds three handbook pages covering conventions that were previously
scattered across feedback memories or rederived from scratch each
time:

- bedrock.md captures the cross-region inference profile requirement
  for Claude 4.x Bedrock Agents and the alias-version pinning gotcha,
  plus the IAM resource pattern and the KB Docker requirement.
- dev-environment.md documents the workstation directory layout,
  pyenv/Node conventions, the macOS launchd/TCC sandbox gotcha, and
  cleanup cadence.
- lambda-template.md provides a minimal SAM scaffold that follows the
  Lambda defaults already in aws-infrastructure.md (Python 3.12,
  arm64, explicit 60-day log retention, scoped Secrets Manager
  access, module-level secret cache).

Also extends two existing pages:

- sam-project-layout.md gains a Lambda Layers section with the
  BuildMethod nesting pattern that caused a ~22-hour production
  outage when violated.
- naming-conventions.md adds a Legacy Stacks note acknowledging that
  pre-convention PascalCase stacks (SeaHavenDoorUnlockStack,
  WorkorderIngestStack) stay as-is rather than risk stack
  replacement.
2026-05-14 19:50:37 -04:00

2.6 KiB

AWS Bedrock

Conventions and gotchas for using AWS Bedrock — Agents, Knowledge Bases, and model invocations.

Foundation Model IDs

For Claude 4.x models on Bedrock Agents, always use the cross-region inference profile ID, not the direct model ID.

Use Example
Direct invocation (bedrock-runtime) anthropic.claude-sonnet-4-5-20250929-v1:0
Bedrock Agent foundationModel us.anthropic.claude-sonnet-4-5-20250929-v1:0

The direct model ID is only valid for bedrock-runtime invocations. Using it on CfnAgent.foundationModel makes the agent prepare successfully but throws ResourceNotFoundException at invocation time.

IAM Permissions

Bedrock Agents need both the underlying foundation model and the cross-region inference profile in their IAM policy:

{
  "Effect": "Allow",
  "Action": "bedrock:InvokeModel",
  "Resource": [
    "arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0",
    "arn:aws:bedrock:us-east-1:<account>:inference-profile/us.anthropic.claude-sonnet-4-5-20250929-v1:0"
  ]
}

The foundation model ARN uses the wildcard region (*) since cross-region inference can route to any of the profile's regions.

Alias Version Pinning

When updating an agent's foundationModel or instruction via CDK or CloudFormation, the alias does not automatically re-point to the new version.

CloudFormation only updates the DRAFT version when CfnAgent changes. The alias stays pinned to the previous version unless the alias resource itself changes.

Force version rotation by bumping the alias description in the same change set:

new bedrock.CfnAgentAlias(this, 'Alias', {
  agentAliasName: 'live',
  agentId: agent.attrAgentId,
  description: `bumped 2026-05-14 — model update`,  // change this to force a new version
});

Knowledge Bases

The @cdklabs/generative-ai-cdk-constructs VectorKnowledgeBase L2 construct requires Docker Desktop on the deploying machine — it uses Code.fromDockerBuild for a custom resource Lambda. CI runners need Docker available.

For Knowledge Base S3 buckets, follow the standard tagging convention from AWS Infrastructure: Purpose and ManagedBy tags.

Action Groups

Action group Lambdas receive a Bedrock-specific event shape — they are not invoked as plain Lambda function URLs. The apiPath and httpMethod fields in the event identify which OpenAPI operation triggered the call. Validate them before dispatching.

Document the action group's OpenAPI schema in the same repo as the Lambda code; CloudFormation stores it inline.