{"id":23698283,"url":"https://github.com/nuuday/terraform-aws-cur","last_synced_at":"2025-10-10T02:02:12.666Z","repository":{"id":41699899,"uuid":"360822350","full_name":"nuuday/terraform-aws-cur","owner":"nuuday","description":"Terraform module for creating Cost and Usage Reports complete with Glue and Athena to make CUR data available to e.g. QuickSight.","archived":false,"fork":false,"pushed_at":"2023-10-17T12:48:39.000Z","size":39,"stargazers_count":21,"open_issues_count":0,"forks_count":16,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-09-03T01:37:04.716Z","etag":null,"topics":["athena","aws","cost-usage-reports","cur","glue","quicksight"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nuuday.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-04-23T08:54:31.000Z","updated_at":"2025-08-25T16:58:18.000Z","dependencies_parsed_at":"2025-09-03T01:32:29.672Z","dependency_job_id":"92ff760b-e55f-452a-9c50-b644449a63d9","html_url":"https://github.com/nuuday/terraform-aws-cur","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/nuuday/terraform-aws-cur","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuuday%2Fterraform-aws-cur","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuuday%2Fterraform-aws-cur/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuuday%2Fterraform-aws-cur/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuuday%2Fterraform-aws-cur/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nuuday","download_url":"https://codeload.github.com/nuuday/terraform-aws-cur/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuuday%2Fterraform-aws-cur/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002492,"owners_count":26083397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["athena","aws","cost-usage-reports","cur","glue","quicksight"],"created_at":"2024-12-30T07:15:32.344Z","updated_at":"2025-10-10T02:02:12.643Z","avatar_url":"https://github.com/nuuday.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AWS Cost \u0026 Usage Reports\n\nThis Terraform module stands up a Cost and Usage Report, together with necessary services making the CUR data queryable in Athena.\n\n## Overview\n\nThe overall architecture looks like the illustration below\n![AWS Cost and Usage Reports overview](./assets/overview.png)\n\n1. AWS delivers Cost and Usage Reports data to the S3 bucket continuously\n2. Whenever new CUR data is delivered, a Glue Crawler makes sure the newly available CUR data is processed and made available in the Data Catalog\n3. Athena provides an SQL interface to the CUR data, using the Data Catalog as its data source\n4. QuickSight visualizes the data returned from querying Athena\n\n\u003c!--- BEGIN_TF_DOCS ---\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 0.13, \u003c 2.0 |\n| \u003ca name=\"requirement_archive\"\u003e\u003c/a\u003e [archive](#requirement\\_archive) | ~\u003e 2.0 |\n| \u003ca name=\"requirement_aws\"\u003e\u003c/a\u003e [aws](#requirement\\_aws) | ~\u003e 3.29 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_aws.cur\"\u003e\u003c/a\u003e [aws.cur](#provider\\_aws.cur) | ~\u003e 3.29 |\n| \u003ca name=\"provider_archive\"\u003e\u003c/a\u003e [archive](#provider\\_archive) | ~\u003e 2.0 |\n| \u003ca name=\"provider_aws\"\u003e\u003c/a\u003e [aws](#provider\\_aws) | ~\u003e 3.29 |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_use_existing_s3_bucket\"\u003e\u003c/a\u003e [use\\_existing\\_s3\\_bucket](#input\\_use\\_existing\\_s3\\_bucket) | Whether to use an existing S3 bucket or create a new one. Regardless, `s3_bucket_name` must contain the name of the bucket. | `bool` | n/a | yes |\n| \u003ca name=\"input_s3_bucket_name\"\u003e\u003c/a\u003e [s3\\_bucket\\_name](#input\\_s3\\_bucket\\_name) | Name of the S3 bucket into which CUR will put the cost data. | `string` | n/a | yes |\n| \u003ca name=\"input_s3_use_existing_kms_key\"\u003e\u003c/a\u003e [s3\\_use\\_existing\\_kms\\_key](#input\\_s3\\_use\\_existing\\_kms\\_key) | Whether to use an existing KMS CMK for S3 SSE. | `bool` | n/a | yes |\n| \u003ca name=\"input_s3_kms_key_alias\"\u003e\u003c/a\u003e [s3\\_kms\\_key\\_alias](#input\\_s3\\_kms\\_key\\_alias) | Alias for the KMS CMK, existing or otherwise. | `string` | `\"\"` | no |\n| \u003ca name=\"input_report_name\"\u003e\u003c/a\u003e [report\\_name](#input\\_report\\_name) | Name of the Cost and Usage Report which will be created. | `string` | n/a | yes |\n| \u003ca name=\"input_report_frequency\"\u003e\u003c/a\u003e [report\\_frequency](#input\\_report\\_frequency) | How often the Cost and Usage Report will be generated. HOURLY or DAILY. | `string` | n/a | yes |\n| \u003ca name=\"input_report_versioning\"\u003e\u003c/a\u003e [report\\_versioning](#input\\_report\\_versioning) | Whether reports should be overwritten or new ones should be created. | `string` | n/a | yes |\n| \u003ca name=\"input_report_format\"\u003e\u003c/a\u003e [report\\_format](#input\\_report\\_format) | Format for report. Valid values are: textORcsv, Parquet. If Parquet is used, then Compression must also be Parquet. | `string` | n/a | yes |\n| \u003ca name=\"input_report_compression\"\u003e\u003c/a\u003e [report\\_compression](#input\\_report\\_compression) | Compression format for report. Valid values are: GZIP, ZIP, Parquet. If Parquet is used, then format must also be Parquet. | `string` | n/a | yes |\n| \u003ca name=\"input_report_additional_artifacts\"\u003e\u003c/a\u003e [report\\_additional\\_artifacts](#input\\_report\\_additional\\_artifacts) | A list of additional artifacts. Valid values are: REDSHIFT, QUICKSIGHT, ATHENA. When ATHENA exists within additional\\_artifacts, no other artifact type can be declared and report\\_versioning must be OVERWRITE\\_REPORT. | `set(string)` | n/a | yes |\n| \u003ca name=\"input_s3_bucket_prefix\"\u003e\u003c/a\u003e [s3\\_bucket\\_prefix](#input\\_s3\\_bucket\\_prefix) | Prefix in the S3 bucket to put reports. | `string` | `\"\"` | no |\n| \u003ca name=\"input_cur_role_arn\"\u003e\u003c/a\u003e [cur\\_role\\_arn](#input\\_cur\\_role\\_arn) | ARN of the role to assume in order to provision the Cost and Usage Reports S3 bucket in us-east-1. | `string` | `\"\"` | no |\n| \u003ca name=\"input_cur_role_session_name\"\u003e\u003c/a\u003e [cur\\_role\\_session\\_name](#input\\_cur\\_role\\_session\\_name) | Session name to use when assuming `cur_role_arn`. | `string` | `\"\"` | no |\n| \u003ca name=\"input_lambda_log_group_retention_days\"\u003e\u003c/a\u003e [lambda\\_log\\_group\\_retention\\_days](#input\\_lambda\\_log\\_group\\_retention\\_days) | Number of days to retain logs from the Lambda function, which ensures Glue Crawler runs when new CUR data is available. | `number` | `14` | no |\n| \u003ca name=\"input_glue_crawler_create_log_group\"\u003e\u003c/a\u003e [glue\\_crawler\\_create\\_log\\_group](#input\\_glue\\_crawler\\_create\\_log\\_group) | Whether to create a CloudWatch Log Group for the Glue Crawler. Crawlers share Log Group, and this gives the option of managing the Log Group with retention through this module. | `bool` | `true` | no |\n| \u003ca name=\"input_glue_crawler_log_group_retention_days\"\u003e\u003c/a\u003e [glue\\_crawler\\_log\\_group\\_retention\\_days](#input\\_glue\\_crawler\\_log\\_group\\_retention\\_days) | Number of days to retain logs from the Glue Crawler, which populates the Athena table whenever new CUR data is available. | `number` | `14` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | Tags which will be applied to provisioned resources. | `map(string)` | `{}` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_s3_bucket_name\"\u003e\u003c/a\u003e [s3\\_bucket\\_name](#output\\_s3\\_bucket\\_name) | Name of S3 bucket used for storing CUR data. This may be provisioned by this module or not. |\n| \u003ca name=\"output_s3_bucket_prefix\"\u003e\u003c/a\u003e [s3\\_bucket\\_prefix](#output\\_s3\\_bucket\\_prefix) | Prefix used for storing CUR data inside the S3 bucket. |\n| \u003ca name=\"output_s3_bucket_arn\"\u003e\u003c/a\u003e [s3\\_bucket\\_arn](#output\\_s3\\_bucket\\_arn) | ARN of S3 bucket used for storing CUR data. This may be provisioned by this module or not. |\n| \u003ca name=\"output_s3_bucket_region\"\u003e\u003c/a\u003e [s3\\_bucket\\_region](#output\\_s3\\_bucket\\_region) | Region where the S3 bucket used for storing CUR data is provisioned. This may be provisioned by this module or not. |\n| \u003ca name=\"output_report_name\"\u003e\u003c/a\u003e [report\\_name](#output\\_report\\_name) | Name of the provisioned Cost and Usage Report. |\n| \u003ca name=\"output_lambda_crawler_trigger_arn\"\u003e\u003c/a\u003e [lambda\\_crawler\\_trigger\\_arn](#output\\_lambda\\_crawler\\_trigger\\_arn) | ARN of the Lambda function responsible for triggering the Glue Crawler when new CUR data is uploaded into the S3 bucket. |\n| \u003ca name=\"output_lambda_crawler_trigger_role_arn\"\u003e\u003c/a\u003e [lambda\\_crawler\\_trigger\\_role\\_arn](#output\\_lambda\\_crawler\\_trigger\\_role\\_arn) | ARN of the IAM role used by the Lambda function responsible for starting the Glue Crawler. |\n| \u003ca name=\"output_crawler_arn\"\u003e\u003c/a\u003e [crawler\\_arn](#output\\_crawler\\_arn) | ARN of the Glue Crawler responsible for populating the Catalog Database with new CUR data. |\n| \u003ca name=\"output_crawler_role_arn\"\u003e\u003c/a\u003e [crawler\\_role\\_arn](#output\\_crawler\\_role\\_arn) | ARN of the IAM role used by the Glue Crawler responsible for populating the Catalog Database with new CUR data. |\n| \u003ca name=\"output_glue_catalog_database_name\"\u003e\u003c/a\u003e [glue\\_catalog\\_database\\_name](#output\\_glue\\_catalog\\_database\\_name) | Name of the Glue Catalog Database which is populated with CUR data. |\n\n\u003c!--- END_TF_DOCS ---\u003e\n\n## References\n\nIt is based on [AWS: Query and Visualize AWS Cost and Usage](https://aws.amazon.com/blogs/big-data/query-and-visualize-aws-cost-and-usage-data-using-amazon-athena-and-amazon-quicksight/).\nCheck out the blog post and the linked resources for an explanation of the concepts.\n\nFor more information about Cost \u0026 Usage Reports in general, see [AWS: What are Cost and Usage Reports?](https://docs.aws.amazon.com/cur/latest/userguide/what-is-cur.html)\n\n\u003c!-- BEGIN_TF_DOCS --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 0.13, \u003c 2.0 |\n| \u003ca name=\"requirement_archive\"\u003e\u003c/a\u003e [archive](#requirement\\_archive) | ~\u003e 2.0 |\n| \u003ca name=\"requirement_aws\"\u003e\u003c/a\u003e [aws](#requirement\\_aws) | ~\u003e 3.29 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_aws.cur\"\u003e\u003c/a\u003e [aws.cur](#provider\\_aws.cur) | ~\u003e 3.29 |\n| \u003ca name=\"provider_aws\"\u003e\u003c/a\u003e [aws](#provider\\_aws) | ~\u003e 3.29 |\n| \u003ca name=\"provider_archive\"\u003e\u003c/a\u003e [archive](#provider\\_archive) | ~\u003e 2.0 |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_use_existing_s3_bucket\"\u003e\u003c/a\u003e [use\\_existing\\_s3\\_bucket](#input\\_use\\_existing\\_s3\\_bucket) | Whether to use an existing S3 bucket or create a new one. Regardless, `s3_bucket_name` must contain the name of the bucket. | `bool` | n/a | yes |\n| \u003ca name=\"input_s3_bucket_name\"\u003e\u003c/a\u003e [s3\\_bucket\\_name](#input\\_s3\\_bucket\\_name) | Name of the S3 bucket into which CUR will put the cost data. | `string` | n/a | yes |\n| \u003ca name=\"input_s3_use_existing_kms_key\"\u003e\u003c/a\u003e [s3\\_use\\_existing\\_kms\\_key](#input\\_s3\\_use\\_existing\\_kms\\_key) | Whether to use an existing KMS CMK for S3 SSE. | `bool` | n/a | yes |\n| \u003ca name=\"input_s3_kms_key_alias\"\u003e\u003c/a\u003e [s3\\_kms\\_key\\_alias](#input\\_s3\\_kms\\_key\\_alias) | Alias for the KMS CMK, existing or otherwise. | `string` | `\"\"` | no |\n| \u003ca name=\"input_report_name\"\u003e\u003c/a\u003e [report\\_name](#input\\_report\\_name) | Name of the Cost and Usage Report which will be created. | `string` | n/a | yes |\n| \u003ca name=\"input_report_frequency\"\u003e\u003c/a\u003e [report\\_frequency](#input\\_report\\_frequency) | How often the Cost and Usage Report will be generated. HOURLY or DAILY. | `string` | n/a | yes |\n| \u003ca name=\"input_report_versioning\"\u003e\u003c/a\u003e [report\\_versioning](#input\\_report\\_versioning) | Whether reports should be overwritten or new ones should be created. | `string` | n/a | yes |\n| \u003ca name=\"input_report_format\"\u003e\u003c/a\u003e [report\\_format](#input\\_report\\_format) | Format for report. Valid values are: textORcsv, Parquet. If Parquet is used, then Compression must also be Parquet. | `string` | n/a | yes |\n| \u003ca name=\"input_report_compression\"\u003e\u003c/a\u003e [report\\_compression](#input\\_report\\_compression) | Compression format for report. Valid values are: GZIP, ZIP, Parquet. If Parquet is used, then format must also be Parquet. | `string` | n/a | yes |\n| \u003ca name=\"input_report_additional_artifacts\"\u003e\u003c/a\u003e [report\\_additional\\_artifacts](#input\\_report\\_additional\\_artifacts) | A list of additional artifacts. Valid values are: REDSHIFT, QUICKSIGHT, ATHENA. When ATHENA exists within additional\\_artifacts, no other artifact type can be declared and report\\_versioning must be OVERWRITE\\_REPORT. | `set(string)` | n/a | yes |\n| \u003ca name=\"input_s3_bucket_prefix\"\u003e\u003c/a\u003e [s3\\_bucket\\_prefix](#input\\_s3\\_bucket\\_prefix) | Prefix in the S3 bucket to put reports. | `string` | `\"\"` | no |\n| \u003ca name=\"input_cur_role_arn\"\u003e\u003c/a\u003e [cur\\_role\\_arn](#input\\_cur\\_role\\_arn) | ARN of the role to assume in order to provision the Cost and Usage Reports S3 bucket in us-east-1. | `string` | `\"\"` | no |\n| \u003ca name=\"input_cur_role_session_name\"\u003e\u003c/a\u003e [cur\\_role\\_session\\_name](#input\\_cur\\_role\\_session\\_name) | Session name to use when assuming `cur_role_arn`. | `string` | `null` | no |\n| \u003ca name=\"input_lambda_log_group_retention_days\"\u003e\u003c/a\u003e [lambda\\_log\\_group\\_retention\\_days](#input\\_lambda\\_log\\_group\\_retention\\_days) | Number of days to retain logs from the Lambda function, which ensures Glue Crawler runs when new CUR data is available. | `number` | `14` | no |\n| \u003ca name=\"input_glue_crawler_create_log_group\"\u003e\u003c/a\u003e [glue\\_crawler\\_create\\_log\\_group](#input\\_glue\\_crawler\\_create\\_log\\_group) | Whether to create a CloudWatch Log Group for the Glue Crawler. Crawlers share Log Group, and this gives the option of managing the Log Group with retention through this module. | `bool` | `true` | no |\n| \u003ca name=\"input_glue_crawler_log_group_retention_days\"\u003e\u003c/a\u003e [glue\\_crawler\\_log\\_group\\_retention\\_days](#input\\_glue\\_crawler\\_log\\_group\\_retention\\_days) | Number of days to retain logs from the Glue Crawler, which populates the Athena table whenever new CUR data is available. | `number` | `14` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | Tags which will be applied to provisioned resources. | `map(string)` | `{}` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_s3_bucket_name\"\u003e\u003c/a\u003e [s3\\_bucket\\_name](#output\\_s3\\_bucket\\_name) | Name of S3 bucket used for storing CUR data. This may be provisioned by this module or not. |\n| \u003ca name=\"output_s3_bucket_prefix\"\u003e\u003c/a\u003e [s3\\_bucket\\_prefix](#output\\_s3\\_bucket\\_prefix) | Prefix used for storing CUR data inside the S3 bucket. |\n| \u003ca name=\"output_s3_bucket_arn\"\u003e\u003c/a\u003e [s3\\_bucket\\_arn](#output\\_s3\\_bucket\\_arn) | ARN of S3 bucket used for storing CUR data. This may be provisioned by this module or not. |\n| \u003ca name=\"output_s3_bucket_region\"\u003e\u003c/a\u003e [s3\\_bucket\\_region](#output\\_s3\\_bucket\\_region) | Region where the S3 bucket used for storing CUR data is provisioned. This may be provisioned by this module or not. |\n| \u003ca name=\"output_report_name\"\u003e\u003c/a\u003e [report\\_name](#output\\_report\\_name) | Name of the provisioned Cost and Usage Report. |\n| \u003ca name=\"output_lambda_crawler_trigger_arn\"\u003e\u003c/a\u003e [lambda\\_crawler\\_trigger\\_arn](#output\\_lambda\\_crawler\\_trigger\\_arn) | ARN of the Lambda function responsible for triggering the Glue Crawler when new CUR data is uploaded into the S3 bucket. |\n| \u003ca name=\"output_lambda_crawler_trigger_role_arn\"\u003e\u003c/a\u003e [lambda\\_crawler\\_trigger\\_role\\_arn](#output\\_lambda\\_crawler\\_trigger\\_role\\_arn) | ARN of the IAM role used by the Lambda function responsible for starting the Glue Crawler. |\n| \u003ca name=\"output_crawler_arn\"\u003e\u003c/a\u003e [crawler\\_arn](#output\\_crawler\\_arn) | ARN of the Glue Crawler responsible for populating the Catalog Database with new CUR data. |\n| \u003ca name=\"output_crawler_role_arn\"\u003e\u003c/a\u003e [crawler\\_role\\_arn](#output\\_crawler\\_role\\_arn) | ARN of the IAM role used by the Glue Crawler responsible for populating the Catalog Database with new CUR data. |\n| \u003ca name=\"output_glue_catalog_database_name\"\u003e\u003c/a\u003e [glue\\_catalog\\_database\\_name](#output\\_glue\\_catalog\\_database\\_name) | Name of the Glue Catalog Database which is populated with CUR data. |\n\u003c!-- END_TF_DOCS --\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuuday%2Fterraform-aws-cur","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnuuday%2Fterraform-aws-cur","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuuday%2Fterraform-aws-cur/lists"}