Database Discovery: Find and Monitor RDS, Cloud SQL, AlloyDB, and Spanner Instances
Database discovery lets the Atlas Agent find database instances in your cloud account and register them for schema monitoring, so you don't have to define a connection for each instance by hand. The agent runs inside your network and uses its own cloud credentials, so Atlas Cloud never needs access to your cloud account or databases.
There are two ways to run discovery:
| Method | Supported databases | Best for |
|---|---|---|
| Atlas Cloud UI | Amazon RDS | A one-time setup from the browser |
| Agent configuration (RDS, GCP) | Amazon RDS, Cloud SQL, AlloyDB, Spanner | Configuration as code, filtering, and re-discovery on every agent start |
Discover Databases from Atlas Cloud
- An Atlas Cloud account. Run
atlas loginto sign in or create one. - An environment where you can run the agent container (Docker, Kubernetes, ECS) with network access to your RDS instances.
- AWS credentials available to the agent with permission to list RDS instances
(
rds:DescribeDBInstances). On Kubernetes, grant this through the agent's service account.
-
Click the + in the top-right corner of Atlas Cloud and select Setup Monitoring.

-
Select Atlas Agent, then either create a new agent or click Use Existing Agent to reuse an agent that is already connected.
When you create an agent, Atlas generates a token for it. The token is shown only once, so copy it and store it securely. Run the rendered
docker runcommand to start the agent. When the agent connects, the Check connection step turns green.
-
Under Next steps, find the Discover databases panel and set the optional fields:
- Add Role: IAM role ARNs the agent assumes to list instances in other AWS accounts. See Cross-Account Discovery.
- IAM user name for database connection: the database user for instances that use IAM authentication. If empty, Atlas uses the instance's master user.
Click Discover. The agent lists the RDS instances its credentials can access. This takes a few seconds, depending on the number of instances.
-
In the Choose Databases to Configure dialog, select the instances to monitor. Each entry shows the instance endpoint and the user Atlas connects with. Unselected instances are discarded. Click Configure N Databases.

-
The selected instances appear under Monitoring > Instances, assigned to your agent.

Instances that use IAM database authentication with the displayed user need no further configuration.
For instances that require a password, or use IAM authentication with a different user, click edit on the right side of the instance entry. In the Edit Instance Authentication dialog, set the username and choose a credentials source (see Security and Credentials). Click Check Connection to verify, then Save Changes.

Cross-Account Discovery
To discover RDS instances in an AWS account other than the one the agent runs in, give the agent an IAM role to assume in the target account:
-
In the target account (where the RDS instances are), create an IAM role with a policy that allows
rds:DescribeDBInstances. Add a trust policy that allows the agent's IAM role or user to assume it. -
In the source account (where the agent runs), allow the agent's IAM role or user to call
sts:AssumeRoleon the role from step 1. -
In the Discover databases panel, click Add Role and enter the ARN of the target account role. Add one ARN per account.

