Skip to content

AWS cost audit. What you can save, and where.

An AWS cost audit at a fixed price per package. You get a list of changes with a saving figure next to each, and I only need read-only access to the account.

Or email jacob@codelevel.pl.

I reply within 1 business day.

Sample data, from the sample report: a bill of USD 4,050 a month, 10 changes, USD 1,386 a month less (34%). Your result depends on your account.

Where the excess comes from

Most often you pay for resources nobody uses any more, for machines bigger than the traffic needs, and for data kept in the most expensive storage class. Add to that no Savings Plans on a steady load, and traffic nobody costed when the system was designed.

What I check

  • The largest items on the bill: EC2, RDS, EBS, S3, data transfer, NAT Gateway, CloudWatch.
  • Instance size and type against the real load, including a move to Graviton.
  • Savings Plans and Reserved Instances: how much to commit to without paying for headroom.
  • Unused volumes, snapshots, IP addresses, and test environments running all night.
  • Tags, budgets and cost alerts, so the bill does not creep back up.

What you get

A report with a list of changes and a saving figure next to each, split into changes that need no code and changes that need your team’s time. I walk you through it on a call. If you want, I make the changes myself, in Terraform.

The method comes from optimising two SaaS platforms in my case studies: Savings Plans, rightsizing and Graviton.

Before you email me, you can read a whole sample report, also as a PDF. The data in it is sample data that does not come from any client, but the layout and level of detail match a real report. The result of the example is not a forecast of your audit. The savings depend on your account.

You can also load a Cost Explorer export into the CSV analysis. It shows how the bill splits and the usual savings signals, and the file never leaves your browser. It is a quick look, not an audit.

Not sure yet whether an audit is worth it? Answer 8 questions about your bill. You see the result straight away, without giving an e-mail address.

Guarantee

If the yearly savings identified in the report add up to less than the audit fee, I refund everything you paid. For AWS bills from USD 800 net a month. How I calculate savings and how to claim: full terms.

Audit packages

The package depends on the size of the bill and the number of accounts. Audits S and M have a fixed price for the scope described with the package; audit L is priced after a short call.

  1. Audit S

    EUR 690

    AWS bill up to USD 2,500 a month, one account

    5 working days

    • the 8–10 largest cost items
    • a report with a saving figure next to every recommendation
    • a 60-minute walkthrough of the results
    • 14 days of follow-up questions by e-mail
    Order audit S
  2. Audit M

    EUR 1,150

    bill of USD 2,500–8,000 a month, up to three accounts (AWS Organizations included)

    7–10 working days

    • everything in Audit S
    • every service above 3% of the bill
    • Savings Plans and Reserved Instances, EKS if you run it
    • a Hetzner or OVH comparison for one or two components
    Order audit M
  3. Audit L

    quote

    over USD 8,000 a month, or more than three accounts

    2–3 weeks

    • full scope, priced after a short call
    Ask for a quote

How the audit goes

  1. Day 0

    You write

    A few sentences and a rough monthly bill. I reply with questions and a suggested package.

  2. Day 1

    Contract and access

    A contract with the package price, and an NDA if you want one. You create a read-only role with the policy below: a few minutes in the console or in Terraform.

  3. S: 5 working days, M: 7–10 working days, L: 2–3 weeks

    Audit

    I read the bill, the metrics and the resource configuration. I change nothing in the account. The time runs from when I get access.

  4. End of the audit

    Report and walkthrough

    A report with a saving figure next to every change, and a 60-minute walkthrough. For 14 days I answer follow-up questions by e-mail.

  5. After the walkthrough

    You remove the access

    You delete the role. You make the changes from the report yourself, with your team, or have me do them, in Terraform.

Access: read-only, none of your data

