AWS Setup Guide
Connect your AWS account to CloudWise with a read-only role.
If your organization has strict security policies, or you just want to evaluate CloudWise first, use Air-Gapped Mode โ analyze an offline cost export with no IAM role and no cross-account access.
๐ Security firstโ
CloudWise follows AWS security best practices:
- Read-only access for monitoring โ no write permissions, nothing in your account is changed or deleted
- Least privilege โ only the permissions detection needs
- Cross-account role, not access keys
- An External ID for each AWS account: one-click setup mints a single-use one and bakes it into the CloudFormation stack for you. The manual fallback shows you an External ID generated for your login and that account, which you paste into the stack
Every permission the role gets is listed publicly, and you can review the whole list before you grant anything: see every permission.
The monitoring role described here is read-only. Executing fixes is a separate, opt-in capability on the Agentic plan that uses a distinct, narrowly-scoped write role. See the AI Remediation Guide. Free, Shield, and Compliance never execute changes โ the agent proposes the fix and you run it.
The Compliance plan does not connect an AWS account at all: it works from Air-Gapped uploads, and this setup refuses a Compliance connection.
๐ Prerequisitesโ
- Permission to create an IAM role and a CloudFormation stack in the AWS account you want to connect
- The AWS account open in your browser (you'll create the stack in your own console)
๐ One-click setup (recommended)โ
This is the fastest path and the one most people should use. There is no template to download and no Role ARN to copy back by hand.
Step 1 โ Open AWS with the stack pre-filledโ
In CloudWise, start the Connect flow (new sign-ups land here; existing users go to Settings โ AWS Accounts) and click "Open AWS โ one-click setup".
CloudWise mints a single-use External ID for your session and opens a CloudFormation quick-create deep link in your own AWS console, with every parameter already filled in โ the read-only role name, the unique External ID, and a callback so the stack can report itself back when it finishes.
Step 2 โ Review it and click Create stackโ
The quick-create screen shows exactly what will be created: one read-only role (CloudWise-Cost-Monitoring-Role-โฆ) whose only trust is CloudWise + your single-use External ID. AWS asks you to tick an IAM acknowledgement: that's CloudFormation confirming the template creates the IAM role it just showed you. Tick it and click Create stack.
Step 3 โ CloudWise verifies and scansโ
When the stack finishes, CloudFormation reports the new role back to CloudWise automatically, and CloudWise validates the access live โ the same check a hand-pasted ARN would go through. There is nothing to paste and nothing to come back for.
The first scan then starts on its own, the moment the role is assumable. You'll see a waste total and a ranked list of findings once that scan finishes. Cost history (from your Cost and Usage Report) fills in once AWS delivers the report. See When your data appears.
Use the manual setup below. Everything downstream (verification, scanning) is identical.
๐ ๏ธ Manual setup (fallback)โ
Use this if a popup blocker stops the quick-create tab from opening, or if your team reviews and deploys CloudFormation templates by hand.
Step 1: Enter your AWS account ID and copy its External IDโ
In the Connect flow, switch to "Set it up manually instead" (on the AWS accounts page, "Prefer manual setup?"). Enter the 12-digit ID of the account you are connecting. CloudWise shows an External ID generated for your login and that account only. Copy it.
Step 2: Launch the read-only stackโ
CloudWise downloads the template to your computer and opens the CloudFormation console. In the console, choose Upload a template file (not the pre-selected "Amazon S3 URL") and pick the file you just downloaded. On the parameters screen, paste the External ID from step 1 into ExternalId, replacing the default.
CloudWise refuses a manual connection whose External ID is not the one it generated for that account. If you kept the default, update the stack with the right value and connect again.
Step 3: Create the stack and paste the outputsโ
Create the stack. When it finishes, open its Outputs tab and copy the values back into the Connect form:
- Role ARN:
arn:aws:iam::YOUR-ACCOUNT:role/CloudWise-Cost-Monitoring-Role(a one-click setup adds an extra suffix) - Cost-report S3 bucket and cost-report name
Then click Connect & start the first scan. Verification and scanning proceed exactly as in the one-click flow.
Reference: the CloudFormation templateโ
The stack CloudWise generates is the public template at cloudcostwise.io/cloudwise-cur-setup-template.yaml. It must be deployed in us-east-1. In short, it creates:
- One IAM role (
CloudWise-Cost-Monitoring-Role-โฆ) that only CloudWise's own access service role can assume, and only with your External ID:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
# 123456789012 stands in for CloudWise's account; the template fills in the real one
AWS: arn:aws:iam::123456789012:role/cloudwise-customer-access-service-role
Action: sts:AssumeRole
Condition:
StringEquals:
'sts:ExternalId': !Ref ExternalId
- One inline policy (
CloudWise-Cost-Monitoring-Policy) that lists every read-only action by name: cost data, Cost Explorer, Savings Plans, Compute Optimizer, and the describe/list/metric calls the waste checks need. It attaches no AWS managed policy and no write action. The permission list shows every action. One of them,lambda:ListFunctions, also returns your functions' environment variables; a scan through this role does not store or log them (details). - The cost-report S3 bucket and the cost report that delivers into it (a CUR 1.0 report definition or a CUR 2.0 data export).
- A one-time callback that tells CloudWise the stack finished, so you don't paste anything back. It runs on CloudWise's side and creates nothing else in your account.
Read the template itself before you build the role by hand; it is the source of truth.
โฑ๏ธ When your data appearsโ
CloudWise reads two different kinds of data on two different clocks:
- Waste findings: from the first scan. Idle NAT gateways, unattached volumes, oversized instances, and the like come from live describe calls and CloudWatch metrics, so they appear on the workspace when the first scan finishes.
- Cost history: after AWS delivers your cost report. Spend by service, trends, and month-over-month comparisons come from your AWS Cost and Usage Report. For a brand-new CUR configuration, AWS itself can take up to 24 hours to deliver the first report. That delay is on the AWS side, not CloudWise.
๐ Troubleshootingโ
The CloudFormation stack failed to createโ
- "Bucket already exists" โ this can happen on a manual setup when an earlier CloudWise stack in that account left its cost-report bucket (
cloudwise-cur-<account>-<region>). Delete the old stack and that bucket, then try again. One-click setup gives each new stack its own bucket name. - Popup never opened โ a browser popup blocker stopped the quick-create tab. Use the manual setup above.
"CloudWise could not assume this role" after the stack succeedsโ
- IAM can take a few seconds to propagate. CloudWise retries a few times automatically; after that you can retry or run Troubleshoot Connection.
- If it persists, confirm the stack created the role in us-east-1 and that no Service Control Policy blocks
sts:AssumeRole.
"No cost data available"โ
- Waste findings appear first; cost data follows once your CUR is delivered (see When your data appears).
- For a brand-new CUR, allow up to 24 hours.
- Confirm the cost-report bucket and report name were captured (one-click does this for you; manual setup requires pasting them).
๐ข Multi-account setupโ
Connect each account with its own one-click flow โ repeat the steps above per account. For AWS Organizations, run the connect flow from each account you want visibility into; consolidated views group them in CloudWise. Ensure any Service Control Policies allow the read-only actions the role requests.
๐ก๏ธ Security best practicesโ
- Least privilege โ the role grants read-only monitoring and nothing more. Review it against the public permission list.
- The External ID is specific to your account: one-click setup mints and manages it per connection; a manual setup uses the External ID CloudWise generated for your login and that account. CloudWise refuses a manual connection with any other value, including the template's default.
- Audit โ CloudTrail records every assume-role, so you can see exactly when and how CloudWise reads your account.
- Revoke anytime โ delete the CloudFormation stack in your console. The role is deleted, so the access is gone. The delete then stops with
DELETE_FAILEDon the cost-report bucket if the bucket is not empty; to remove the bucket too, empty it in S3, including every object version, and delete the stack again. If you also deployed the remediation role, delete that stack too; it has no bucket, so its delete finishes in one step.
๐ Need help?โ
- ๐ IAM Best Practices Guide
- ๐ง Troubleshooting Guide
- ๐ฌ Community Forum
- โ๏ธ support@cloudcostwise.io
๐ Read-only: nothing in your account is changed. ๐ Real numbers: a waste total from your first scan.