Export AWS quotas and usage on Prometheus.
A subset of the aws service quotas are labelled adjustable. This can be at the account or region level. If some of the quotas are adjusted for some regions, then the quotas per region would no longer be homogeneous. This would cause a rift when creating monitoring or alerting logic in prometheus based on the service quotas.
The aim of the aws_quota_exporter is to export these quotas in prometheus to solve the above problem. At the time of writing, this feature is not currently available in the prometheus yace exporter
go run . --prom.port=10100 --config.file=config.yml
config.ymljobs:
- serviceCode: lambda
accountName: dev-account # optional
regions:
- us-west-1
- us-east-1
role: arn:aws:iam::ACCOUNT-ID:role/rolename # optional
- serviceCode: cloudformation
accountName: prod-account # optional
regions:
- us-west-1
- us-east-1
withUsageOnly: true # optional, collect only quotas with Usage defined
role key if you want the exporter to assume the role when retrieving that specific job metrics$ ./aws_quota_exporter -h
Usage of ./aws_quota_exporter:
-cache.duration duration
Cache expiry time. (default 5m0s)
-cache.serve-stale
Serve stale cache data during cache refresh. This avoids delays in serving metrics. (default: false)
-collect.usage
Collect quotas usage where available (NOTE: CloudWatch calls aren't free, default: false)
-config.file string
Path to configuration file. (default "/etc/aqe/config.yml")
-log.folder string
Folder to store logfiles. logs to stdout if not specified. (default "stdout")
-log.format string
Format of log messages (text or json). (default "text")
-log.level string
Log level to log from (DEBUG|INFO|WARN|ERROR). (default "INFO")
-prom.port int
Port to expose prometheus metrics. (default 10100)
-version
Display aqe version
$ ./aws_quota_exporter -version
{
App: "AWS Quota Exporter (AQE)",
Version: "dev",
Date: "Sun Sep 3 17:54:45 UTC 2023",
Platform: "darwin/arm64",
Commit: "none",
GoVersion: "go1.21.13"
}
The serviceCode is the AWS service identifier. To identify the serviceCode for a particular service, use the following aws cli command:
aws service-quotas list-services
You can enable quota usage collection with -collect.usage flag (ℹ️ Not all quotas have usage. see docs). The latest usage value from CloudWatch using GetMetricStatistics API method is collected. ⚠️ CloudWatch API calls aren't free! However, there are no charges to use GetMetricStatistics for up to 1 million API requests (docs).
The label type="usage|quota is used to differentiate the metrics. This "type": "usage" will export usage metrics while "type": "quota" will export quota metrics.
Example promQL query to get quota usage ratio:
{job="quota-exporter", type="usage"} / {job="quota-exporter", type="quota"}
NOTE: It requires cloudwatch:GetMetricStatistics permission in IAM policy.
Using the docker image avaliable on dockerhub
docker run --name my-aqe -d -p 10100:10100 -e AWS_ACCESS_KEY=111222 -e AWS_SECRET_KEY=secret ugwuanyi/aqe:main
This program relies on the AWS SDK for Go V2 for handling authentication.
The AWS SDK uses its default credential chain to find AWS credentials. This default credential chain looks for credentials in the following order:
Environment variables
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)(AWS_WEB_IDENTITY_TOKEN_FILE)Shared configuration files
credentials file and config file under .aws folder that is placed in the home folder on the host.IAM role for tasks.
IAM role for Amazon EC2.
By default, the SDK checks the AWS_PROFILE environment variable to determine which profile to use. If no AWS_PROFILE variable is set, the SDK uses the default profile.
To set profile to use:
$ AWS_PROFILE=test_profile
Steps to use the helm chart
helm repo add aws_quota_exporter https://emylincon.github.io/aws_quota_exporter
helm show values aws_quota_exporter/aqe
secret:
# base64 encoded secrets
AWS_ACCESS_KEY_ID: QVdTX0FDQ0VTU19LRVlfSUQK
AWS_SECRET_ACCESS_KEY: QVdTX1NFQ1JFVF9BQ0NFU1NfS0VZCg==
kubectl create namespace aqe
helm install -n aqe -f values.test aqe aws_quota_exporter/aqe
helm list -A
helm uninstall -n aqe aqe
The exporter requires the AWS managed policy ServiceQuotasReadOnlyAccess. This also depends on the jobs specified in the config.yml file, as all of the permissions are probably not required. The permissions included in ServiceQuotasReadOnlyAccess are as follows in policy document:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAccountLimits",
"cloudformation:DescribeAccountLimits",
"cloudwatch:DescribeAlarmsForMetric",
"cloudwatch:DescribeAlarms",
"cloudwatch:GetMetricData",
"cloudwatch:GetMetricStatistics",
"dynamodb:DescribeLimits",
"elasticloadbalancing:DescribeAccountLimits",
"iam:GetAccountSummary",
"kinesis:DescribeLimits",
"organizations:DescribeAccount",
"organizations:DescribeOrganization",
"organizations:ListAWSServiceAccessForOrganization",
"rds:DescribeAccountAttributes",
"route53:GetAccountLimit",
"tag:GetTagKeys",
"tag:GetTagValues",
"servicequotas:GetAssociationForServiceQuotaTemplate",
"servicequotas:GetAWSDefaultServiceQuota",
"servicequotas:GetRequestedServiceQuotaChange",
"servicequotas:GetServiceQuota",
"servicequotas:GetServiceQuotaIncreaseRequestFromTemplate",
"servicequotas:ListAWSDefaultServiceQuotas",
"servicequotas:ListRequestedServiceQuotaChangeHistory",
"servicequotas:ListRequestedServiceQuotaChangeHistoryByQuota",
"servicequotas:ListServices",
"servicequotas:ListServiceQuotas",
"servicequotas:ListServiceQuotaIncreaseRequestsInTemplate",
"servicequotas:ListTagsForResource"
],
"Resource": "*"
}
]
}
Please Remove permissions that you would not use
Visualizing Quotas & Usage

