Skip to main content
When running Prometheus in cloud environments (especially with auto-scaling), infrastructure is dynamic: instances are created and terminated frequently. Prometheus EC2 service discovery automates target discovery so Prometheus can always find the EC2 instances it should scrape.
A slide titled "AWS EC2" explaining that cloud infrastructure is dynamic and that EC2 Service Discovery lets Prometheus find all available EC2 instances. A simple diagram shows a bordered box with multiple server icons and an "EC2" label.

How EC2 service discovery works

Prometheus queries the EC2 Describe APIs to receive a list of available instances. For each discovered instance it exposes a rich set of metadata labels that you can use for filtering, relabeling, and target selection. To enable EC2 service discovery, add an ec2_sd_configs block to your scrape_configs in prometheus.yml. The minimal required fields are:
  • the AWS region to query,
  • AWS credentials (access key and secret key) or a secure alternative (recommended),
  • optionally filters to limit discovered instances.
Example minimal job snippet:
Prometheus exposes many metadata labels per discovered target. Example discovered labels:
Important: the default instance label (and __address__) typically use the private IP and port, because Prometheus is commonly deployed inside the same VPC. If Prometheus runs outside the VPC or cannot reach private IPs, use relabeling to change the target address to the public IP (for example set __address__ to __meta_ec2_public_ip__:9100). See the official docs for ec2_sd_config and relabel_config:
Prometheus exposes useful EC2 metadata labels for filtering and relabeling, such as __meta_ec2_tag_Name__, instance type, VPC ID, private/public IPs, and AMI IDs — use these to limit scrapes to relevant instances.

Common EC2 metadata labels

Setting up IAM credentials for Prometheus

Prometheus needs permission to call EC2 Describe APIs. Create an IAM user or role with read-only EC2 permissions. Recommended steps:
  1. Open the AWS Console: IAM → Users → Create user.
  2. Create a user for programmatic access only (no console sign-in).
  3. Attach the managed policy AmazonEC2ReadOnlyAccess or a custom scoped policy that permits the EC2 read-only actions Prometheus requires.
  4. Save the Access key ID and Secret access key — the secret is shown only once. Use secure mechanisms to provide credentials to Prometheus (see warning below).
See AWS docs: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html
A screenshot of the AWS IAM "Add user" permissions screen with "Attach existing policies directly" selected and a search filter for "ec2", showing a scrollable list of AWS-managed EC2 policies (e.g., AmazonEC2ReadOnlyAccess) with checkboxes. Navigation buttons like "Previous" and "Next: Tags" are visible at the bottom.
After creation you will see the keys once. Example success message:
Do not store long-lived AWS access keys directly in prometheus.yml in production. Prefer IAM roles (instance profiles), short-lived credentials (via STS), environment variables, or a secrets manager.
Replace the placeholders with your AWS region and preferred credential configuration. For production, prefer IAM roles or environment-based credentials instead of embedding keys in the YAML.
After updating prometheus.yml, restart Prometheus:
Then verify discovery in the Prometheus UI:
  • Status → Service Discovery: confirm EC2 is listed and shows the number of discovered targets.
  • Status → Targets: inspect each discovered target, its labels, and scrape status.
If a target is DOWN, check:
  • Network connectivity (security groups, VPC routing, NAT/Gateway),
  • Whether Prometheus can reach the instance private IP (or switch to public IP via relabeling),
  • That the node exporter or other exporter is running on the expected port.
As EC2 instances scale up and down, Prometheus will refresh discovered targets automatically, keeping your monitoring accurate in dynamic AWS environments.

Additional references

Watch Video