The managed ReadOnlyAccess policy can read S3 objects, logs and data in your databases. A cost audit does not need any of that, so I ask for a narrower policy: billing and Cost Explorer read, CloudWatch metrics and resource descriptions. It has no s3:GetObject, no log reads, no secrets and no DynamoDB data.

  • You attach the policy to a role my AWS account assumes (with an ExternalId I send you by e-mail), or to a named user with MFA. Your choice.
  • With AWS Organizations, you create the role in the management account, where the whole bill and the Savings Plans are, and in the accounts with the resources. I prepare a StackSet or a Terraform module for it.
  • API calls made with this role show up in your CloudTrail event history.
  • I do not read Lambda function configuration or ECS task definitions, because they hold environment variables. Their cost shows in Cost Explorer and in the metrics.
  • If something needs logs, for example VPC Flow Logs, I give your team a ready query and you send me back only the result.
  • If you have a CUR 2.0 export (Data Exports), I do not read it from your S3. For an L audit I ask you to send 3 months of the export, or to create a separate, one-off role limited to the CUR bucket.
  • A day before, enable Cost Explorer, Compute Optimizer and Cost Optimization Hub (all free). My role only reads, so it cannot enable them itself. The first data appears within about 24 hours.
  • AWS charges USD 0.01 per Cost Explorer API request. For an audit that is usually a few dollars on your bill.
  • After the walkthrough you delete the role or the user, and my access ends there.
IAM policy for the cost audit (JSON)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BillingAndCostRead",
      "Effect": "Allow",
      "Action": [
        "ce:Describe*",
        "ce:Get*",
        "ce:List*",
        "cur:DescribeReportDefinitions",
        "bcm-data-exports:GetExport",
        "bcm-data-exports:ListExports",
        "billing:GetBillingData",
        "billing:GetBillingDetails",
        "billing:GetCredits",
        "budgets:ViewBudget",
        "savingsplans:Describe*",
        "compute-optimizer:Describe*",
        "compute-optimizer:Get*",
        "cost-optimization-hub:Get*",
        "cost-optimization-hub:List*",
        "organizations:Describe*",
        "organizations:List*",
        "pricing:DescribeServices",
        "pricing:GetAttributeValues",
        "pricing:GetProducts"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DescribeResourcesNoData",
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*",
        "autoscaling:Describe*",
        "elasticloadbalancing:Describe*",
        "rds:Describe*",
        "rds:ListTagsForResource",
        "elasticache:Describe*",
        "es:Describe*",
        "es:ListDomainNames",
        "eks:Describe*",
        "eks:List*",
        "ecs:DescribeClusters",
        "ecs:DescribeServices",
        "ecs:ListClusters",
        "ecs:ListServices",
        "ecr:DescribeRepositories",
        "elasticfilesystem:DescribeFileSystems",
        "dynamodb:DescribeTable",
        "dynamodb:ListTables",
        "cloudfront:ListDistributions",
        "s3:GetBucketLocation",
        "s3:GetBucketTagging",
        "s3:GetBucketVersioning",
        "s3:GetIntelligentTieringConfiguration",
        "s3:GetLifecycleConfiguration",
        "s3:ListAllMyBuckets",
        "cloudwatch:DescribeAlarms",
        "cloudwatch:GetMetricData",
        "cloudwatch:GetMetricStatistics",
        "cloudwatch:ListMetrics",
        "logs:DescribeLogGroups",
        "tag:GetResources"
      ],
      "Resource": "*"
    },
    {
      "Sid": "NoDataNoSecrets",
      "Effect": "Deny",
      "Action": [
        "s3:GetObject*",
        "dynamodb:BatchGetItem",
        "dynamodb:GetItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "logs:FilterLogEvents",
        "logs:GetLogEvents",
        "logs:StartQuery",
        "rds:DownloadDBLogFilePortion",
        "secretsmanager:GetSecretValue",
        "ssm:GetParameter*",
        "ec2:DescribeInstanceAttribute",
        "ec2:DescribeLaunchTemplateVersions",
        "autoscaling:DescribeLaunchConfigurations",
        "ec2:DescribeSpotInstanceRequests",
        "ec2:DescribeSpotFleetRequests",
        "lambda:GetFunction*",
        "ecs:DescribeTaskDefinition"
      ],
      "Resource": "*"
    }
  ]
}

