# AWS Integration

Source: https://docs.ops0.com/docs/settings/integrations/aws

ops0 connects to AWS using IAM role assumption (STS AssumeRole). This is the only supported method — no long-lived access keys are stored.

---

## Adding the Integration

### Navigate to Integrations
Go to **Settings** > **Integrations** > **Add Integration**.

### Select AWS
Choose **AWS** from the provider list.

### Enter Credentials
Provide the required AWS identifiers and region settings.

### Set Up the IAM Role
Create the IAM role in your AWS account using the trust policy shown in the form.

### Connect
Click **Connect** to verify the integration.

![AWS integration setup form in ops0](https://docs.ops0.com/images/settings-integrations-aws.png)

---

## Assume Role Fields

| Field | Required | Description |
|-------|----------|-------------|
| **Name** | Yes | Integration display name |
| **Role ARN** | Yes | ARN of the IAM role ops0 will assume |
| **Regions** | Yes | One or more AWS regions to use |

---

## External ID

ops0 automatically generates a deterministic External ID from your organization ID. You do **not** create this value — ops0 creates it for you.

To find your External ID:

1. Navigate to **Settings** > **Integrations** > **Add AWS Integration**.
2. The External ID is displayed in the integration form.
3. Copy it and paste it into your IAM role's trust policy.

**Do Not Create Your Own External ID**

Always use the External ID shown in the ops0 integration form. Do not generate or substitute your own value — the role assumption will fail if the IDs do not match.

---

## Setting Up the IAM Role

### Create the Role
In the AWS Console, create a new IAM role and select **Another AWS account** as the trusted entity type.

### Add the Trust Policy
Copy the External ID from the ops0 integration form and use it in the trust policy below.

### Attach Permissions
Grant the role the discovery or deployment permissions you want ops0 to use.

### Copy the Role ARN
Paste the **Role ARN** into the integration form in `brew.ops0.ai`.

**Trust Policy**

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<paste the External ID shown in the ops0 integration form>"
        }
      }
    }
  ]
}
```

---

## Required AWS Permissions

### For IaC Deployments

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:*",
        "s3:*",
        "iam:*",
        "rds:*",
        "lambda:*"
      ],
      "Resource": "*"
    }
  ]
}
```

### For Discovery Only

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*",
        "s3:List*",
        "rds:Describe*",
        "lambda:List*"
      ],
      "Resource": "*"
    }
  ]
}
```

---

## Organization & Multi-Account Scanning

When connecting an AWS integration, you can scope it to scan across your entire AWS Organization or selected member accounts. This requires the integration to be set up on the management (payer) account.

### Scan Modes

| Mode | Description |
|------|-------------|
| **Single Account** | Scan only the account the role belongs to (default) |
| **Organization** | Scan all accounts in your AWS Organization |
| **Selected Accounts** | Scan specific member account IDs you list |

### Additional Fields for Organization and Selected Accounts Modes

| Field | Description |
|-------|-------------|
| **AWS Organization ID** | Your org ID (e.g. `o-abc123`) |
| **Management Account ID** | Account ID of the management/payer account |
| **Member Accounts** | Account IDs to include (Selected Accounts mode) |
| **Excluded Accounts** | Account IDs to skip (Organization mode) |

### Required IAM Permissions for Org Scanning

Add the following to the IAM role policy on the management account:

```json
{
  "Effect": "Allow",
  "Action": [
    "organizations:ListAccounts",
    "organizations:DescribeOrganization",
    "sts:AssumeRole"
  ],
  "Resource": "*"
}
```

**Member Account Roles**

ops0 assumes a role in each member account. Each member account must have a role with the same trust policy pointing back to your management account role.

---

## 1-Click IAM Role Setup

Instead of manually creating the IAM role, ops0 can generate a CloudFormation template that creates the role for you with a single click.

### Open 1-Click Setup
In the AWS integration form, click **Launch with CloudFormation**.

### Select a permission tier
Choose how much access to grant the role:

| Tier | Description |
|------|-------------|
| **Discovery only** | Read-only `Describe*` and `List*` permissions for resource scanning |
| **IaC deployments** | Full service permissions for Terraform deployments |
| **Admin** | Broad administrative access for all ops0 features |

### Launch the stack
ops0 generates a CloudFormation template and opens the AWS Console with it pre-loaded. Click **Create Stack**.

### Copy the Role ARN
After the stack creates (usually under 30 seconds), find the Role ARN in the stack Outputs tab and paste it into the ops0 integration form.

**The External ID is pre-embedded**

The generated CloudFormation template includes your organization's External ID in the trust policy condition automatically — no need to copy it manually.

---

## AI Policy Generator

If you prefer to create the IAM role manually but need a custom policy, ops0 can generate one using AI.

### Open AI Policy Generator
In the integration form, click **Generate IAM Policy with AI**.

### Describe what you need
Describe the AWS services and operations ops0 should have access to:

```
I need ops0 to:
- Discover EC2, RDS, S3, and Lambda resources
- Deploy Terraform for EC2 and ECS workloads
- Read CloudWatch metrics
```

### Review the generated policy
The AI produces an IAM policy document with least-privilege permissions for your described use case.

### Copy and apply
Copy the policy JSON and attach it to your IAM role in the AWS Console.

---

## Troubleshooting

- **Access Denied**: Verify the trust policy includes the correct AWS account ID and external ID.

- **Role Not Found**: Confirm the IAM role exists and the copied ARN is exact.

- **Invalid External ID**: Use the value shown in ops0 rather than a custom identifier.

---

## Related

- [Connect Your Cloud](https://docs.ops0.com/docs/getting-started/connect-cloud#aws): Quick-start onboarding for AWS and other providers.

- [Integrations Overview](https://docs.ops0.com/docs/settings/integrations): Return to the shared integrations documentation.
