Support Portal
costlensaws accounts

AWS Accounts

Connect your AWS accounts to CostLens using an IAM Role or Access Keys.

Last updated: May 2025

CostLens reads your AWS cost data and resource configurations using a cross-account IAM role. The setup takes about 5 minutes and requires no code changes or agents in your AWS environment.

How it works

StepWhat happens
1. You create an IAM RoleIn your AWS Console, create a role that trusts CostLens's AWS account and attach read-only permissions.
2. External ID prevents hijackingYour unique External ID is required to assume the role — it prevents any other party from using CostLens's identity to access your account.
3. CostLens scans automaticallyBilling data syncs every 6 hours. Optimisation checks and AI explanations run every 12 hours. You can trigger a manual sync at any time.

What is the External ID?

When you click Add Account, a unique External ID (a UUID like 550e8400-e29b-41d4-a716-446655440000) is generated and displayed in the form. You must paste this value into your AWS IAM role trust policy. It acts as a shared secret — without it, no one can assume your role, even if they know your Role ARN. Keep it private and treat it like a password. It is always visible on your account card if you need to copy it again.

Step 1 — Open CostLens → Accounts → Add Account

Click Add Account in the top-right corner of the Accounts page. Select IAM Role (recommended). Your unique External ID is shown in the form — copy it now, you will paste it into AWS Console in step 3.

Step 2 — Go to AWS Console → IAM → Roles → Create role

Log in to console.aws.amazon.com. Search for IAM in the top bar, open Roles in the left nav, and click Create role.

Step 3 — Configure the trusted entity

On the "Select trusted entity" screen:

FieldValue
Trusted entity typeAWS account
Which AWS accountAnother AWS account
Account IDEnter the CostLens AWS account ID (shown in the trust policy JSON in the connect dialog)
OptionsCheck "Require external ID"
External IDPaste the External ID you copied from CostLens in Step 1

Leave MFA unchecked. Click Next.

Step 4 — Attach ReadOnlyAccess + Apply Fix policy

Step 4a — Scan only

Search for ReadOnlyAccess and select the AWS-managed policy. This lets CostLens scan for waste and surface recommendations.

# Covered by ReadOnlyAccess (scanning)
ce:GetCostAndUsage, ce:GetCostForecast
ec2:DescribeInstances, DescribeVolumes, DescribeAddresses
rds:DescribeDBInstances
cloudwatch:GetMetricStatistics
With ReadOnlyAccess alone, CostLens can detect waste but cannot apply fixes.

Step 4b — Apply Fix permissions (recommended)

After attaching ReadOnlyAccess, click NextCreate role. Then open the role → Add permissionsCreate inline policyJSON and paste:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "CostlensApplyFix",
    "Effect": "Allow",
    "Action": [
      "ec2:DeleteVolume",
      "ec2:DeleteSnapshot",
      "ec2:TerminateInstances",
      "ec2:ModifyVolume",
      "ec2:ModifyInstanceAttribute",
      "ec2:StopInstances",
      "ec2:StartInstances",
      "ec2:ReleaseAddress",
      "ec2:CreateTags",
      "ssm:SendCommand",
      "ssm:GetCommandInvocation",
      "rds:DeleteDBInstance",
      "rds:StopDBInstance",
      "rds:StartDBInstance",
      "rds:AddTagsToResource",
      "scheduler:CreateSchedule",
      "scheduler:CreateScheduleGroup",
      "scheduler:GetScheduleGroup",
      "iam:GetRole",
      "iam:CreateRole",
      "iam:PutRolePolicy",
      "iam:PassRole",
      "logs:PutRetentionPolicy",
      "logs:DescribeLogGroups"
    ],
    "Resource": "*"
  }]
}

Name the inline policy CostlensApplyFix and save.

