CostLensAWS Accounts

AWS Accounts

Connect an AWS account to CostLens in one click — CloudFormation provisions the role automatically and CostLens detects the connection with no copy-pasting.

Updated September 202612 min read

CostLens reads your AWS cost data and resource configuration using a cross-account IAM role. The guided Add Account wizard is the fastest way to connect — it opens a pre-filled CloudFormation stack, creates the role for you, and detects the connection automatically. No IAM console work and no values to copy back into CostLens.

Prefer to do it by hand?

If your organization requires manual IAM review, the manual setup further down still works — same trust model, same role, just typed in yourself.

How it works

StepWhat happens
1. Choose access levelRead-Only (monitoring, reporting, recommendations) or Read/Write (adds Auto-Fix). Read-Only is the default and is enough for everything except applying fixes.
2. Review exactly what's grantedBefore anything is created, CostLens shows the precise IAM permissions it's about to request — no surprises.
3. AuthorizeOpens AWS CloudFormation with the template, stack name, and parameters pre-filled. You click Create stack.
4. CostLens detects it automaticallyThe stack's own notifier reports back to CostLens the moment it finishes — you don't need to return to CostLens or paste anything.
5. First sync startsBilling sync, optimization checks, and AI explanations run automatically once connected.

Connect a new AWS account

Step 1 — Add Account → AWS → choose access level

From the Accounts page, click Add Account, choose AWS, then choose Read-Only or Read/Write. The next screen shows exactly what CostLens is about to be granted:

Access levelGrantsEnables
Read-OnlyReadOnlyAccess, Cost Explorer reads (ce:Get*/ce:List*), Compute Optimizer signals, CUR ingestion (if configured), resource-inventory enumerationBilling visibility, inventory, anomaly detection, recommendations & savings estimates
Read/WriteEverything in Read-Only, plus the specific EC2/EBS/CloudWatch-Logs/S3 actions CostLens's reversible remediations use — never AdministratorAccess or broad adminEverything in Read-Only, plus Apply Fix and Auto-Fix

The trust model is a cross-account IAM role assumed via sts:AssumeRole with a unique External ID (confused-deputy protection) — CostLens never creates or stores AWS access keys for this flow.

Step 2 — Authorize

Click Authorize. This opens AWS CloudFormation Quick-Create in a new browser tab, signed into whichever AWS account your browser is currently authenticated as, with everything pre-filled:

  • The CostLens-hosted template
  • A stack name unique to your CostLens organization (costlens-<id>)
  • Your External ID (also shown in CostLens if you need to copy it)
  • The access level you chose

Make sure you're signed into the right AWS account

Quick-Create runs against whatever AWS account is active in that browser tab. Double-check the account switcher in the top-right of the AWS Console before clicking Create stack.

Step 3 — Create stack

In the AWS tab, review the stack (nothing to edit — the parameters are already filled in) and click Create stack. CloudFormation provisions an IAM role named CostLensAccessRole, trusting CostLens's account with your External ID, and attaches exactly the permissions your chosen access level requires.

Step 4 — CostLens connects automatically

Once the stack reaches CREATE_COMPLETE, its notifier reports the account ID straight back to CostLens — the wizard's "Finishing automatically…" screen updates on its own within a few seconds, no action needed. First sync (billing → optimization checks → AI explanations) starts immediately.

Stack taking a while, or want to skip waiting?

If auto-detection hasn't finished after about 25 seconds, the wizard offers a manual fallback: type in your 12-digit AWS account ID (found in your AWS Console) and click Connect account to finish immediately — useful if outbound webhooks are blocked in your AWS environment.

Reconnecting, or connecting a second AWS account

CostLens can't see into an AWS account before you grant it access, so it can't always know in advance whether "Authorize" should create a new role or reuse one that already exists. It handles this in two ways:

