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

# Amazon Web Services - Commitment Management Setup

> Enable AWS Commitment Management in nOps using CloudFormation. Deploy three IAM roles for cross-account access, commitment purchasing, and inventory reads.

## FAQs

<AccordionGroup>
  <Accordion title="Is this the same as the initial AWS integration setup?">
    No. The initial [AWS integration setup](/aws/integration-setup) connects **billing and cost visibility** (CUR + integration IAM role). Commitment Management uses **separate IAM roles** deployed via CloudFormation for purchasing and managing Reserved Instances and Savings Plans.
  </Accordion>

  <Accordion title="Does the central role have to be in the payer account?">
    No. Deploy `NopsCMCrossAccountAssume` in **any account in your AWS Organization**. Many teams use the management (payer) account for convenience, but a dedicated member account works the same way. What **does** require payer access: launching **StackSets** for the child read role and deploying the **payer read role** directly in the management account (StackSets skip that account by default).
  </Accordion>

  <Accordion title="Where is the ShareSave role deployed?">
    The **ShareSave** role is deployed in a **dedicated child account** within your AWS Organization. Commitments purchased from any account in an organization automatically apply across all accounts via RI/SP sharing. Using a dedicated account isolates purchase permissions from your payer account — a security best practice.
  </Accordion>

  <Accordion title="What permissions does nOps get?">
    Three roles with scoped permissions: a **central role** (can only assume child read roles), a **child read role** (read-only EC2, RDS, ElastiCache, Savings Plans, and Organizations metadata), and a **ShareSave role** (commitment purchasing, Cost Explorer, and Organizations read). See the full breakdown in each step below or the [Permissions & Resources](/aws/permissions-and-resources) reference.
  </Accordion>

  <Accordion title="Can I review the exact IAM policies before deploying?">
    Yes. Every permission is documented in this guide and in the [Permissions & Resources](/aws/permissions-and-resources) reference page. The CloudFormation templates are also available for review before you deploy them.
  </Accordion>

  <Accordion title="Do I need Inform to view Commitment Inventory?">
    No. [Commitment Inventory](/optimize/commitment-inventory) is included on every nOps plan for members, admins, and owners when your AWS integration is **active**. Inform is only required to **email** or **schedule** inventory reports. This CM setup is for purchasing and for the full cross-account inventory read path—not for opening the Inventory page itself.
  </Accordion>
</AccordionGroup>

***

## Overview

**You're enabling Commitment Management for AWS** — giving nOps the ability to view, quote, and purchase Reserved Instances and Savings Plans on your behalf across your AWS Organization.

