Claude Platform on AWS in Practice

Terraform for Claude Platform on AWS

Almost everything that governs your Claude access on AWS — roles, policies, network paths — is ordinary AWS infrastructure. Which means it belongs in Terraform, not in someone's console history.

Claude 3P 101 · Updated July 2026 · Unofficial guide

Claude Platform on AWS is Anthropic-operated, but its control surface on your side is plain AWS: IAM policies against the aws-external-anthropic service, network endpoints, and (if you use API-key auth) secrets. All of that is expressible with the standard Terraform AWS provider — no special plugin required. This article maps the pieces to resources and sketches a promotion plan across environments.

What Terraform manages — and what it doesn't

Draw the line early. Terraform-managed: IAM roles and policies, Secrets Manager entries for any API keys, VPC endpoints, CloudTrail configuration. Not directly Terraform-managed: the AWS Marketplace subscription and Anthropic organization setup (a one-time signup flow), Claude Console roles (assigned by an Anthropic account representative), and the workspaces themselves — those are created from the AWS Console Workspaces page or through the Admin API workspace endpoints. Treat workspace IDs as inputs to your Terraform modules (variables per environment), and if you want workspace creation automated, do it in a pipeline step calling the Admin API, run by a role scoped with the documented provisioning pattern: CreateWorkspace, GetWorkspace, ListWorkspaces, UpdateWorkspace, ArchiveWorkspace on Resource: "*" — and deliberately no inference permissions.

The IAM module

The core module output is an application role with a least-privilege inference policy bound to one workspace ARN. The ARN format is arn:aws:aws-external-anthropic:{region}:{account-id}:workspace/{workspace-id}, where the workspace ID is the tagged wrkspc_... value your app also passes as ANTHROPIC_AWS_WORKSPACE_ID. In Terraform terms this is an aws_iam_policy attached to an aws_iam_role, with the region, account, and workspace ID supplied as module variables. The policy document itself — the part worth reviewing carefully — is Anthropic's documented minimal single-workspace inference policy:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["aws-external-anthropic:CreateInference",
               "aws-external-anthropic:CountTokens",
               "aws-external-anthropic:GetModel",
               "aws-external-anthropic:ListModels",
               "aws-external-anthropic:GetWorkspace"],
    "Resource": "arn:aws:aws-external-anthropic:us-west-2:123456789012:workspace/wrkspc_01AbCdEf23GhIj"
  }]
}

Three IAM subtleties to encode in code review rather than rediscover in an incident. First, wildcards over-match: *File also matches the UserProfile actions because "Profile" ends in "file" — enumerate Files actions explicitly. Second, route-less actions like CallWithBearerToken and AssumeConsole do not bind to workspace ARNs; grant them in a separate statement on Resource: "*" when needed. Third, CreateInference and CreateBatchInference are separate actions — a policy meant to block all model calls must deny both.

Secrets and network

Prefer SigV4 (role-based) auth everywhere you can — then there is no secret to manage. Where a component genuinely needs a bearer token, store the AWS Console-generated API key in an aws_secretsmanager_secret with rotation reminders, and grant the consuming role CallWithBearerToken. For private connectivity, Claude Platform on AWS supports AWS PrivateLink, so a VPC endpoint (aws_vpc_endpoint) keeps traffic to the regional endpoint (https://aws-external-anthropic.{region}.api.aws) off the public internet — check the official docs for the current service name to reference in the endpoint resource.

Environment promotion

Use one module, instantiated per environment with different variables: workspace ID, region, and environment name. Two facts shape the design. Workspaces are bound to a single AWS region, so the region variable and workspace variable must move together — you cannot point a us-east-1 stack at a us-west-2 workspace. And the account-level prerequisite aws iam enable-outbound-web-identity-federation must be run once per AWS account before any request works; if dev, staging, and prod live in separate accounts (a good idea anyway), make it part of each account's bootstrap. Promotion then looks like: apply to dev, run your evaluation suite against the dev workspace, promote the identical plan to staging and prod with only the variable file changing.

Rule of thumb: if a permission change for Claude access can't be traced to a pull request, it didn't go through Terraform — and it will be the thing your next access review can't explain.

Where to go next

See IAM policy templates for more ready-made policy shapes, the VPC endpoint guide for PrivateLink details, and CI/CD integration for the pipeline that applies these plans.

Sources