Automatic reuse. If your organization previously connected an AWS account to CostLens and later removed it, clicking Add Account → AWS shows "Found and verified your existing connection" immediately — CostLens already checked that account's role still works and skips CloudFormation entirely. Click Continue to finish.

Explicit choice. If your organization has connected AWS before but CostLens can't automatically verify a reusable role (e.g. you're adding a genuinely different, second AWS account), the Review screen replaces the single Authorize button with two options:

ButtonUse when
New AWS accountYou're signed into an AWS account CostLens has never touched — opens Quick-Create (Create stack)
Reconnect / update existingYou're signed into an AWS account CostLens has already set up before — opens Update stack, which refreshes the role's trust policy with the current External ID instead of creating a new one

Seeing "Resource of type AWS::IAM::Role... already exists"?

That means you clicked New AWS account (or plain Authorize) while signed into an AWS account that already has a CostLensAccessRole from an earlier connection. Close that error and use Reconnect / update existing instead — it updates the same stack rather than trying to create a duplicate.

If you go ahead and connect an account that turns out to already be active in your CostLens organization, you'll see "This account already exists — it's already connected. Nothing was added again" on the success screen, rather than a misleading "new account connected" message.

Connect an entire AWS Organization (multi-account)

If you manage many AWS accounts under an AWS Organization, click Connect an organization from the Accounts page instead of adding accounts one at a time:

  1. Pick a seed account — an already-connected account whose role has organization-level reach (typically the management account).
  2. First time only: expand "Grant organization-wide access" for a generated script that extends the seed account's role to every member account (via CloudFormation StackSets).
  3. Click Discover & connect — CostLens enumerates every member account under the seed and connects each one, showing a live per-account result (Connected / Failed / Skipped). Accounts already connected are updated, not duplicated; a failed account gets an "Enter details manually" link so one bad account never blocks the rest.

Alternative: create the IAM role by hand

If you'd rather not use CloudFormation (e.g. your organization requires manual IAM review before any role is created), you can create the role yourself and paste its details into CostLens instead — same trust model, same permissions, same role name.

Step 1 — AWS Console → IAM → Roles → Create role

Log in to console.aws.amazon.com. Search for IAM, open Roles, and click Create role.

Step 2 — Configure the trusted entity

FieldValue
Trusted entity typeAWS account
Which AWS accountAnother AWS account
Account IDCostLens's AWS account ID (shown in CostLens's onboarding wizard)
OptionsCheck "Require external ID"
External IDYour CostLens organization's External ID — shown on the wizard's manual-entry step ("CostLens External ID", with a Copy button)

Leave MFA unchecked. Click Next.

Step 3 — Attach permissions

Read-only scan — search for ReadOnlyAccess and attach the AWS-managed policy:

# 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.

Apply Fix permissions (only if you chose Read/Write) — after creating the role, open it → Add permissions → Create inline policy → JSON, name it CostlensApplyFix, and paste:

json
{
  "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": "*"
  }]
}

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 4 — Name the role and create it