Open your active AWS integration card in [**Settings > Cloud Provider Integrations**](https://clara.nops.io/settings) and choose **Enable CM**. You'll complete **four steps**:

1. **Central Role** — Deploy the central role in any org account; deploy child read roles via StackSets from the management account; capture ARNs
2. **ShareSave Role** — Dedicated child account: deploy ShareSave role for commitment purchasing
3. **Confirm Details** — Save role ARNs and external IDs to nOps
4. **Verify Access** — Platform checks assume-role chains and API access

**Prerequisite:** Complete [AWS integration setup](/aws/integration-setup) first (Legacy CUR + integration IAM role).

<Info>
  **Who can do this:** Only **Admin** users in your nOps organization can enable or manage Commitment Management. See [Users and roles](/platform/users).
</Info>

***

## Prerequisites

Before you start, make sure you can:

* Access the **payer (management) account** for **IAM**, **CloudFormation**, and **AWS Organizations**
* Run **CloudFormation StackSets** from the payer account (or a delegated administrator) with trusted access enabled
* Have the **Savings Analysis** integration already active on the same payer account

***

## CloudFormation templates

nOps uses three CloudFormation templates. Each creates a single IAM role with scoped permissions.

| Template                      | Role created               | Deploy in                                  | Purpose                                                                    |
| ----------------------------- | -------------------------- | ------------------------------------------ | -------------------------------------------------------------------------- |
| `nops-cm-central-role.yaml`   | `NopsCMCrossAccountAssume` | Any org account (not required to be payer) | Assume child read roles across member accounts                             |
| `nops-cm-child-role.yaml`     | `NopsCMReadEC2Instances`   | Each member account (via StackSets)        | Read-only EC2, RDS, ElastiCache, Savings Plans, and Organizations metadata |
| `nops-cm-sharesave-role.yaml` | `nops-sharesave-mgt`       | Dedicated child account                    | Commitment purchasing, Cost Explorer, Organizations read                   |

***

## Step 1: Central Role

The central role can be deployed in **any account in your AWS Organization** — it does not have to be the payer (management) account. Many teams use the management account for convenience, but a dedicated member account works the same way.

<Info>
  You still need access to the **payer (management) account** (or a delegated StackSets administrator) for **Step 2** (child read role StackSets) and **Step 3** (payer read role).
</Info>

<Steps>
  <Step title="Open Enable CM in nOps">
    In [**Settings > Cloud Provider Integrations**](https://clara.nops.io/settings), open your AWS integration and choose **Enable CM**.
  </Step>

  <Step title="Enter management (payer) account ID">
    Enter your **AWS Organization management (payer) account ID** (12 digits). nOps uses this to identify your organization and to pre-fill StackSet defaults — it is not required to be the account where you deploy the central role.
  </Step>

  <Step title="Copy External ID (Central)">
    Copy the **External ID (Central)** from nOps. It is passed automatically when you open the central stack. Keep it for **Confirm Details** later.
  </Step>

  <Step title="Deploy central role (single stack)">
    Sign into the AWS account where you want the central role, then click **Deploy Central Role (CloudFormation)**. This opens the AWS CloudFormation console with the template pre-loaded.

    Review the stack parameters:

    * **NopsCMAssumerRoleArn** — pre-filled with the nOps bridge role ARN (no changes needed)
    * **ExternalId** — pre-filled with the External ID from nOps

    Acknowledge the IAM resource creation checkbox and click **Create stack**. Wait for **CREATE\_COMPLETE**.

    <Info>
      The central role `NopsCMCrossAccountAssume` has a single permission: `sts:AssumeRole` scoped to `arn:aws:iam::*:role/NopsCMReadEC2Instances`. It cannot access any other resources.
    </Info>

    <AccordionGroup>
      <Accordion title="Central role — trust policy">
        ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::861341088565:role/NopsCMCentralClientAccountAssume"
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                "StringEquals": {
                  "sts:ExternalId": "<external_id_from_nops>"
                }
              }
            }
          ]
        }
        ```
      </Accordion>

      <Accordion title="Central role — permissions policy (NopsCMAssumeChildRoles)">
        ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": "sts:AssumeRole",
              "Resource": "arn:aws:iam::*:role/NopsCMReadEC2Instances"
            }
          ]
        }
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Deploy child read role (StackSets)">
    Click **Deploy Child Role (CloudFormation StackSets)** to open the StackSets console. nOps copies the child role template URL to your clipboard — paste it into **Amazon S3 URL** in the StackSets wizard.

    Deploy to all member accounts in your organization (or specific OUs). The child read role is **read-only** — it can only describe existing instances and commitments.

    <AccordionGroup>
      <Accordion title="Child read role — trust policy">
        ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::<central-account-id>:role/NopsCMCrossAccountAssume"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        }
        ```
      </Accordion>

      <Accordion title="Child read role — permissions policy (NopsCMReadEC2Policy)">
        ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeReservedInstances",
                "savingsplans:DescribeSavingsPlans",
                "rds:DescribeDBInstances",
                "rds:DescribeReservedDBInstances",
                "elasticache:DescribeReservedCacheNodes",
                "organizations:ListAccounts"
              ],
              "Resource": "*"
            }
          ]
        }
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Deploy payer read role (single stack)">
    StackSets do **not** deploy to the payer (management) account by default. Click **Deploy Payer Read Role (CloudFormation)** to deploy the same `NopsCMReadEC2Instances` role directly in the payer account.

    This ensures nOps can also read commitment data from the management account itself, not just member accounts.
  </Step>

  <Step title="Paste Central and Read role ARNs">
    After all stacks complete:

    * **Central Role ARN** — e.g. `arn:aws:iam::<central-account-id>:role/NopsCMCrossAccountAssume` (from the account where you deployed Step 1)
    * **Read Role ARN** — e.g. `arn:aws:iam::<member-id>:role/NopsCMReadEC2Instances` (from any StackSet instance)
  </Step>

  <Step title="Continue">
    Click **Next** to move to **ShareSave Role**.
  </Step>
