
Amazon Bedrock provides a secure, serverless way to deploy Anthropic’s Claude models without managing underlying infrastructure. This technical guide outlines the architectural flow, security considerations, and line-by-line code implementation required for a production-ready deployment.
Architectural Design
[ Client Application ]
| (IAM Authenticated / HTTPS)
v
[ Amazon Bedrock Endpoint ]
| (VPC Endpoint / PrivateLink)
v
[ Claude Model (Anthropic) ] ----> [ AWS CloudWatch Logs ] (Audit / Metrics)
Key Architecture Components
- Serverless Execution: No infrastructure provisioning or GPU management required.
- Network Security: Traffic stays within the AWS backbone using AWS PrivateLink (VPC Endpoints).
- Data Privacy: Inputs and outputs are encrypted at rest (AWS KMS) and in transit (TLS 1.2+). Your data is never used to train base models.
- Identity and Access Management (IAM): Fine-grained, role-based access control rules govern model invocation.
Prerequisites & Setup
Before writing code, ensure the following steps are completed in the AWS Management Console:
- Model Access: Navigate to Amazon Bedrock > Model access and enable access for the desired Claude model (e.g., Claude 3.5 Sonnet).
- IAM Permissions: Grant the executing environment (Lambda, ECS, or EC2) the following minimal IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockInvocation",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:*::foundation-model/anthropic.claude-3-5-sonnet-*"
}
]
}
Code Implementation (Python / Boto3)
This implementation uses the Anthropic Messages API format natively supported by Amazon Bedrock.
import boto3
import json
from botocore.exceptions import ClientError
def generate_architectural_review(prompt_text):
# Initialize the Bedrock runtime client in a specific region
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name="us-east-1")
# Specify the target model ID (Claude 3.5 Sonnet)
model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0"
# Construct the standardized Messages API payload
body = json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"temperature": 0.2,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": prompt_text
}
]
}
]
})
try:
# Synchronously invoke the model via HTTPS POST
response = bedrock_runtime.invoke_model(
body=body,
modelId=model_id,
accept="application/json",
contentType="application/json"
)
# Parse the streaming response body
response_body = json.loads(response.get("body").read())
# Extract and return the generated text content
return response_body["content"][0]["text"]
except ClientError as e:
print(f"AWS Error: {e.response['Error']['Message']}")
raise e
# Example Execution
if __name__ == "__main__":
prompt = "Review this architecture: Web UI -> Lambda -> DynamoDB. List 3 failure modes."
print(generate_architectural_review(prompt))
Line-by-Line Code Breakdown
boto3.client(service_name=”bedrock-runtime”, …)
Establishes the SDK connection. Note the use of bedrock-runtime instead of bedrock. The runtime client handles data plane operations (invocations), while the base client handles control plane operations (listing models, creating custom models).
model_id = “anthropic.claude-3-5-sonnet-…”
Defines the unique uniform resource name for the foundational model. Ensure this matches the exact model version enabled in your console.
“anthropic_version”: “bedrock-2023-05-31”
A mandatory parameter for Anthropic models on Bedrock indicating the system schema version to process the payload.
“max_tokens”: 1000, “temperature”: 0.2
Hyperparameters optimizing response length and randomness. A lower temperature (0.2) forces deterministic, factual technical analysis.
“messages”: […]
The structured conversation array. Claude expects alternating user and assistant roles containing content blocks.
bedrock_runtime.invoke_model(…)
The execution call. accept and contentType headers must strictly specify JSON format payloads.
response.get(“body”).read()
The raw payload returns a streaming data body (StreamingBody). The .read() method buffers the complete bytes into memory before parsing.
What’s Next?
If you want to expand on this implementation, consider:
- Code for streaming responses (real-time word rendering)
- Integrating system prompts for specialized architectural persona constraints
- Setting up a VPC Endpoint via Terraform for private network routing
Want to build AI-powered applications? Join an AI hackathon on Reskilll and put these skills to work.