What each permission enables:

  • ec2:DeleteVolume / DeleteSnapshot — remove unused EBS volumes & snapshots
  • ec2:TerminateInstances — terminate long-stopped EC2 instances
  • ec2:StopInstances / StartInstances / ModifyInstanceAttribute — schedule & rightsize EC2 instances
  • ec2:ModifyVolume + ssm:* — expand full EBS volumes live (no downtime)
  • ec2:ReleaseAddress — release unattached Elastic IPs
  • rds:DeleteDBInstance — delete idle RDS databases
  • rds:StopDBInstance / StartDBInstance — schedule RDS stop-start
  • scheduler:* + iam:* — create EventBridge schedules for automated stop-start
  • logs:PutRetentionPolicy / DescribeLogGroups — set 30-day retention on CloudWatch Log Groups

Step 5 — Name the role and create it

On the "Name, review, and create" screen, set the role name to AezonaCostlens. Scroll down and verify the Trusted entities section shows the CostLens Account ID and your External ID condition. Click Create role.

Step 6 — Copy the Role ARN back into CostLens

In AWS Console, open the newly created role. Copy the ARN shown at the top:

arn:aws:iam::123456789012:role/AezonaCostlens

Go back to the CostLens connect dialog, paste it into the Role ARN field, optionally enter an account name, then click Test Connection. Once the test passes, click Connect Account to save.

First sync phases

After saving, a first-sync progress panel appears. It runs three phases in sequence:

PhaseDuration
Fetching billing data10 s – 2 min — pulls monthly and daily cost history from AWS Cost Explorer
Running optimisation checks30 s – 3 min — scans EC2, EBS, RDS, networking, Lambda, and CloudWatch for waste
Generating AI explanations20 s – 1 min — Aevi writes plain-English explanations and savings estimates

The panel auto-dismisses after completion. The account card then shows In sync and a last-synced timestamp.

Create a dedicated IAM User

In AWS IAM, create a dedicated IAM User (not your personal user). Attach the ReadOnlyAccess policy.

Generate access keys

Under the user's Security credentials tab, click Create access key. Select "Third-party service" as the use case. Copy both the Access Key ID and Secret Access Key.

Paste into CostLens

In CostLens, click Add Account, select Access Keys in the auth method toggle, and paste both values. CostLens encrypts them at rest using AES-256.

Tip

Rotate access keys every 90 days. Never use AWS root account credentials. Create a dedicated IAM user with only the minimum permissions required.

Adding Apply Fix permissions later

If you skipped Step 4b, you can add the CostlensApplyFix inline policy at any time by opening your AezonaCostlens IAM role in AWS → Add permissions → Create inline policy → JSON and pasting the JSON from Step 4b.

Without the Apply Fix policy, the "Apply Fix" button on recommendations is disabled. Scanning and recommendations work fully with ReadOnlyAccess alone.

Managing connected accounts

ActionWho can do itDescription
Sync NowOperators, AdminsTriggers an immediate billing sync
Edit CredentialsAdmins onlyOpens the connect dialog to update the Role ARN or swap auth method
Setup GuideAdmins only (IAM Role accounts)Opens the full IAM role setup guide with your External ID pre-filled
Remove AccountAdmins onlyDisconnects and permanently deletes all associated data — cannot be undone

Sync status reference

StatusMeaning
Not syncedAccount has never been synced
Syncing…A sync is in progress
In syncLast sync completed successfully
Sync failedThe sync encountered an error — expand the card to see details and a Try again button

Common errors and fixes

ErrorFix
AccessDenied: not authorized to assume roleThe External ID in your IAM trust policy doesn't match. Open the role in AWS → Trust relationships → verify sts:ExternalId matches exactly.
AWS Cost Explorer not enabledGo to AWS Console → Cost Explorer → Enable Cost Explorer. It can take up to 24 hours for data to appear.
InvalidClientTokenId / no such access keyThe Access Key ID is wrong or deactivated. Regenerate a new access key and use Edit Credentials to update it.
The requested resource does not exist (role ARN)Double-check the Role ARN is copied exactly as shown in the AWS Console, including the correct 12-digit account number.
Sync stuck in one phase for more than 10 minutesClick Force retry or click Sync Now on the account card to restart.
Previous
Getting Started
Next
Recommendations