Send me your AWS bill

Within 2 business days I will reply with 3 concrete observations.

I do not need access to the account. A PDF invoice from the console or a Cost Explorer export for the last 3 months is enough.

Only I read the file, and I do not paste it into AI tools. I delete it when you ask, and after 12 months at the latest.

Questions about the audit

Why does my AWS bill keep growing when traffic has not changed?

Part of the cost grows with time, whatever the traffic. CloudWatch log groups never expire by default, and old snapshots, idle IP addresses and load balancers with no traffic cost money every month until someone removes them. Then there is the NAT Gateway, which charges for every gigabyte, including traffic to S3 in the same region when there is no VPC endpoint. For a first look, load a Cost Explorer export into the CSV analysis: it shows the split of the bill and common saving signals. The audit shows how much of it you can get back.

Cost Explorer CSV analysis, the file never leaves your browser

Link to this question: Why does my AWS bill keep growing when traffic has not changed?
Do I have to give you access to the account?

For the audit, yes, but read-only and with no access to your data: the IAM policy is shown above. Without access I can look at a Cost Explorer export, but that is a quick look, not an audit: a bill does not show how loaded your servers are.

Link to this question: Do I have to give you access to the account?
Do you change anything in the account during the audit?

No. The policy only allows reading. You make the changes from the report yourself, or order them from me separately, after the walkthrough.

Link to this question: Do you change anything in the account during the audit?
Which package should I choose?

Audit S: AWS bill up to USD 2,500 a month, one account. Audit M: bill of USD 2,500–8,000 a month, up to three accounts (AWS Organizations included). Audit L: over USD 8,000 a month, or more than three accounts. If you are not sure, tell me what you pay a month and I will suggest one.

Link to this question: Which package should I choose?
Is an audit worth it on a small AWS bill?

Yes, that is what audit S is for: AWS bill up to USD 2,500 a month, one account, EUR 690 net. If the yearly savings identified in the report add up to less than the audit fee, I refund everything you paid. The guarantee applies to bills from USD 800 net a month. On a smaller bill, start with the free Cost Explorer CSV analysis: it shows whether there is anything to look for.

Cost Explorer CSV analysis

Link to this question: Is an audit worth it on a small AWS bill?
How long does the audit take?

Audit S takes 5 working days, M 7–10 working days, L 2–3 weeks. The time runs from when I get access. Then you get the report and a 60-minute walkthrough.

Link to this question: How long does the audit take?
I have several AWS accounts. Does the audit cover them?

Yes. The package depends on the number of accounts and the size of the bill: audit S covers one account, M up to three, L more. With AWS Organizations, you create the role in the management account, where the whole bill and the Savings Plans are, and in the accounts with the resources. I prepare a StackSet or a Terraform module for it.

Link to this question: I have several AWS accounts. Does the audit cover them?
Will you sign an NDA?

Yes, before the first call: yours or mine. I do not describe your company in a case study without your consent.

Link to this question: Will you sign an NDA?
What if the audit finds no savings?

If the yearly savings identified in the report add up to less than the audit fee, I refund everything you paid. This applies to AWS bills from USD 800 net a month, and you do not have to implement anything. Full terms are on the pricing page.

Link to this question: What if the audit finds no savings?
How do you invoice?

Prices are net, in euro; the invoice is in EUR, in the amount fixed in the offer, paid by SEPA transfer. A VAT-registered business in another EU country gets it with reverse charge (EU VAT ID: PL7651699157). A business in Poland pays 23% VAT; a business outside the EU gets an invoice without Polish VAT.

Link to this question: How do you invoice?

Posts on this topic

Start with one e-mail

Tell me what you pay for AWS a month and what is growing fastest. I will reply with the package that fits and when I can start.

Or email jacob@codelevel.pl.

I reply within 1 business day.

From a case study: after the rebuild, a SaaS platform pays 30% less for AWS than on its original infrastructure. See the case study