-
Click Discover and continue from step 4 above.
When you add roles, the agent lists instances only through those roles and does not use its default
credentials. To include instances from the agent's own account, add a role ARN for that account too.
The same rule applies to the roles attribute in RDS Discovery.
RDS Discovery
Automatically discover RDS instances using the rds_discovery data source and create instance blocks for
each discovered instance.
How RDS Discovery Works
The rds_discovery data source supports two modes of operation:
-
Default credentials mode: If no
rolesare provided, the agent uses the default AWS credentials (from the environment, IAM role, or credentials file) to discover instances in the current AWS account. -
Role-based discovery: If
rolesare provided, the agent only uses those roles to discover instances. It will not use default credentials. This allows you to discover instances across multiple AWS accounts by assuming different IAM roles.
If you need to discover instances in both the current account and other accounts, you have two options:
-
Use multiple data blocks: Create separate
rds_discoveryblocks—one without roles (for current account) and one with roles (for other accounts). -
Include a role for the current account: Add an IAM role ARN for the current account to the
roleslist along with roles for other accounts.
Filtering Discovered Instances
The rds_discovery data source supports filtering to narrow down which instances are discovered:
tags: Filter instances by AWS resource tags. You can specify tag keys with specific values, or usenullto match any instance that has the tag key (regardless of value).name_regex: Filter instances by name using a regular expression pattern.exclude_tags: Exclude instances that have specific tags. You can specify tag keys with specific values, or usenullto exclude any instance that has the tag key (regardless of value).
Filters are applied together (AND logic), so an instance must match all specified filters to be included in the results.
data "rds_discovery" "production" {
region = "us-east-1"
filter {
# Match instances with specific tag values
tags = {
Environment = "production"
Team = "backend"
}
# Exclude instances with specific tags (regardless of value)
exclude_tags = {
Deprecated = null # Exclude instances that have the "Deprecated" tag
}
# Match instances whose name ends with "-prod"
name_regex = ".*-prod$"
}
}
Example: Discovering Instances in Current Account
# Discover instances using default credentials (current account)
data "rds_discovery" "current_account" {
region = "us-east-1"
# No roles specified - uses default credentials
filter {
tags = {
Environment = "production"
}
}
}
Example: Discovering Instances Across Multiple Accounts
# Discover instances in multiple accounts using IAM roles
data "rds_discovery" "production" {
region = "us-east-1"
roles = [
"arn:aws:iam::123456789012:role/AtlasRDSRole", # Account 1
"arn:aws:iam::987654321098:role/AtlasRDSRole", # Account 2
]
filter {
tags = {
Environment = "production"
}
name_regex = ".*-prod$"
}
}
# Create an instance block for each discovered RDS instance
instance {
for_each = toset(data.rds_discovery.production.instances)
name = each.value.identifier
driver = each.value.driver
tags = each.value.tags
metadata = each.value.metadata
connection {
host = each.value.address
port = each.value.port
user = each.value.master_user
database = each.value.initial_database
auth {
aws_iam {
endpoint = each.value.address
region = "us-east-1"
# assume_role is optional - only include if the instance was discovered using a role
assume_role = each.value.assume_role
}
}
}
default_monitor "all" {
snapshot_interval = "1h"
statistics {
enabled = true
}
}
}
Example: Discovering in Current Account and Other Accounts
# Discover instances in current account using default credentials
data "rds_discovery" "current_account" {
region = "us-east-1"
# No roles - uses default credentials
filter {
tags = {
Environment = "production"
}
}
}
# Discover instances in other accounts using roles
data "rds_discovery" "other_accounts" {
region = "us-east-1"
roles = [
"arn:aws:iam::987654321098:role/AtlasRDSRole", # Other account
]
filter {
tags = {
Environment = "production"
}
}
}
# Combine instances from both data sources
locals {
all_instances = concat(
data.rds_discovery.current_account.instances,
data.rds_discovery.other_accounts.instances
)
}
instance {
for_each = toset(local.all_instances)
name = each.value.identifier
driver = each.value.driver
tags = each.value.tags
metadata = each.value.metadata
connection {
host = each.value.address
port = each.value.port
user = each.value.master_user
database = each.value.initial_database
auth {
aws_iam {
endpoint = each.value.address
region = "us-east-1"
assume_role = each.value.assume_role
}
}
}
default_monitor "all" {
snapshot_interval = "1h"
statistics {
enabled = true
}
}
}
RDS Discovery Data Source Fields
The rds_discovery data source returns instances with the following fields:
identifier- Unique identifier for the instance (used as the map key)driver- Database driver (e.g., "postgres", "mysql")address- Database endpoint addressport- Database port numberinitial_database- Initial database to connect tomaster_user- Master username for the databaseassume_role- IAM role ARN used when discovering this instance (empty string if default credentials were used)iam_database_authentication_enabled- Whether IAM authentication is enabledtags- Map of tags associated with the instancearn- AWS ARN of the RDS instancemetadata- Map of instance metadata (e.g. region, engine, cluster info); pass through to the instance block'smetadataattribute
GCP Discovery
Automatically discover GCP database instances (AlloyDB, Cloud SQL, and Spanner) using the gcp_discovery
data source and create instance blocks for each discovered instance.
How GCP Discovery Works
The gcp_discovery data source uses your GCP credentials (from the environment, e.g.
GOOGLE_APPLICATION_CREDENTIALS, or default application credentials) to discover instances in a single GCP
project. You must enable at least one of alloydb, cloudsql, or spanner to discover that type of
instance.
Filtering Discovered Instances
The gcp_discovery data source supports filtering to narrow down which instances are discovered:
labels: Filter instances by GCP resource labels. You can specify label keys with specific values, or usenullto match any instance that has the label key (regardless of value).name_regex: Filter instances by name (or identifier) using a regular expression pattern.
Filters are applied together (AND logic), so an instance must match all specified filters to be included in the results.
data "gcp_discovery" "production" {
project = "my-gcp-project"
alloydb = true
cloudsql = true
spanner = true
filter {
labels = {
Environment = "production"
Team = "backend"
}
name_regex = ".*-prod$"
}
}
Example: Discovering AlloyDB and Cloud SQL Instances
AlloyDB and Cloud SQL instances use host/port connections. Use the discovered address, port,
initial_database, and configure authentication (e.g. Cloud SQL IAM or environment variable for password):
data "gcp_discovery" "relational" {
project = "my-gcp-project"
alloydb = true
cloudsql = true
filter {
labels = {
Environment = "production"
}
}
}
# Create an instance block for each discovered AlloyDB and Cloud SQL instance
locals {
relational_instances = concat(
data.gcp_discovery.relational.alloydb_instances,
data.gcp_discovery.relational.cloudsql_instances
)
}
instance {
for_each = { for inst in local.relational_instances : inst.identifier => inst }
name = each.value.display_name
driver = each.value.driver
tags = each.value.labels
metadata = each.value.metadata
connection {
host = each.value.address
port = each.value.port
user = "atlas_monitor"
database = each.value.initial_database != "" ? each.value.initial_database : "postgres"
auth {
env_var "DATABASE_PASSWORD" {}
}
}
default_monitor "all" {
snapshot_interval = "1h"
statistics {
enabled = true
}
}
}
Example: Discovering Spanner Instances
Spanner instances use a connection path (project/instance/database). Each Spanner instance can have
multiple databases; you can create one instance block per Spanner instance and use monitor blocks per
database, or structure your config to match your discovery output:
data "gcp_discovery" "spanner" {
project = "my-gcp-project"
spanner = true
filter {
labels = {
Environment = "production"
}
}
}
# One instance block per Spanner instance
instance {
for_each = { for inst in data.gcp_discovery.spanner.spanner_instances : inst.identifier => inst }
name = each.value.display_name
driver = each.value.driver
tags = each.value.labels
metadata = each.value.metadata
connection {
path = each.value.address
}
}
# One monitor per database (Spanner instance + database)
monitor "all" {
for_each = flatten([
for inst in data.gcp_discovery.spanner.spanner_instances : [
for db in inst.databases : merge(db, { instance_id : inst.identifier })
]
])
instance = instance[each.value.instance_id]
database = each.value.name
statistics {
enabled = true
}
}
GCP Discovery Data Source Fields
The gcp_discovery data source returns:
alloydb_instances– List of AlloyDB instances (one per cluster, preferring a reader instance). Each element has:name,identifier,display_name,driver(e.g."postgresql"),address,port,initial_database,labels,metadata(map of instance metadata; pass through to the instance block'smetadataattribute).cloudsql_instances– List of Cloud SQL instances. Each element has:name,identifier,display_name,driver(e.g."postgresql","mysql","sqlserver"),address,port,initial_database,labels,metadata(map of instance metadata; pass through to the instance block'smetadataattribute).spanner_instances– List of Spanner instances. Each element has:name,identifier,display_name,driver("spanner"),address(e.g.projects/{project}/instances/{instance}),databases(list of{ name, dialect, state }),labels,metadata(map of instance metadata; pass through to the instance block'smetadataattribute).
Monitor the Discovered Instances
Discovered instances are monitored like any other instance. From Monitoring > Instances, click an instance name to view its schema, ERD, and changelog. The agent takes a new snapshot on each monitoring interval, and Atlas records every schema change it finds.
From there, you can:
- Compare an instance against its intended schema with drift detection.
- Send schema change and drift alerts to Slack with Slack notifications.
- Move discovery into your deployment by declaring the
rds_discoveryorgcp_discoverydata source in the agent configuration file and deploying the agent with Helm or Terraform.
Next Steps
Agent Quickstart
Configure the Atlas Agent and its monitored instances in HCL
Security and Credentials
Configure how the agent authenticates to your databases
Drift Detection
Detect when a live schema deviates from its intended state
Slack Notifications
Send schema change and drift notifications to Slack
Deploy with Helm
Run the Atlas Agent on Kubernetes using the Helm chart
Agent HCL Reference
Full reference for agent, instance, and data source blocks