> For the complete documentation index, see [llms.txt](https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services.md).

# Amazon Web Services

Connect AWS to Heeler across an entire Organization or a single account, with CloudFormation, Terraform, or the AWS CLI.

Heeler gets broad, read-only visibility into AWS and can onboard **all accounts via an AWS Organization** or **an individual account**. Connecting at the **Organization** level is recommended — it simplifies onboarding and keeps coverage complete as your footprint grows (new accounts are picked up automatically).

To add near-real-time change detection, also set up [AWS Event Collection](/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services/aws-event-collection.md).

## Setup paths

<table data-view="cards"><thead><tr><th></th><th></th><th data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>AWS Organization Setup</strong> (recommended)</td><td>One template on the payer account; StackSets deploy to every member account.</td><td><a href="/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services/aws-organization-setup.md">AWS Organization Setup</a></td></tr><tr><td><strong>AWS Single Account Setup</strong></td><td>One template on one account.</td><td><a href="/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services/aws-single-account-setup.md">AWS Single Account Setup</a></td></tr><tr><td><strong>AWS Event Collection</strong></td><td>Near-real-time changes via CloudTrail → SQS.</td><td><a href="/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services/aws-event-collection.md">AWS Event Collection</a></td></tr><tr><td><strong>AWS Supported Services</strong></td><td>Per-service polling cadence and event support.</td><td><a href="/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services/aws-supported-services.md">AWS Supported Services</a></td></tr></tbody></table>

## Setup options

Heeler provides templates for **CloudFormation** and **Terraform**, plus **AWS CLI** instructions for single-account. The in-app on-boarding wizard can **launch the CloudFormation StackSet for you**.

<table><thead><tr><th width="200">Method</th><th>Best for</th></tr></thead><tbody><tr><td><strong>CloudFormation</strong> (recommended)</td><td>The wizard launches the template/StackSet directly — the least manual path.</td></tr><tr><td><strong>Terraform</strong></td><td>Teams that manage cloud infrastructure as code.</td></tr><tr><td><strong>AWS CLI</strong></td><td>A scripted single-account setup (bash script provided).</td></tr></tbody></table>

## What the template deploys

In each account, Heeler provisions tightly-scoped IAM so it can read **metadata and configuration only** — never your data plane:

