Amazon Redshift connection¶
Connect a task to an Amazon Redshift cluster (or Redshift Serverless) over a managed Leoflow Connection. Redshift speaks the Postgres wire protocol, so the Connection has the same host-bearing shape as Postgres.
Declare the provider¶
Each DAG image bundles only the providers it declares. Add Redshift in
leoflow.yaml:
URI shape¶
The control plane builds this URI from the Connection's fields and percent-escapes
reserved characters in the password (e.g. @ โ %40). The receiving
RedshiftSQLHook un-escapes back to the original. The chain-of-custody test
TestRedshiftConnectionURIShapeIntegration pins the round-trip, including a
password with reserved characters.
Fields¶
| Field | Required | Notes |
|---|---|---|
| Conn Id | yes | e.g. redshift_dw. Exported as AIRFLOW_CONN_REDSHIFT_DW. |
| Conn Type | yes | redshift. |
| Host | yes | Cluster endpoint, e.g. mycluster.abc123.eu-central-1.redshift.amazonaws.com. |
| Port | optional | Defaults to 5439. |
| Login | yes* | DB user. Omit when using IAM auth (keyless โ preferred). |
| Password | yes* | DB password. Stored encrypted at rest (ADR 0019). Omit for IAM auth. |
| Schema | optional | The database name. |
| Extra | optional | JSON, e.g. {"sslmode":"require"} or IAM hints ({"iam":true,"cluster_identifier":"mycluster"}). |
* Login/Password are only needed for the password auth path. Keyless-first (IAM role, ADR 0035) is the recommended posture: attach an IAM role to the task identity and let the hook mint temporary credentials.
Example DAG (doc-only)¶
The provider import goes inside the @task body โ a top-level provider
import runs at parse time and fails the compile (the parser image doesn't carry
provider deps).
from datetime import datetime
from airflow.decorators import dag, task
@dag(schedule=None, start_date=datetime(2024, 1, 1), catchup=False)
def redshift_demo():
@task
def count_rows() -> int:
from airflow.providers.amazon.aws.hooks.redshift_sql import RedshiftSQLHook
hook = RedshiftSQLHook(redshift_conn_id="redshift_dw")
rows = hook.get_records("SELECT count(*) FROM analytics.events")
return int(rows[0][0])
count_rows()
redshift_demo()
Security notes¶
- Keyless-first. Prefer an IAM role on the task identity over a stored password (ADR 0035). The Connection then carries only the host + IAM hints, no secret.
- TLS in transit. Pass
sslmode=require(orverify-full) in Extra. - Never log the URI โ it carries the password. Log host + login only.
- Secrets travel only over the authenticated, TLS agent channel (ADR 0021).
Related¶
- ADR 0019 โ secret encryption at rest.
- ADR 0021 โ agent secret delivery.
- ADR 0035 โ keyless-first cloud connector auth.
- athena.md โ the other AWS data service in this batch.