How do I add Postgres tables to the evidence an AI SRE reads when CloudWatch alarms fire?
Tares lets you add a Postgres source next to your CloudWatch alarm source, so rows from your own tables are stored as events alongside the alarm events. CloudWatch alarms reach Tares through the webhook connector and an EventBridge setup, and the postgres connector polls the table you choose on a cursor column. Each source gets labels, with one primary label such as tenant_id, so you can see which tenant or order the incident touched. Together they give an AI SRE a second signal beyond telemetry.
How it works
You run two sources side by side, each with its own path into Tares.
- CloudWatch alarms reach Tares through the webhook connector and a vendor setup in AWS. Tares has no connector of its own for CloudWatch today. EventBridge posts each alarm state change as a JSON body to the source’s ingest URL, and the webhook connector stores the payload lossless. It parses the body whatever the Content-Type.
- Postgres tables are polled by Tares. The postgres connector reads a table incrementally and creates one event per new or changed row. A cursor column that only grows, such as an autoincrement id or updated_at, tracks where the last poll stopped.
- Labels map payload fields and columns into each event. Mark one label primary on each source. For orders, that is usually an entity column such as tenant_id.
The alarm event carries source and detail-type as top-level fields. The alarm name sits at detail.alarmName, which works as a one-level dotted label. detail.state.value is two levels deep, so flatten it with an input transformer on the EventBridge rule target if you want it as a label or in a text template.
The postgres driver ships with Tares, so there is nothing extra to install. The database only has to be reachable from the Tares host.
Set it up
- Create the CloudWatch webhook source. In the console go to Sources, Add source, webhook. Declare a label for each payload field you want to correlate on and mark one primary. Use detail.alarmName for the alarm name. Save, then copy the ingest endpoint from the source page. EventBridge needs a public HTTPS URL, so the endpoint must be reachable that way.
- Point EventBridge at it. Create an API destination whose endpoint is the Tares ingest URL and whose method is POST. Give it a connection, which EventBridge requires on every API destination. Use API key authorization with header name Authorization and the value Bearer followed by an ingest-scoped API key. The key value only matters when Tares has auth on.
- Route alarms to the destination. Create a rule on the default event bus that matches source aws.cloudwatch and detail-type CloudWatch Alarm State Change. Set the API destination as the rule’s target. Alarm actions that publish to SNS are a different route and do not fit. An SNS HTTPS subscription cannot send a custom header, and its SubscriptionConfirmation message would never be confirmed.
- Add the Postgres source. In the console go to Sources, Add source, Postgres. Enter the connection URL and press Discover. Tares lists the tables it can see, and after you pick one it proposes the cursor, the entity key and the labels from the columns. Choose which columns to pull, then save. You can also ask a connected agent to ingest the table, keyed by the column you name. The result looks like this:
- name: orders
connector: postgres
poll: 10s
config:
dsn: postgresql://user:pass@host:5432/appdb
table: orders
cursor_column: updated_at
columns: id,tenant_id,status,amount,updated_at # empty = every column
labels:
- { name: tenant_id, field: tenant_id, primary: true }
- { name: status, field: status }- Verify both sources. Open each source. Recent events shows the events that arrived, and Fields lists every field seen with its coverage. On the Postgres source, check that the key column is reliably present. On the CloudWatch source, check that alarm fields such as detail.alarmName arrive.
The dsn is stored as a secret, redacted in the API and omitted from catalog exports. Pull only the columns you need, so the evidence stays focused on who or what the incident touched.
What you get
- Alarm events and application rows are stored in Tares as events, each with labels you chose.
- A primary label on the table, such as tenant_id, names the entity each row belongs to.
- New and changed rows arrive on the poll interval you set, so the table keeps adding evidence after the first alarm.
- Each payload is stored as received, so labels you declare later can still reach every field.
- The Fields view shows how often each column or payload field arrives, so you can check your key before relying on it.
When something else fits
- If the evidence is an API response rather than a table, use the http_poll connector, which polls any JSON endpoint and stores one event per item.
- If a table has no column that only ever grows, the postgres connector has no cursor to track, so pick a different column or source for that data.
- If your alarms use SNS actions instead of EventBridge, switch to the EventBridge route in step 3, because the SNS route does not work with the webhook connector.
Related
- Postgres table
- How do I add Postgres tables to the evidence an AI SRE reads when alerts from Prometheus fire?
- How do I add Postgres tables to the evidence an AI SRE reads when Alertmanager alert groups fire?
- How do I add JSON API endpoints to the evidence an AI SRE reads when Datadog monitors fire?
Still stuck? Get help