</Steps>

***

## Step 2: ShareSave Role

This step deploys the **ShareSave** purchasing role in a **dedicated child account** within your AWS Organization. This role grants nOps the permissions to purchase and manage commitments on your behalf.

<Info>
  Using a dedicated child account isolates purchase permissions from your payer account. Commitments purchased from any account in your organization automatically apply across all accounts via RI/SP sharing.
</Info>

<Steps>
  <Step title="Create or identify the dedicated account">
    Create a new child account in your AWS Organization (recommended name: **nops-cm-sharesave**) or use an existing dedicated account. Enter its **12-digit account ID** in the nOps wizard.
  </Step>

  <Step title="Deploy ShareSave role in the dedicated account">
    Sign into the **dedicated child account**, then click **Deploy ShareSave Role (CloudFormation)**.

    Review the stack parameters:

    * **NopsCrossAccountRoleArn** — pre-filled with the nOps bridge role ARN (no changes needed)
    * **ExternalId** — pre-filled with the ShareSave External ID from nOps

    Acknowledge the IAM resource creation checkbox and click **Create stack**. Wait for **CREATE\_COMPLETE**.

    <AccordionGroup>
      <Accordion title="ShareSave role — trust policy">
        ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::861341088565:role/CrossAccountSharesaveMgt"
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                "StringEquals": {
                  "sts:ExternalId": "<sharesave_external_id_from_nops>"
                }
              }
            }
          ]
        }
        ```
      </Accordion>

      <Accordion title="ShareSave role — AWS managed policies">
        The ShareSave role attaches five AWS managed policies:

        | Managed Policy                   | Purpose                                    |
        | -------------------------------- | ------------------------------------------ |
        | `AWSSavingsPlansFullAccess`      | Create, describe, and manage Savings Plans |
        | `AWSOrganizationsReadOnlyAccess` | List and describe organization accounts    |
        | `AWSCloudTrail_ReadOnlyAccess`   | Read CloudTrail event history for audit    |
        | `AWSSupportAccess`               | Create and view support cases              |
        | `ServiceQuotasFullAccess`        | View and request service quota increases   |
      </Accordion>

      <Accordion title="ShareSave role — inline policy (NopsSharesaveMgtPolicy)">
        ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "ec2:CreateTags",
                "ec2:DescribeReservedInstances",
                "ec2:DescribeReservedInstancesListings",
                "ec2:DescribeReservedInstancesModifications",
                "ec2:DescribeReservedInstancesOfferings",
                "ec2:ModifyReservedInstances",
                "ec2:PurchaseReservedInstancesOffering",
                "ec2:CreateReservedInstancesListing",
                "ec2:CancelReservedInstancesListing",
                "ec2:DeleteQueuedReservedInstances",
                "ec2:GetReservedInstancesExchangeQuote",
                "ec2:AcceptReservedInstancesExchangeQuote",
                "rds:DescribeReservedDBInstances",
                "rds:DescribeReservedDBInstancesOfferings",
                "rds:PurchaseReservedDBInstancesOffering",
                "elasticache:DescribeReservedCacheNodes",
                "elasticache:DescribeReservedCacheNodesOfferings",
                "elasticache:PurchaseReservedCacheNodesOffering",
                "savingsplans:ReturnSavingsPlan",
                "savingsplans:TagResource",
                "ce:*"
              ],
              "Resource": "*"
            }
          ]
        }
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Paste ShareSave Role ARN and external ID">
    After the stack completes, paste **ShareSave Role ARN** (expected form: `arn:aws:iam::<dedicated-account-id>:role/nops-sharesave-mgt`) and confirm **External ID (Sharesave)** matches what nOps shows.
  </Step>

  <Step title="Continue">
    Click **Next** for **Confirm Details**.
  </Step>
</Steps>

***

## Step 3: Confirm Details

Review and edit fields so they match what you deployed:

* **Central Role ARN** — `NopsCMCrossAccountAssume` in the account where you deployed the central role (any org account)
* **Read Role ARN** — `NopsCMReadEC2Instances` in a member account reached by your StackSet
* **ShareSave Role ARN** — `nops-sharesave-mgt` in the dedicated child account
* **Child Role Name** (optional) — defaults to **`NopsCMReadEC2Instances`** if unchanged
* **External ID (Central)** and **External ID (Sharesave)** — must both be set and **must not** be identical

Click **Save & Continue** to persist configuration before verification.

***

## Step 4: Verify Access

Click **Run Verification** (or advance with **Next** from the prior step, which triggers the same check).

nOps performs server-side checks that validate both role assumption chains and API-level permissions:

| Check                           | What it verifies                                                                                                                           |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Assume ShareSave role           | Bridge → `nops-sharesave-mgt` (with ShareSave external ID)                                                                                 |
| EC2 reserved instances read     | `ec2:DescribeReservedInstances` via ShareSave role                                                                                         |
| Savings Plans read              | `savingsplans:DescribeSavingsPlans` via ShareSave role                                                                                     |
| RDS reserved DB instances read  | `rds:DescribeReservedDBInstances` via ShareSave role                                                                                       |
| Organizations read *(optional)* | `organizations:ListAccounts` via ShareSave role — informational only; not required when the ShareSave role is in a dedicated child account |
| Assume central/child read role  | Bridge → `NopsCMCrossAccountAssume` → `NopsCMReadEC2Instances` (3-hop chain)                                                               |
| Child account EC2 RI read       | `ec2:DescribeReservedInstances` via child read role                                                                                        |

If any check fails, verify:

* **Trust policies** — correct nOps bridge role ARN in the `Principal`
* **External IDs** — match what nOps shows (central and ShareSave must differ)
* **StackSet deployment scope** — ensure all target accounts/OUs are included
* **Managed policies** — all five AWS managed policies attached to the ShareSave role

When all checks pass, Commitment Management is marked **enabled** for that integration.

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Check fails: Assume ShareSave role">
    * Verify you deployed `nops-cm-sharesave-role.yaml` in the **dedicated child account**
    * Confirm the `NopsCrossAccountRoleArn` parameter was left at the default value
    * Check that the `ExternalId` parameter matches the **ShareSave External ID** shown in nOps
    * Ensure the CloudFormation stack reached **CREATE\_COMPLETE** (not ROLLBACK)
  </Accordion>

  <Accordion title="Check fails: Assume central/child read role">
    * Verify `nops-cm-central-role.yaml` was deployed and note which account hosts `NopsCMCrossAccountAssume` (it does not have to be the payer account)
    * Confirm the **Central Role ARN** in nOps matches that account
    * Confirm the `ExternalId` parameter matches the **Central External ID** shown in nOps
    * Ensure the StackSet for `nops-cm-child-role.yaml` deployed successfully to the target member accounts
    * If testing with the payer account itself, ensure you also deployed the child read role directly in the payer account (StackSets skip the management account by default)
  </Accordion>

  <Accordion title="Verification passes but operations fail later">
    * Verification checks **read** permissions. If a purchase operation fails with `UnauthorizedOperation`, check that all five AWS managed policies are attached to the ShareSave role (especially `AWSSavingsPlansFullAccess`)
    * If you see `AccessDenied` on a specific service (e.g., RDS), confirm the inline policy `NopsSharesaveMgtPolicy` is present on the role
  </Accordion>
</AccordionGroup>

***

## Related guides

<CardGroup cols={2}>
  <Card title="AWS integration setup" icon="plug" href="/aws/integration-setup">
    Legacy CUR in S3 and the integration cross-account role for cost visibility.
  </Card>

  <Card title="Permissions & Resources" icon="shield-check" href="/aws/permissions-and-resources">
    Complete reference of all IAM roles, policies, and trust relationships for both Savings Analysis and Commitment Management.
  </Card>

  <Card title="Platform integrations" icon="plug" href="/platform/integrations">
    All cloud integrations and setup entry points.
  </Card>
</CardGroup>