* An IAM policy **`Heeler`** that **denies** data-plane actions (`s3:GetObject`, `dynamodb:GetItem`, and more) and **allows** two workload-analysis actions, `lambda:GetFunction` and `ssm:SendCommand` (optional — see below).
* An IAM policy that lets Heeler associate `AmazonEKSAdminViewPolicy` with its own access entry on each EKS cluster. Its name depends on the template: **`HeelerEKS`**, **`HeelerEKS-tf`**, **`HeelerItemizedEKS`**, or **`HeelerItemizedEKS-tf`**. The Terraform modules take the name as an input, so yours can differ. See [Kubernetes access on EKS](#kubernetes-access-on-eks) for what that grants inside the cluster, and for the least-privilege alternative.
* A **`heeler-member`** role carrying those policies plus the AWS-managed **`ReadOnlyAccess`**, trusted by a read-only management role.
* For Organizations: a **`heeler-management-ro`** role in the payer account and a **StackSet** that rolls the member setup out to every account, now and in the future.

{% hint style="info" %}
**`ssm:SendCommand` is optional and applies only to EC2 workloads.** It exists solely so Heeler can run its read-only analyzer on EC2 instances. If an account runs no EC2 workloads, remove the action from the `Heeler` policy: Heeler detects the denial and skips EC2 workload scans, and everything else continues to work. The same applies per workload type on other clouds — see the [Azure code-scanning role](/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/microsoft-azure.md#create-and-assign-the-code-scanning-role) and the [GCP Artifact Registry grant](/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/google-cloud-platform/gcp-organization-setup.md#grant-org-level-read-roles).
{% endhint %}

## Kubernetes access on EKS

Heeler reads Kubernetes resources from inside each EKS cluster. That access is separate from the IAM permissions above, and you grant it one of two ways.

### An AWS-managed access policy

The EKS policy created by the template lets Heeler associate **`AmazonEKSAdminViewPolicy`** with its own access entry on each cluster. The AWS-managed policy is read-only despite its name.

`AmazonEKSViewPolicy` is not sufficient. It maps to the stock Kubernetes `view` role, which omits six resource types Heeler reads: `nodes`, `persistentvolumes`, `ingressclasses`, both admission webhook configuration types, and the Argo Rollouts CRD. Among the AWS-managed access policies, only `AmazonEKSAdminViewPolicy` and the cluster-admin tier cover all six.

`AmazonEKSAdminViewPolicy` also grants read on Kubernetes Secrets. Heeler does not read them. AWS provides no way to remove a resource from a managed policy: an IAM `Deny` does not apply to Kubernetes API calls, and Kubernetes RBAC has no deny rule.

### A ClusterRole you manage

On this path you provision cluster access yourself and Heeler associates no AWS-managed policy. The EKS policy is not created, so Heeler holds neither `eks:CreateAccessEntry` nor `eks:AssociateAccessPolicy` and cannot change its own cluster access. The `heeler-member` role keeps `ReadOnlyAccess`, which covers the EKS describe and list calls Heeler uses to discover clusters.

To follow this path you need permission to create and update EKS access entries, to disassociate access policies, and to apply cluster-scoped RBAC on each cluster.

#### Where the access mode is set

Two things are set independently: whether the account holds the EKS IAM policy, and which mode Heeler uses on a given cluster.

<table><thead><tr><th width="330">Setting</th><th>Scope</th></tr></thead><tbody><tr><td>The onboarding template option</td><td>Whether the EKS IAM policy is created in the account.</td></tr><tr><td>The AWS connection default</td><td>Every cluster on that connection that carries no per-cluster setting, including clusters Heeler discovers later. Contact the Heeler team to set it.</td></tr><tr><td><strong>Kubernetes Access</strong> on a cluster row under <strong>Connections → Kubernetes Clusters</strong></td><td>That one cluster. It overrides the connection default until you clear it. See <a href="/mrecEO40m5D6bt7Pq5pE/administer-and-monitor/connections-and-integrations/source-connections.md">Source Connections</a>.</td></tr></tbody></table>

Decline the IAM policy on whichever onboarding template you deployed:

<table><thead><tr><th width="330">Template</th><th>Setting</th></tr></thead><tbody><tr><td>CloudFormation, Organization or single account</td><td><code>CustomerManagedK8sRbac = true</code></td></tr><tr><td>Terraform, Organization or single account</td><td><code>customer_managed_k8s_rbac = true</code></td></tr><tr><td>Itemized variants of either</td><td><code>EnableEksAccess</code> / <code>enable_eks_access = false</code></td></tr></tbody></table>

On the itemized templates, `false` declines only the EKS permissions. Kubernetes inventory still arrives, granted by the ClusterRole you apply.

#### New clusters

**1. Create the access entry**, placing the Heeler member role in a Kubernetes group:

```sh
aws eks create-access-entry \
  --cluster-name <cluster> \
  --principal-arn <heeler-member-role-arn> \
  --kubernetes-groups heeler-readers
```

Do not associate an AWS-managed access policy with this entry. The ClusterRole below replaces it.

**2. Apply the `heeler-inventory-reader` ClusterRole and binding.** It grants `get` and `list` on the resources Heeler reads. Secrets are absent, and `watch` is not granted.

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: heeler-inventory-reader
  annotations:
    heeler.ai/cluster-role-version: "1"
rules:
  - apiGroups: [""]
    resources: [configmaps, endpoints, namespaces, nodes, persistentvolumeclaims,
                persistentvolumes, pods, serviceaccounts, services]
    verbs: [get, list]
  - apiGroups: ["admissionregistration.k8s.io"]
    resources: [mutatingwebhookconfigurations, validatingwebhookconfigurations]
    verbs: [get, list]
  - apiGroups: ["apps"]
    resources: [daemonsets, deployments, replicasets, statefulsets]
    verbs: [get, list]
  - apiGroups: ["argoproj.io"]
    resources: [rollouts]
    verbs: [get, list]
  - apiGroups: ["batch"]
    resources: [cronjobs, jobs]
    verbs: [get, list]
  - apiGroups: ["networking.k8s.io"]
    resources: [ingressclasses, ingresses, networkpolicies]
    verbs: [get, list]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: heeler-inventory-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: heeler-inventory-reader
subjects:
  - kind: Group
    name: heeler-readers
    apiGroup: rbac.authorization.k8s.io
```

Repeat both steps for each cluster in the account. The connection reports healthy and Kubernetes workloads appear in your inventory within one collection cycle.

#### Clusters Heeler already onboarded

A cluster Heeler onboarded has an access entry for the member role with `AmazonEKSAdminViewPolicy` associated. Heeler does not disassociate access policies, so you remove that association. Until you do, the access entry carries the read on Kubernetes Secrets.

Follow the steps in order.

**1. Set the mode in Heeler**, with **Kubernetes Access** on the cluster row or with the AWS connection default. Heeler associates no policy from its next onboarding run onward. Set the mode before you change anything in AWS, so the policy is not re-associated.

**2. Update the access entry** to place the member role in the Kubernetes group. Creating an entry fails when one already exists for the principal, so use `update-access-entry`:

```sh
aws eks update-access-entry \
  --cluster-name <cluster> \
  --principal-arn <heeler-member-role-arn> \
  --kubernetes-groups heeler-readers
```

**3. Disassociate the AWS-managed access policy** from that entry:

```sh
aws eks disassociate-access-policy \
  --cluster-name <cluster> \
  --principal-arn <heeler-member-role-arn> \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminViewPolicy
```

**4. Apply the `heeler-inventory-reader` ClusterRole and binding** shown above.

Repeat the four steps for each cluster. Until the ClusterRole is in place, the cluster reports impaired visibility and names the resources it cannot read.

{% hint style="info" %}
**Missing grants appear on the connection.** Heeler re-checks the ClusterRole on every connection health sweep using a `SelfSubjectAccessReview`, which requires no permission of its own. When a grant is missing, the connection reports impaired visibility and names the resources it cannot list. The ClusterRole carries a version annotation: when Heeler starts reading a new resource type that version changes, and you re-apply the manifest.
{% endhint %}

## Permissions for the person doing the setup

These are the permissions the operator needs to run the template — **not** the permissions Heeler ends up with. Confirm they're in place before you start:

```
cloudformation:CreateStackSet · UpdateStackSet · DeleteStackSet ·
  CreateStackInstances · DeleteStackInstances · DescribeStackSet · ListStackInstances
iam:CreateRole · UpdateAssumeRolePolicy · PutRolePolicy · DeleteRolePolicy · TagRole ·
  GetRole · ListRoles · CreatePolicy · AttachRolePolicy · DeletePolicy · DetachRolePolicy ·
  GetPolicy · GetPolicyVersion · ListPolicies · CreateServiceLinkedRole
```

Prefer to check first? Download the operator permission-check script and run it against the target account before you start:

{% file src="/files/bSYfmOhThmS6aOtoDP66" %}

{% hint style="info" %}
**Validation is built in.** Before a connection saves, Heeler runs preflight checks — role assumption, account/OU listing, a sampled harvest, and an IAM-permission simulation. The connection won't save until every check passes, and each failure shows inline guidance.
{% endhint %}

## Related

* [Connect Your Cloud and Runtime](/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime.md) — the spine and event-collection concept.
* [AWS CodeArtifact](/mrecEO40m5D6bt7Pq5pE/get-started/registries-and-artifacts/aws-codeartifact.md) — first-party package analysis on top of this connection.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/get-started/cloud-and-runtime/amazon-web-services.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
