Skip to content

Onboarding: AWS

This guide wires your AWS environment into Venturi. It assumes one AWS account and one customer-side workload identity (GitHub Actions OIDC, EKS IRSA, or similar) that will assume the role.

Time required

~15 minutes of click-and-paste, plus a single terraform apply.

What this grants Venturi

A cross-account IAM role that Venturi assumes from its own production account, restricted to read-only APIs:

  • Cost & billing — Cost Explorer (ce:Get*), Cost & Usage Report S3 bucket (s3:GetObject / s3:ListBucket on the CUR bucket only), pricing catalog (pricing:*).
  • Bedrock (optional, default on) — foundation/custom model metadata, invocation-logging configuration, inference profiles, provisioned-throughput inventory.
  • CloudWatch & CloudTrail — metrics, log events, and Bedrock API call history for the period under analysis.
  • Identity inventory — IAM roles/users listing (no policy mutation) and Organizations hierarchy read.

It does not grant write access to any AWS API. check_permissions.py in the platform repo enforces this at gate time; the role's policy is verifiable in infra/aws/onboarding/main.tf.

Step 1 — Get the values Venturi will provide

Email [email protected] and ask for:

  • venturi_account_id — the AWS account ID Venturi assumes from.
  • external_id — a per-customer string for the sts:ExternalId condition. Treat as moderately sensitive (a confused-deputy mitigation, not a full secret).

You will provide back to Venturi:

  • The role_arn output from terraform apply.
  • The S3 bucket where your Cost & Usage Reports are delivered (cur_bucket_name).
  • (Optional) the cur_report_prefix, if your CUR uses a non-default prefix.

Step 2 — Configure your terraform.tfvars

Create terraform.tfvars in infra/aws/onboarding/ (or wherever you've vendored the module):

aws_region        = "us-east-1"               # the region your CUR bucket lives in
venturi_account_id = "<from Venturi>"
external_id       = "<from Venturi>"
cur_bucket_name   = "my-org-cur-bucket"
cur_report_prefix = "cur/"                    # optional, default depends on your CUR config

enable_bedrock_access = true                  # default true; flip to false if not using Bedrock

A complete terraform.tfvars.example ships in the module directory.

Step 3 — Apply

cd infra/aws/onboarding
terraform init
terraform plan        # confirm the role + policies that will be created
terraform apply

terraform apply prints two outputs:

  • role_arn — paste this into your reply to Venturi.
  • granted_permissions — a human-readable summary of what was granted; keep for audit.

Step 4 — Verify

You don't have to take Venturi's word that access is read-only. From inside your AWS account:

cd infra/aws/onboarding
./scripts/verify.sh

The script assumes the role under the same trust policy Venturi uses, then exercises one Get/List call per granted service. Pass = each call returns success or a 4xx that's clearly an access-scoped not-found (not 403). Any 403 means a permission gap; any 200 on a write API is a security finding and the script exits non-zero.

Step 5 — Hand the role ARN to Venturi

Reply to your onboarding email with:

role_arn:        <terraform output>
cur_bucket:      <bucket name>
cur_prefix:      <prefix>           (if non-default)
region(s):       us-east-1, ...     (any region where you want Bedrock or CW Logs inventoried)
notes:           <anything Venturi should know about your account layout>

Venturi responds within 1 business day confirming the role is reachable and that ingestion has started.

Rotating the external_id

Recommended every 12 months:

  1. Ask Venturi for a new external_id.
  2. Update terraform.tfvars and terraform apply.
  3. Confirm Venturi can still assume the new role before destroying the old trust.

Removing access

cd infra/aws/onboarding
terraform destroy

This deletes the IAM role and its policies; Venturi loses visibility within ~5 minutes. Notify Venturi first so attribution ingestion can pause cleanly.

Troubleshooting

Symptom Most likely cause
Venturi reports "AccessDenied" assuming the role external_id mismatch — confirm with your onboarding contact.
Venturi reports CUR data is missing CUR bucket name or prefix doesn't match terraform.tfvars.
Venturi reports Bedrock data is missing enable_bedrock_access = false, or Bedrock invocation logging isn't enabled. See AWS docs.
terraform apply fails on iam:CreateRole The caller lacks IAM admin. Run as a user with IAMFullAccess or equivalent.

Reference