Name the role CostLensAccessRole (the same name CloudFormation would have used — CostLens assumes this name by default, so using it means you don't have to paste the ARN back). Verify the Trusted entities section shows CostLens's account ID and your External ID condition, then click Create role.

Step 5 — Paste into CostLens

Back in the CostLens wizard's manual-entry step, enter your 12-digit AWS account ID. Leave IAM role ARN blank (CostLens assumes CostLensAccessRole in that account) — or paste the full ARN if you used a different role name. Click Connect account.

Additional billing source: Cost & Usage Reports (optional)

Once an AWS account is connected via IAM Role, its account card shows a Billing Data Source panel where you can optionally layer on Cost & Usage Reports (CUR) — a more granular, resource-level billing export than Cost Explorer provides. This reuses the same CostLensAccessRole you already created (just add s3:GetObject/s3:ListBucket on the CUR bucket to its policy) — no separate role. See the dedicated Cost & Usage Reports guide for the full setup.

Kubernetes (EKS) cost & optimization

The ReadOnlyAccess policy attached above already covers everything CostLens needs for EKS — eks:List*/Describe*, Auto Scaling, EC2 and CloudWatch reads for the node-pool checks, plus Cost Explorer for Kubernetes cost. No extra IAM is required. Two capabilities depend on an AWS billing setting (not a permission):

Node-pool optimization — no setup needed

CostLens follows each EKS managed node group to its EC2 Auto Scaling Group and reads node CPU from CloudWatch. Idle / right-sizing / Spot node-pool recommendations appear on the Recommendations page automatically. See Kubernetes Optimization.

Per-cluster node cost — activate the cluster cost-allocation tag

In AWS Billing → Cost allocation tags, activate the AWS-generated aws:eks:cluster-name tag. AWS then tags each cluster's node compute (EC2 / EBS / networking) so CostLens can total it per cluster in the Kubernetes panel on the Billing page.

Per-namespace & per-workload cost — enable Split Cost Allocation Data

In AWS Cost Management → Cost allocation tags, enable Split Cost Allocation Data for EKS, then activate the aws:eks:namespace (and aws:eks:workload-name for workload-level) tags. AWS splits each node's cost across its pods and tags the result, which CostLens reads via Cost Explorer. Data appears within ~24 hours. See Kubernetes Costs.

No agent, no cluster access

CostLens reads EKS cost and utilisation entirely from Cost Explorer and CloudWatch — there is nothing to install in the cluster and no Kubernetes API access is required. Cost Explorer bills $0.01 per request on your account; CostLens caches Kubernetes cost queries for 6 hours and records the namespace trend only once a month, so it adds only a few cents.

Adding Apply Fix permissions later

Connected with Read-Only and want Auto-Fix later? Open your CostLensAccessRole IAM role in AWS → Add permissions → Create inline policy → JSON and paste the CostlensApplyFix JSON from the manual-setup section above.

Without the Apply Fix policy, the "Apply Fix" button on recommendations is disabled. Scanning and recommendations work fully with Read-Only access alone.

First sync phases

After connecting, 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.

Managing connected accounts

ActionWho can do itDescription
Sync NowOperators, AdminsTriggers an immediate billing sync
Test ConnectionOperators, AdminsRe-validates the role without changing anything
Edit CredentialsAdmins onlyUpdate the account name, or swap in a different Role ARN
Remove AccountAdmins onlyDisconnects and permanently deletes all associated data — cannot be undone. CostLens remembers the role/External ID even after removal, so reconnecting the same account later can skip CloudFormation entirely (see "Automatic reuse" above).

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
Resource of type 'AWS::IAM::Role'... already exists (in the AWS Console, during Quick-Create)This AWS account already has a CostLensAccessRole from an earlier connection. Close the error and use Reconnect / update existing on the Review screen instead of Create/Authorize — see "Reconnecting, or connecting a second AWS account" above.
"Found and verified your existing connection" appears unexpectedlyCostLens detected a working role from a previous connection for your organization and is offering to skip CloudFormation — this is expected when reconnecting a removed account. Click Continue, or close the wizard and use Add Account again if you actually meant to add a different AWS account.
Stack finishes but CostLens doesn't detect itAuto-detection can occasionally miss a network hiccup or take longer than expected — CostLens automatically retries for a few minutes if the role validation itself is the holdup. If it's still not connected after that, enter your 12-digit AWS account ID in the manual-fallback field on the same screen.
AccessDenied: not authorized to assume role / IAM_ROLE_NOT_TRUSTEDThe External ID in the role's trust policy doesn't match, or the role was deleted. Open the role in AWS → Trust relationships → verify sts:ExternalId matches the value CostLens shows you 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. Alternatively, use Cost & Usage Reports as a billing data source — CUR does not require Cost Explorer.
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.
CostLens
Previous
Dashboard
CostLens
Next
Azure Accounts