# AWS EC2 fleet

> Agentless CloudWatch metric streaming — see your EC2 instances without installing anything

Rocketgraph shows your EC2 fleet without an agent on any instance. A CloudFormation stack
creates a CloudWatch Metric Stream in **your** account that pushes metrics to your
Rocketgraph ingress. No long-lived AWS credentials leave your account — Firehose assumes
an IAM role you own.

## Connect

Open **Integrations → AWS** in the dashboard and click *Connect AWS*. The quick-create
link is prefilled with your ingress endpoint and API key, so the only thing you choose is
the region.

```
CloudWatch metrics (AWS/EC2)
        │
        ▼
CloudWatch Metric Stream        OutputFormat: opentelemetry1.0
        │
        ▼
Kinesis Firehose                GZIP · buffer 60s / 1 MB · retry 60s
        │                       failures → S3 backup bucket (7-day expiry)
        ▼
https://ingress.rocketlog.io/firehose     auth: X-Amz-Firehose-Access-Key
        │
        ▼
ClickHouse
```

> **Note:** Delivery goes to the `/firehose` path, not the plain OTLP `/v1/metrics` path. Firehose
  wraps records in its own envelope, so it needs the Firehose receiver rather than the OTLP
  one.

The stack streams the `AWS/EC2` namespace by default. `MetricNamespaces` is a
comma-delimited parameter, so you can add `AWS/RDS`, `AWS/ApplicationELB` and others later
without changing anything on the Rocketgraph side.

## What the fleet view shows

The hexagon grid on **Infrastructure → AWS** is built from two CloudWatch metrics:

| Metric | Used for |
| --- | --- |
| `CPUUtilization` | CPU %, computed as Sum ÷ Count of the latest sample |
| `StatusCheckFailed` | Any non-zero sum puts the instance into `warning` |

Instances are grouped by the `InstanceId` dimension; region comes from the
`cloud.region` resource attribute. Only instances that reported in the **last 15 minutes**
appear.

### Health states

```
stopped   not reporting as running
warning   StatusCheckFailed > 0 — an EC2 status check is failing
idle      CPU < 3%    — running, doing essentially nothing
low       CPU < 15%   — running, lightly loaded
healthy   CPU >= 15%  — running and working
```

`idle` is a cost signal rather than a fault — it is the state to look for when hunting
instances nobody needs any more.

> **Note:** There is no sample or preview data. Until a stream is connected the fleet is empty rather
  than populated with placeholders.

## Known limits

> **Warning:** The metric stream carries only the `InstanceId` dimension — **no availability zone and no
  instance type**. Every instance is labelled `EC2` and the grid groups by region only.
  Getting AZ and type requires either extra CloudWatch dimensions or an
  `ec2:DescribeInstances` call, neither of which the agentless stream makes today.

- **Names are instance ids.** Name tags are not carried in the stream.
- **Uptime is a proxy** — how long Rocketgraph has observed the instance, not its real
  launch time. Reconnecting the stream resets it.
- **Metric streams do not cross regions.** An account spanning `us-east-1` and `us-east-2`
  needs the stack deployed once in each, or instances in the missing region never appear.

## Troubleshooting

**Nothing after 15 minutes.** Check the Firehose delivery stream in the AWS console for
delivery errors. Firehose retries for 60 seconds, then writes the record to the S3 backup
bucket the stack created.

**Objects piling up in the backup bucket** means delivery is failing, not that metrics are
missing. The object body carries the HTTP response from the ingress — a `401` there means
the API key parameter is wrong. The bucket expires objects after 7 days, so debug while
the evidence still exists.

**Some instances missing.** Confirm the stack is deployed in that instance's region, and
that the instance has been running long enough to emit a CloudWatch sample.

## Beyond metrics

CloudWatch gives you the managed view. For traces and logs from applications running on
those instances, instrument the app and send OTLP — see [AWS](/instrumentation/aws) for
ECS, Fargate, Lambda and EC2 collector setup.
