> ## Documentation Index
> Fetch the complete documentation index at: https://docs.incident.io/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS

> Connect AWS once to give investigations CloudWatch, EKS, OpenSearch, and your RDS databases.

AWS is a provider: connect it once and investigations reach the accounts and regions behind your credentials. From there they discover the services you enable: CloudWatch metrics and logs, Kubernetes workloads on EKS, OpenSearch domains, and PostgreSQL or MySQL databases on RDS and Aurora.

## What it provides

Connecting AWS lets investigations discover and query the data sources behind it:

| Data source                                                          | Capability       |
| -------------------------------------------------------------------- | ---------------- |
| [CloudWatch](/investigations/connect/telemetry/cloudwatch)           | Metrics and logs |
| [Kubernetes](/investigations/connect/telemetry/kubernetes) (via EKS) | Cluster state    |
| [OpenSearch](/investigations/connect/telemetry/opensearch)           | Logs             |
| [PostgreSQL](/investigations/connect/telemetry/postgresql) (via RDS) | SQL              |
| [MySQL](/investigations/connect/telemetry/mysql) (via RDS)           | SQL              |

Each has its own page covering what it supports and how it's queried. CloudWatch is region-scoped, so investigations see one CloudWatch data source per region you enable. Selecting RDS discovers both RDS and Aurora databases (`aurora-postgresql` / `aurora-mysql`); they appear as PostgreSQL or MySQL children, not a separate Aurora type.

## Setup

Setting up AWS has two parts: give incident.io credentials that can read your telemetry, then choose the accounts and regions investigations may query.

### Credentials

Choose one of two ways for incident.io to authenticate to your account.

* **OIDC IAM role (recommended).** Create a role that incident.io assumes with `sts:AssumeRoleWithWebIdentity`. You provide the role ARN. The trust policy federates `accounts.google.com` and pins two conditions: `accounts.google.com:sub` (the numeric unique ID of incident.io's Google service account, shown in the setup form) and `accounts.google.com:oaud` (`incident-io-telemetry`). Do not pin `accounts.google.com:aud`. Sessions are short-lived, so there are no long-lived keys to store or rotate.
* **Static access keys.** Create an IAM user with the same permissions and paste in its access key ID and secret access key. This works for a single account, but the keys are long-lived and you own rotating them, so prefer the role.

We recommend read-only access either way. Investigations only ever read telemetry from AWS; they never change anything.

The connect form shows CLI, Terraform, and CloudFormation tabs with the exact trust and permissions policy JSON for the services you selected. Use those rather than copying a policy from elsewhere.

### Permissions per service

Grant only the actions for the services you want investigations to use. The in-product setup emits an IAM policy with one block per service, so you can keep a block to allow that service or drop it to hold it back:

* **CloudWatch**: `cloudwatch:ListMetrics`, `cloudwatch:GetMetricData`, and the CloudWatch Logs Insights actions `logs:DescribeLogGroups`, `logs:StartQuery`, `logs:GetQueryResults`, and `logs:StopQuery`. `logs:StopQuery` lets a running query be canceled rather than left to finish.
* **EKS**: `eks:ListClusters` and `eks:DescribeCluster` to discover clusters. Access to workloads inside each cluster is granted separately: create an EKS access entry for the role or user, and associate the managed `AmazonEKSViewPolicy` on each cluster.
* **OpenSearch**: `es:ListDomainNames`, `es:DescribeDomains`, `es:ListTags`, and the data-plane calls `es:ESHttpGet`, `es:ESHttpPost`, and `es:ESHttpHead`. Domains also need a domain access policy that allows those `es:ESHttp*` calls. If fine-grained access control (FGAC) is enabled, map the principal to an OpenSearch backend role with read privileges.
* **RDS**: `rds:DescribeDBInstances`, `rds:DescribeDBClusters`, and `rds:DescribeBlueGreenDeployments` for discovery. The IAM policy covers discovery of your RDS and Aurora databases. After you connect, choose how each database authenticates: RDS IAM (`rds-db:connect` on the database user, with no stored password) or a username and password. Add a [proxy](/integrations/proxy) if the database isn't reachable from the public internet.

<Tip>
  The blocks in the IAM policy match the service toggles in the connect form. Whatever you choose during connection, the
  permissions you grant and the services investigations use stay in step.
</Tip>

### Connecting

1. From the [Investigations settings](https://app.incident.io/~/investigations), add a telemetry data source and choose **AWS**.
2. Choose OIDC or access keys, select the services to enable, and follow the in-product instructions to create the role or user. Provide the role ARN, or the access keys, along with a default region.
3. Optionally set a region allowlist, the regions investigations may query. Leave it empty to use the default region only.
4. Test the connection. Before connecting, incident.io makes read-only calls to each service you selected and reports back exactly which permissions are missing, per service, so you can fix the policy before finishing.

Once connected, investigations discover the account behind your credentials and a child data source for each service and region you enabled.

<Note>
  Discovered accounts, regions, and children are disabled by default, so you opt in deliberately. Review what's found
  and enable the ones your team relies on during incidents.
</Note>

### Pre-existing Google OIDC provider

If the AWS account already has an IAM Identity Provider for `accounts.google.com`, AWS validates the incoming token against that provider's **Client IDs** before it evaluates the role trust policy.

When that list doesn't include incident.io's identity, the connection fails with `InvalidIdentityToken`, even if the trust policy's `sub` and `oaud` conditions are correct.

Fix it by adding our service account's **numeric unique ID** (the same value as `accounts.google.com:sub` in the setup form) to the provider's Client IDs. Adding only `incident-io-telemetry` is not enough when the token carries an `azp` claim, because AWS compares Client IDs against `azp` in that case.

Check whether a provider already exists in the console under IAM → Identity providers, or with `aws iam list-open-id-connect-providers`.

## Related

<CardGroup cols={2}>
  <Card title="CloudWatch" icon="chart-line" href="/investigations/connect/telemetry/cloudwatch">
    Metrics and logs behind AWS.
  </Card>

  <Card title="Kubernetes" icon="cubes" href="/investigations/connect/telemetry/kubernetes">
    Workloads on your EKS clusters.
  </Card>

  <Card title="OpenSearch" icon="database" href="/investigations/connect/telemetry/opensearch">
    Logs on your OpenSearch domains.
  </Card>

  <Card title="PostgreSQL" icon="database" href="/investigations/connect/telemetry/postgresql">
    SQL against RDS and Aurora Postgres.
  </Card>

  <Card title="Telemetry overview" icon="database" href="/investigations/connect/telemetry/overview">
    How providers and data sources fit together.
  </Card>

  <Card title="How telemetry works" icon="magnifying-glass" href="/investigations/connect/telemetry/how-it-works">
    Routing, query planning, guidance, and memory.
  </Card>
</CardGroup>
