Configure Cost and Usage reports

Cost and Usage Reports provide the most detailed information on your usage and bills. They can be configured to deliver 1 line per resource, for every hour of the day. They must be configured to enable you to access and analyze your usage and billing information.

Configure a Cost and Usage Report

If you configure multiple Cost and Usage Reports (CURs), then it is recommended to have 1 CUR per bucket. If you must have multiple CURs in a single bucket, ensure you use a different report path prefix so it is clear they are different reports.

  1. Log in to your management account as an IAM user with the required permissions, and go to the Billing console: Images/AWSCUR1.png

  2. Select Cost & Usage Reports from the left menu: Images/AWSCUR2.png

  3. Click on Create report: Images/AWSCUR3.png

  4. Enter a Report name (it can be any name), ensure you have selected Include resource IDs and Data refresh settings, then click on Next: Images/AWSCUR4.png

  5. Click on Configure: Images/AWSCURDelivery0.png

  6. Enter a unique bucket name, and ensure the region is correct, click Next: Images/AWSCURDelivery1.png

  7. Read and verify the policy, this will allow AWS to deliver billing reports to the bucket. Click on I have confirmed that this policy is correct, then click Save: Images/AWSCURDelivery3.png

  8. Verify the settings:

  • Ensure your bucket is a Valid Bucket (if not, verify the bucket policy)
  • Enter a Report path prefix (it can be any word) without any ‘/’ characters
  • Ensure the Time Granularity is Hourly
  • Report Versioning is set to Overwrite existing report
  • Under Enable report data integration for select Amazon Athena, and click Next: Images/AWSCURDelivery4.png
  1. Review the configuration, scroll to the bottom and click on Review and Complete: Images/AWSCUR6.png

You have successfully configured a Cost and Usage Report to be delivered. It may take up to 24hrs for the first report to be delivered.

There will be S3 Costs incurred to store the CUR, however the CUR is compressed to minimize costs.

Configure the CUR Bucket

We will update the CUR bucket so that the Cost Optimization linked account can access the CURs.

  1. Go to the S3 console, select the CUR Bucket, select Permissions: Images/s3cur_permissions.png

  2. Select Bucket Policy: Images/s3cur_bucketpolicy.png

  3. Add S3 read access to the Cost Optimization account by adding the following statements under the current bucket policy. Edit (Cost Optimization Member account ID) and (CUR bucket) and update the bucket policy:

         "Effect": "Allow",
         "Principal": {
             "AWS": "arn:aws:iam::(sub account ID):root"
         "Action": "s3:ListBucket",
         "Resource": "arn:aws:s3:::(CUR bucket)"
         "Effect": "Allow",
         "Principal": {
             "AWS": "arn:aws:iam::(Cost Optimization Member account ID):root"
         "Action": "s3:GetObject",
         "Resource": "arn:aws:s3:::(CUR bucket)/*"
Click here for a completed example policy

Configure re-write of the S3 object ACLs

We will setup a Lambda function to re-write the ACLs on newly delivered CUR files. This is required to allow sub accounts to read the CUR files, as they are delivered with bucket owner (management account) access only.

  1. Go to the IAM Dashboard

  2. Click on Policies, click Create policy: Images/IAMPolicy_Createpolicy.png

  3. Click on JSON, edit the following policy - replacing (bucket name) with your CUR bucket, Click Review policy:

        "Version": "2012-10-17",
        "Statement": [
                "Effect": "Allow",
                "Action": [
                "Resource": "arn:aws:s3:::(bucket name)/*"


  1. Enter a name of Lambda_S3Linked_PutACL, enter a Description and click Create policy: Images/IAM_PolicyCreate.png

  2. Click Roles, click Create role: Images/IAMRole_Create.png

  3. Click Lambda as the use case, click Next: Permissions: Images/IAM_LambdaPermissions.png

  4. Search for the Lambda_S3Linked_PutACL policy, select it and click Next: Tags: Images/IAM_PolicyTags.png

  5. Click Next: Review

  6. Enter a Role name of Lambda_Put_Linked_S3ACL, a description and click Create role: Images/IAM_RoleCreate.png

  7. Go to the Lambda Service dashboard, click Create function: Images/Lambda_home.png

  8. Select Author from scratch, enter a function name of S3LinkedPutACL, a runtime of Node.js 12.x, Execution role Use an existing role and select the Lambda_Put_Linked_S3ACL role, click Create function: Images/Lambda_functionscratch.png

  9. Paste in the following Lambda code, replace the following strings with the values of your accounts:

  • management Account Name: The owner account name - the account email without the @companyname, they will get FULL_CONTROL permissions
  • management Canonical ID: The owner canonical ID, to get the Canonical ID, refer to:
  • Linked Account Name: The cost optimization account name - the account email without the @companyname, they will get READ permissions
  • Linked Account Canonical ID: The cost optimization account canonical ID
Click here for the Lambda Code
  1. Click Save: Images/Lambda_functionsave.png

  2. Go to the S3 service dashboard, select your CUR bucket, click Properties: Images/s3cur_bucketproperties.png

  3. Select Events, click Add notification: Images/s3cur_event.png

  4. Enter a name of S3PutACL, select All object create events, Send to Lambda Function, Lambda function S3LinkedPutACL, click Save: Images/s3_event.png

  5. You will need to wait until the next CUR file is delivered by AWS (at most 24 hours). Navigate to the latest CUR file and check the permissions, it will have the original owner (AWS), your management account with full permissions (as per original), and your linked Cost Optimization account as read permissions: Images/s3_newCUR.png

Update existing CURs

If there are existing CURs from other reports that need permissions to be updated, you can use the following CLI - which will copy the objects over themselves and update the permissions as it copies.

aws s3 cp --recursive s3://(CUR bucket) s3://(CUR bucket) --grants read=id=(sub account canonical ID) full=id=(management account canonical ID) --storage-class STANDARD

Congratulations - you will now have CURs delivered and accessible by your Cost Optimization account.