Skip to content

AWS

Connect an AWS account on Account → Cloud accounts. Pick AWS, then Add account. Keep that drawer open while you launch the stack.

Koltto does not ask for an access key. The stack creates a read-only role named koltto/KolttoReaders. Koltto’s own account assumes that role, and only if the ExternalId in the stack matches the one shown in the drawer.

Spend comes from the Cost and Usage Report in your S3 bucket, not from Cost Explorer. That is the same report AWS billing documents: hourly lines with resource IDs, delivered by AWS into a bucket you own.

One account vs an organization

The stack runs in one AWS account. That is the whole setup if you only have one account — no extra step.

Setup What this stack covers
One AWS account (no organization, or the only account) Inventory, CloudWatch metrics, and cost for that account.
AWS Organizations — payer Same, in the payer. CUR on the payer can include linked-account spend. Inventory and metrics stay in the payer until each member has its own role.
Member / child accounts Do not launch this stack in a member. With DeployToOrganization = Yes on the payer, AWS creates the member role there. Koltto does not ask you to open each child account.

organizations:ListAccounts is allowed so Koltto can see the org roster. The payer stays one connection in Koltto. Run Refresh data after the stack update so the new accounts show up.

What “Launch CloudFormation in AWS” does

The button does not change your account by itself. It opens the AWS CloudFormation console in us-east-1 with Koltto’s template on S3 and the ExternalId from the drawer already filled in. The cost report resource only exists in us-east-1, so every customer stack is created there. Nothing is created until you choose Create stack. You need permission in that AWS account to create IAM, and, if you let the stack create the report, S3 and a Cost and Usage Report.

When the stack finishes, this is what exists in your account:

  • A read-only IAM role koltto/KolttoReaders. Koltto can assume it only with the ExternalId from the drawer. You can remove access later by deleting the role or the stack. The stack does not create an access key.
  • Either a new hourly CUR and the bucket koltto-cur-<account-id> (prefix koltto), or only the permission to read a CUR bucket you already have. That new bucket blocks public access. Only AWS Billing, and only this account, can write objects into it. The report includes resource IDs.

The bucket is billed to your AWS account. Koltto does not host that bucket. Deleting the stack removes the role and, if this stack created the report, stops that report. The bucket and the files already in it stay, so the billing history is not erased. Delete the bucket yourself in S3 if you want it gone. A cost report you already owned is not part of this stack, so deleting the stack does not touch that bucket either.

Launch the stack

  1. In the add-account drawer, copy the ExternalId. Leave the drawer open. You can paste it again if the page reloads.
  2. Choose Launch CloudFormation in AWS.
  3. Create the stack in us-east-1. Stack name KolttoReaders. Confirm ExternalId matches the drawer. Set Region in the Koltto form to us-east-1.
  4. On the options page, before you create or update:
Option What to choose
Express mode Leave off. A failed create should roll back.
Behavior on failure Roll back all resources.
Disable deployment validations Leave off.
Resource auto-import Disable. The role and bucket already belong to this stack. Enable can adopt other resources that are not part of this change.
IAM acknowledgement Check the box. The template creates a role with a custom name.
  1. Parameters:
Parameter When to use it
ExternalId The value from the Koltto drawer. Required. Do not leave the placeholder koltto-pending.
CreateCostReport = Yes (default) New hourly CUR with resource IDs, plus bucket koltto-cur-<account-id> and prefix koltto. The stack also lets AWS Billing deliver objects to that bucket.
CreateCostReport = No You already have a CUR (legacy report or Data Exports in the same bucket). Set ExistingCurBucket and ExistingCurPrefix. The stack only creates IAM. The existing report should include resource IDs.
DeployToOrganization = No (default) One account. No roles are created in other accounts.
DeployToOrganization = Yes AWS installs the member role in every account under OrganizationalUnitId, including accounts you add later. Turn on CloudFormation StackSets trusted access in the management account first. Paste the root id (r-xxxx) from Organizations → AWS accounts.

Copy AccountId, CurS3Bucket, and CurPrefix from the stack Outputs tab into the drawer, then save. Those three are filled either way: the bucket this stack created, or ExistingCurBucket / ExistingCurPrefix when you already had a report.

The bucket name is ready when the stack completes. The first CUR file can take up to 24 hours. In the AWS Billing console, Cost and Usage Reports shows the report the stack created (or the existing one you pointed at). Inventory can start as soon as you save; spend stays empty until that file exists and you run Refresh data → Cost.

What the role is allowed to do

Read-only. Koltto cannot create, start, stop, or delete your resources.

Area Allowed actions
Identity sts:GetCallerIdentity
Organization roster organizations:ListAccounts
Inventory Read-only list and describe for EC2, EFS, load balancers, RDS, Aurora, ElastiCache, DynamoDB, ECS, EKS, Lambda, Redshift, and OpenSearch, plus s3:ListAllMyBuckets, s3:GetBucketLocation, s3:GetBucketTagging
Metrics cloudwatch:ListMetrics, cloudwatch:GetMetricData
Cost s3:ListBucket, s3:GetBucketLocation, and s3:GetObject only on the CUR bucket, not on every bucket
Other accounts When DeployToOrganization is Yes, a StackSet creates koltto/KolttoReaders in those accounts. The payer role can also sts:AssumeRole that same role.

Not included: Cost Explorer, Resource Explorer, listing object keys outside the CUR bucket, and any write action.

EC2 memory in Inventory only appears if the instance has the CloudWatch agent (or equivalent) publishing memory. CPU, disk, load balancer, and storage metrics do not need that agent.

Fields in the form

Field What to enter
Name A label in Koltto (prod-core).
Region Home region for the API. Use us-east-1 for the first connect, the same region as the stack.
ExternalId Shown by Koltto. Paste the same value into the stack. Do not invent another one.
Account ID 12-digit AWS account ID (stack output AccountId).
CUR S3 bucket Stack output CurS3Bucket. Required.
CUR prefix Stack output CurPrefix (koltto when the stack created the report). Optional if your existing report has no prefix.

After save

Koltto checks that it can assume the role. If the stack used a different ExternalId, save fails and nothing is stored. Inventory then starts. Run Refresh data → Cost so Overview and Spend Analytics fill — after the first CUR file is in the bucket. Run Metrics if you want Opportunities.

You can edit CUR bucket and prefix later.

This account becomes an organization later

Do not delete the stack. In the management account, open CloudFormation in us-east-1 and activate StackSets trusted access if it is not already on.

Update the stack KolttoReaders. Choose Replace current template and use the same S3 URL the launch button uses, so the new parameters are on the form. Leave ExternalId unchanged.

Set DeployToOrganization to Yes and OrganizationalUnitId to the root id (r-xxxx) from Organizations → AWS accounts. Use the same options table as the first launch, including Resource auto-import = Disable, and acknowledge IAM.

When the update finishes, run Refresh data in Koltto once. A child account you add later under that root gets the role from AWS. You do not add it in Koltto. A permission change later is another update of this same payer stack, not a stack in every child account.

Inventory covers EC2, EKS, RDS instances, Aurora clusters, database snapshots, ElastiCache, EBS, S3, EFS, load balancers, NAT gateways, CloudWatch log groups, and WAFv2 (regional and CloudFront). An existing stack lists the newer services only after you update it. Until that update, a missing permission skips that service and the rest of the sync continues.