applied quota values for the specified AWS service. For some quotas, only the default values are available. If the applied quota value is not available for a quota, the quota is not retrieveddefault values for the quotas for the specified AWS service. A default value does not reflect any quota increases.Go Template
48.2%
Go
44.3%
Mustache
7.0%
Export AWS quotas and usage on Prometheus.
A subset of the aws service quotas are labelled adjustable. This can be at the account or region level. If some of the quotas are adjusted for some regions, then the quotas per region would no longer be homogeneous. This would cause a rift when creating monitoring or alerting logic in prometheus based on the service quotas.
The aim of the aws_quota_exporter is to export these quotas in prometheus to solve the above problem. At the time of writing, this feature is not currently available in the prometheus yace exporter
go run . --prom.port=10100 --config.file=config.yml
config.ymljobs:
- serviceCode: lambda
accountName: dev-account # optional
regions:
- us-west-1
- us-east-1
role: arn:aws:iam::ACCOUNT-ID:role/rolename # optional
- serviceCode: cloudformation
accountName: prod-account # optional
regions:
- us-west-1
- us-east-1
withUsageOnly: true # optional, collect only quotas with Usage defined
role key if you want the exporter to assume the role when retrieving that specific job metrics$ ./aws_quota_exporter -h
Usage of ./aws_quota_exporter:
-cache.duration duration
Cache expiry time. (default 5m0s)
-cache.serve-stale
Serve stale cache data during cache refresh. This avoids delays in serving metrics. (default: false)
-collect.usage
Collect quotas usage where available (NOTE: CloudWatch calls aren't free, default: false)
-config.file string
Path to configuration file. (default "/etc/aqe/config.yml")
-log.folder string
Folder to store logfiles. logs to stdout if not specified. (default "stdout")
-log.format string
Format of log messages (text or json). (default "text")
-log.level string
Log level to log from (DEBUG|INFO|WARN|ERROR). (default "INFO")
-prom.port int
Port to expose prometheus metrics. (default 10100)
-version
Display aqe version
$ ./aws_quota_exporter -version
{
App: "AWS Quota Exporter (AQE)",
Version: "dev",
Date: "Sun Sep 3 17:54:45 UTC 2023",
Platform: "darwin/arm64",
Commit: "none",
GoVersion: "go1.21.13"
}
The serviceCode is the AWS service identifier. To identify the serviceCode for a particular service, use the following aws cli command:
aws service-quotas list-services
You can enable quota usage collection with -collect.usage flag (ℹ️ Not all quotas have usage. see docs). The latest usage value from CloudWatch using GetMetricStatistics API method is collected. ⚠️ CloudWatch API calls aren't free! However, there are no charges to use GetMetricStatistics for up to 1 million API requests (docs).
The label type="usage|quota is used to differentiate the metrics. This "type": "usage" will export usage metrics while "type": "quota" will export quota metrics.
Example promQL query to get quota usage ratio:
{job="quota-exporter", type="usage"} / {job="quota-exporter", type="quota"}
NOTE: It requires cloudwatch:GetMetricStatistics permission in IAM policy.
Using the docker image avaliable on dockerhub
docker run --name my-aqe -d -p 10100:10100 -e AWS_ACCESS_KEY=111222 -e AWS_SECRET_KEY=secret ugwuanyi/aqe:main
This program relies on the AWS SDK for Go V2 for handling authentication.
The AWS SDK uses its default credential chain to find AWS credentials. This default credential chain looks for credentials in the following order:
Environment variables
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)(AWS_WEB_IDENTITY_TOKEN_FILE)Shared configuration files
credentials file and config file under .aws folder that is placed in the home folder on the host.IAM role for tasks.
IAM role for Amazon EC2.
By default, the SDK checks the AWS_PROFILE environment variable to determine which profile to use. If no AWS_PROFILE variable is set, the SDK uses the default profile.
To set profile to use:
$ AWS_PROFILE=test_profile
Steps to use the helm chart
helm repo add aws_quota_exporter https://emylincon.github.io/aws_quota_exporter
helm show values aws_quota_exporter/aqe
secret:
# base64 encoded secrets
AWS_ACCESS_KEY_ID: QVdTX0FDQ0VTU19LRVlfSUQK
AWS_SECRET_ACCESS_KEY: QVdTX1NFQ1JFVF9BQ0NFU1NfS0VZCg==
kubectl create namespace aqe
helm install -n aqe -f values.test aqe aws_quota_exporter/aqe
helm list -A
helm uninstall -n aqe aqe
The exporter requires the AWS managed policy ServiceQuotasReadOnlyAccess. This also depends on the jobs specified in the config.yml file, as all of the permissions are probably not required. The permissions included in ServiceQuotasReadOnlyAccess are as follows in policy document:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAccountLimits",
"cloudformation:DescribeAccountLimits",
"cloudwatch:DescribeAlarmsForMetric",
"cloudwatch:DescribeAlarms",
"cloudwatch:GetMetricData",
"cloudwatch:GetMetricStatistics",
"dynamodb:DescribeLimits",
"elasticloadbalancing:DescribeAccountLimits",
"iam:GetAccountSummary",
"kinesis:DescribeLimits",
"organizations:DescribeAccount",
"organizations:DescribeOrganization",
"organizations:ListAWSServiceAccessForOrganization",
"rds:DescribeAccountAttributes",
"route53:GetAccountLimit",
"tag:GetTagKeys",
"tag:GetTagValues",
"servicequotas:GetAssociationForServiceQuotaTemplate",
"servicequotas:GetAWSDefaultServiceQuota",
"servicequotas:GetRequestedServiceQuotaChange",
"servicequotas:GetServiceQuota",
"servicequotas:GetServiceQuotaIncreaseRequestFromTemplate",
"servicequotas:ListAWSDefaultServiceQuotas",
"servicequotas:ListRequestedServiceQuotaChangeHistory",
"servicequotas:ListRequestedServiceQuotaChangeHistoryByQuota",
"servicequotas:ListServices",
"servicequotas:ListServiceQuotas",
"servicequotas:ListServiceQuotaIncreaseRequestsInTemplate",
"servicequotas:ListTagsForResource"
],
"Resource": "*"
}
]
}
Please Remove permissions that you would not use
Visualizing Quotas & Usage

applied quota values for the specified AWS service. For some quotas, only the default values are available. If the applied quota value is not available for a quota, the quota is not retrieveddefault values for the quotas for the specified AWS service. A default value does not reflect any quota increases.Go Template
48.2%
Go
44.3%
Mustache
7.0%