Learn how to crawl Cloud SQL for PostgreSQL assets and publish them to Atlan for discovery.
Cloud SQL for PostgreSQL assets app
The Cloud SQL for PostgreSQL assets app crawls Cloud SQL for PostgreSQL databases,
schemas, tables, views, and columns and publishes them to Atlan. Build it with the
AtlanCloudsqlPostgresCrawler builder, which mirrors the "new app" wizard:
Credential → Connection → Metadata.
Each create mints a new connection and new assets. To re-crawl, re-run the existing workflow (see Re-run an existing app).
Cloud SQL for PostgreSQL supports four authentication methods: basic
(username/password), IAM user, IAM service account, and Workload Identity
Federation. The port is optional and defaults to 5432.
Basic authentication
- Python
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.apps import AtlanCloudsqlPostgresCrawler
client = AtlanClient()
response = (
AtlanCloudsqlPostgresCrawler(client)
.basic( # (1)
username="atlan_user", # (2)
password="••••••", # (3)
host="203.0.113.10", # (4)
database="postgres", # (5)
)
.connection( # (6)
name="production-cloudsql",
admin_roles=[client.role_cache.get_id_for_name("$admin")],
)
.include_metadata({"postgres": ["analytics", "sales"]}) # (7)
.run(name="cloudsql-prod") # (8)
)
print(response.slug, response.run_id)
- Step 1—Credential. Username/password auth; the secret is vaulted.
- Required. Database username.
- Required. Password.
- Required. The public IP address of the Cloud SQL instance. The port
(
port=) is optional and defaults to5432. - Required. Database to connect to.
- Step 2—Connection. Display name + at least one admin.
- Step 3—Metadata. Schemas to crawl, as
{database: [schema, ...]}. Omit to crawl everything. Exclude takes priority over include. .run(name=...)creates and submits a run; use.create(name=...)to create without running.
IAM authentication
For the IAM methods, Atlan connects through the Cloud SQL Language Connector, so
name is the instance connection name from the instance's Overview page
(<project>:<region>:<instance>). The IAM identity must also exist as a database
user on the instance.
- Python
# IAM user
AtlanCloudsqlPostgresCrawler(client).iam_user(
username="analyst@example.com", # (1)
password="ya29.••••••", # (2)
name="my-project:us-central1:my-instance", # (3)
database="postgres",
)
# IAM service account
AtlanCloudsqlPostgresCrawler(client).iam_service_account(
username="atlan-crawler@my-project.iam", # (4)
password="••••••", # (5)
name="my-project:us-central1:my-instance",
gcp_service_account='{"type": "service_account", ...}', # (6)
database="postgres",
)
# Workload Identity Federation
AtlanCloudsqlPostgresCrawler(client).workload_identity_federation(
username="atlan-crawler@my-project.iam", # (7)
name="my-project:us-central1:my-instance",
database="postgres",
)
- Required. The IAM user's email address, without a trailing
.gserviceaccount.com. - Required. A short-lived access token for that user
(
gcloud auth print-access-token --account=<iam-user>). It expires in about an hour, so prefer a service account for scheduled workflows. - Required. The instance connection name.
- Required. The service account's email address, without a trailing
.gserviceaccount.com. - Required. The password field of the IAM service account form.
- Optional. The service account's JSON key, as a string. Omit it for keyless setups where the environment can obtain access tokens.
- Required. The service account the Self-Deployed Runtime's federation is configured for. Available only on a Self-Deployed Runtime on Google Cloud.
Configuration options
All metadata options are optional—set only what you need:
- Python
(
AtlanCloudsqlPostgresCrawler(client)
.basic(username="atlan_user", password="••••••", host="...", database="postgres")
.connection(name="production-cloudsql", admin_roles=[...])
.include_metadata({"postgres": ["analytics"]}) # (1)
.exclude_metadata({"postgres": ["staging"]}) # (2)
.exclude_regex_for_tables_views(".*_TMP|.*_TEMP|TMP.*|TEMP.*") # (3)
.redact_sql_text(True) # (4)
.cloud_provider("AWS") # (5)
.run(name="cloudsql-prod")
)
- Databases/schemas to include, as
{database: [schema, ...]}. - Databases/schemas to exclude—exclude takes priority over include.
- Regex of tables/views to ignore.
- Replace literal values in extracted view, function, and procedure definitions with placeholders. Off by default. See Query redaction.
- The cloud the Atlan tenant runs on, as the UI sets it for the same workflow.
Update existing workflows
Publish a new version on the same slug with the builder's load() / update().
It reads the workflow's current inputs, lets you change only the fields you pass,
and preserves everything else, including the connection and its credential. No run
starts; the next run, manual or scheduled, uses the new version.
- Python
(
AtlanCloudsqlPostgresCrawler(client)
.load("atlan-cloudsql-postgres-1700000000-AbC123") # (1)
.redact_sql_text(True) # (2)
.update()
)
- Seed the builder from the workflow's current inputs.
- Change only the fields you need; anything unset keeps its current value.
To apply one change across every Cloud SQL for PostgreSQL crawler and miner on the tenant, loop over the workflows:
- Python
from pyatlan.model.apps import AtlanCloudsqlPostgresCrawler, CloudsqlPostgresMiner
BUILDERS = {
"atlan-cloudsql-postgres": AtlanCloudsqlPostgresCrawler, # (1)
"cloudsql-postgres-miner": CloudsqlPostgresMiner, # (2)
}
cursor = None
while True:
page = client.app.get_all(limit=100, cursor=cursor)
for wf in page.workflows:
app_id = (wf.dag.get("extract") or {}).get("inputs", {}).get("app_id")
builder = BUILDERS.get(app_id)
if builder is None:
continue
builder(client).load(wf.slug).redact_sql_text(True).update() # (3)
if not page.has_more:
break
cursor = page.next_cursor
- Crawler workflows.
- Miner workflows. Redact SQL Text is a separate setting on each.
- One new workflow version per workflow, with only the toggle changed. Running the loop again is harmless.
See Manage apps for the rest of the lifecycle—list, get, run status, schedules, and delete—shared by every app.