Generated banner for Setting Up Cloudwatch Observability
Generated logo for Setting Up Cloudwatch Observability

Setting Up Cloudwatch Observability

AWSOfficialPublished by AWS

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • Medium risk

From the author

Sets up CloudWatch observability for the first time - Omni (CloudWatch Application Observability) and classic CloudWatch. Omni: creating a Space or Domain; access grants (who has access, at what level), access profiles bounding alerts, integrations, agents; instrumenting an app or AI agent with the plain ADOT SDK so traces reach Omni (Python/Node/Java/.NET on EC2/ECS/EKS/Lambda), incl. no-image-rebuild, CoreCLR vars; ingesting Azure or Google Cloud telemetry via the CloudWatch agent (VM/AKS, GCE/GKE); connecting Slack or the AWS DevOps Agent to a Space; whether GitHub or a custom MCP tool server (HTTP/stdio) can connect. CloudWatch: onboarding a service to Application Signals: ADOT auto-instrumentation, amazon-cloudwatch-observability add-on, monitored service, ServiceEvents, CI/CD metadata, Terraform. For using what is set up - queries, dashboards, alarms, Omni alerts, X-Ray, synthetics, Dynamic Instrumentation, AI agent evaluation, detecting Omni vs classic - use aws-observability.
— the description by AWS

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides the end-to-end setup procedures for two distinct CloudWatch observability products: CloudWatch Application Observability (Omni) and classic CloudWatch Application Signals. It acts as a central routing hub, helping users identify the correct product based on their requirements and guiding them through the specific onboarding, instrumentation, and configuration steps for each. It covers resource creation, access management, and telemetry ingestion, while clearly delineating the boundaries between the two products to ensure correct implementation.

What it does

  • Routes setup requests to the correct product path based on user intent and environment.
  • Guides users through CloudWatch Omni Domain and Space creation, access grants, and profile configuration.
  • Provides instructions for instrumenting applications and AI agents with the ADOT SDK for Omni.
  • Details the onboarding process for classic CloudWatch Application Signals, including auto-instrumentation and add-ons.
  • Supports telemetry ingestion configuration for Azure and Google Cloud environments.
  • Manages integration setups for Slack and the AWS DevOps Agent.

When to use it

  • When you need to set up CloudWatch Application Observability (Omni) for the first time.
  • When you need to onboard a service to classic CloudWatch Application Signals.
  • When you are unsure which CloudWatch observability product is appropriate for your workload.
  • When you need to configure access grants, profiles, or integrations for an existing Space.
  • When you need to instrument an application or AI agent to export telemetry to CloudWatch.

Advantages

  • Prevents configuration conflicts by enforcing mutually exclusive setup paths for Omni and Application Signals.
  • Provides a structured, step-by-step sequence for complex resource hierarchies like Domains and Spaces.
  • Clarifies the distinction between setup tasks and day-to-day operational tasks.
  • Ensures correct principal resolution and permission scoping for access grants and profiles.

Usage examples

“How do I start setting up CloudWatch Application Observability?”
The agent will explain the setup order (Domain, Space, grants, telemetry) and direct you to the app-basics reference to begin.
“I need to onboard my EKS service to Application Signals.”
The agent will route you to the Application Signals onboarding guide and the specific EKS-language instrumentation steps.
“How do I give a team access to my CloudWatch Omni Space?”
The agent will guide you through resolving the principal and using the access-grants reference to configure the appropriate permission level.
“Can I connect my GitHub repository to CloudWatch Omni?”
The agent will clarify that Omni does not support GitHub integration and stop the setup process.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/aws/setting-up-cloudwatch-observability/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip setting-up-cloudwatch-observability.zip -d .agents/skills

Documentation by AWS

Setting Up CloudWatch Observability

Scope: First-time CloudWatch observability setup, for both products — a CloudWatch Application Observability (Omni) Space from creation through first traces flowing, and onboarding a service to classic CloudWatch Application Signals. For using what is already set up (queries, dashboards, alarms, Omni alerts, evaluations, live debugging), route to aws-observability.

Two products, two reference folders

This skill owns setup for two products that share the CloudWatch name but are separate services. The folder a reference lives in is the signal for which product it belongs to — the same convention aws-observability uses:

FolderProductWhat setup means there
references/cloudwatch-omni/CloudWatch Omni (Application / Agent Observability)Domain → Space → grants → telemetry in → plain ADOT SDK instrumentation. No add-on, no CloudWatch Agent application_signals config, no port 4316.
references/cloudwatch/Classic CloudWatchOnboarding a service to Application Signals: ADOT auto-instrumentation, the amazon-cloudwatch-observability EKS add-on, the CloudWatch Agent, monitored service, ServiceEvents, CI/CD git/deployment metadata, port 4316.

The two instrumentation paths are mutually exclusive on a given workload — the Omni path explicitly forbids the Application Signals env vars and the add-on, and vice versa. Decide the product first (Routing Rules 1–4 below), then stay inside that folder. Enabling one does not replace the other; an account may run both, on different services.

Works best with the AWS MCP server — enables running AWS CLI commands directly. All guidance also works with standard AWS CLI access (aws cloudwatchomni ... on the Omni path; aws eks, aws iam, and aws application-signals on the Application Signals path).

Concepts — Omni (references/cloudwatch-omni/)

These are Omni's resources. None of them exist on the Application Signals path — that one has no Domain, Space, grant, or Dataset; its unit is a monitored service, and access is plain IAM. Do not ask an Application Signals onboarding customer for a spaceId.

TermWhat it is
DomainThe identity boundary. Carries the authorization provider (IAM or Identity Center) and owns the endpoint URL customers reach Omni through. One per account, or one shared across an AWS Organization.
SpaceA workspace holding telemetry, in exactly one account and one Region. Created under a Domain. At most one per account per Region. Region rule: under an IAM-only Domain a Space may sit in a Region other than the Domain's; under an account-scoped Identity Center Domain the Space must be in the Domain's own Region; under an org-scoped Identity Center Domain it must be in a Region the instance is replicated to.
Access grantAttaches a principal — person, group, IAM identity, or async workload — to one Space at a permission level. The only way anyone reaches data through a Space — it does not restrict the source CloudWatch log groups, which stay readable under their own IAM.
Access ProfileA named boundary for async workloads (alerts, integrations, agents) that act without a person in the loop. It is only a named container: create-access-profile takes a Space, a name, and a description and nothing else — no permission, action, or scope input. It does something only once two separate sets of grants exist (what the profile may do; which workloads may assume it) and a workload names it.
DatasetWhat queries run against. Telemetry arrives through the CloudWatch OTLP endpoints, or by forwarding what is already in CloudWatch log groups.

Omni setup order from nothing: Domain → Space → grants → telemetry in → instrumentation. (The Application Signals equivalent is much shorter and has no prerequisite resources — add-on/agent, IAM, then the per-platform enablement change; see references/cloudwatch/application-signals-onboarding.md.) "Telemetry in" (a collector exporting to CloudWatch's OTLP endpoints, plus dataset forwarding for what is already in CloudWatch) is its own step, separate from instrumenting the workloads. Access Profiles are conditional, not a step in the sequence — only when async workloads (alerts, integrations, agents) are involved. Whenever you give this sequence, also say that instrumentation or forwarding started before a Space exists appears to succeed while delivering telemetry nowhere the customer can see — a customer who checks Omni first reads a working, empty Space as a failure. For the concept relationships and the full arc, see references/cloudwatch-omni/app-basics.md.

This is a routing skill. Classify the user's setup request and delegate to the correct reference. Omni references live under references/cloudwatch-omni/; classic-CloudWatch (Application Signals) references live under references/cloudwatch/.

User intentReference
Onboard a service to Application Signals (auto-instrumentation, the amazon-cloudwatch-observability EKS add-on, CloudWatch Agent IAM for Application Signals, monitored service, reporting telemetry to Application Signals, ServiceEvents, the two onboarding tiers)references/cloudwatch/application-signals-onboarding.md
Propagate ServiceEvents git/deployment metadata through CI/CD (the 5 OTEL_AWS_SERVICE_EVENTS_* vars, per-provider patterns)references/cloudwatch/application-signals-cicd-metadata.md
Per-platform × per-language Application Signals enablement steps once platform and language are knownThe matching references/cloudwatch/appsignals-guides/<platform>-<language>.md (e.g. references/cloudwatch/appsignals-guides/eks-python.md)
Turn on Dynamic Instrumentation for a service at onboarding time (the OTEL_AWS_DYNAMIC_INSTRUMENTATION_* vars and their IAM)references/cloudwatch/application-signals-onboarding.md (Step 5d). Using it to debug is aws-observability
Understand what Omni is, its concepts, or where to startreferences/cloudwatch-omni/app-basics.md
Instrument an AI agent (ADOT, OpenInference, framework detection, trace verification), or deploy an agent to production and get traces flowing to CloudWatch — env vars per platform (AgentCore, Lambda, or other platforms such as ECS/EC2/EKS), routing spans to a custom trace log group, IAM permissions needed, how the export authenticates (AWS credentials, no API token), ADOT version requirementsreferences/cloudwatch-omni/omni-agents-instrumentation/omni-agents-instrumentation.md (§ Production deployment for the deploy case)
Per-framework OpenInference guide (LangChain, LangGraph, Strands, CrewAI, OpenAI Agents, Vercel AI) once the agent framework is knownreferences/cloudwatch-omni/omni-agents-instrumentation/openinference-framework-guide.md, then the matching references/cloudwatch-omni/omni-agents-instrumentation/instrument-<framework>.md
Instrument an application (ADOT SDK on EC2/ECS/EKS/Lambda — Python, Node.js, Java, .NET)references/cloudwatch-omni/instrumentation/instrumentation.md
Emit a custom application or agent metric so it is queryable in Omni (why OTLP and not PutMetricData/EMF)references/cloudwatch-omni/instrumentation/instrumentation.md (§ Custom metrics)
Create an account-scoped Space or Domainreferences/cloudwatch-omni/spaces-and-domains.md
Whether a Space can be in a different Region from its Domainreferences/cloudwatch-omni/spaces-and-domains.md (Prerequisites → Region rules)
The AgentCore evaluation role that create-space asks for — what it is, whether to create onereferences/cloudwatch-omni/spaces-and-domains.md (Step 3 → Also resolve the AgentCore evaluation role)
Let Omni run Bedrock models for a Space (Agent Playground, evaluations run from Omni), or a Bedrock AccessDeniedException from those featuresreferences/cloudwatch-omni/spaces-and-domains.md (Step 3 → Optional: let Omni invoke Bedrock models)
A Space that was created successfully but returns an authorization error when usedreferences/cloudwatch-omni/spaces-and-domains.md (Troubleshooting → If the Space was created but cannot be used) — a space access role trust-policy problem, not a grant problem
Create a Domain shared across an AWS Organizationreferences/cloudwatch-omni/org-domains.md
Configure access grants for people or IAM identities or alertsreferences/cloudwatch-omni/access-grants.md
An aws cloudwatchomni command reporting that the service is not supported, or a request to repair the customer's CLI or SDK so Omni commands workNot a setup task — a local client-version problem. STOP and route to aws-observability
A programmatic caller denied on a Space it already had working — a CI role, SDK client, CloudFormation role, coding agent, or a workload under an Access Profilereferences/cloudwatch-omni/access-grants.md (Grants, IAM, and Access Profiles), and aws-observability for the API-side view
Bound an alert, integration, or agent with an Access Profilereferences/cloudwatch-omni/access-profiles.md
Deploy an OTel Collector so an instrumented app has somewhere to export to (EC2/ECS/EKS) — it exports to CloudWatch's own per-signal OTLP endpointsreferences/cloudwatch-omni/instrumentation/collector.md
An OTLP collector already running (a CloudWatch Agent with an opentelemetry section or OTLP on 4317/4318, or otelcol-contrib) whose telemetry does not arrive, in whole or for one signal such as tracesreferences/cloudwatch-omni/instrumentation/collector.md (Verify), then the platform collector guide it links for the troubleshooting table
Enable Transaction Search so traces reach a Space (spans land in aws/spans only once it is on — per account, per Region)references/cloudwatch-omni/instrumentation/collector.md (Step 1)
Forward telemetry already in CloudWatch into the Datasetreferences/cloudwatch-omni/data-forwarding-and-centralization.md
Send your application's own telemetry from Azure (the logs/metrics/traces your service emits, via the CloudWatch agent on an Azure VM/AKS)references/cloudwatch-omni/azure-ingestion/azure-ingestion.md (intent triage), then references/cloudwatch-omni/azure-ingestion/custom-telemetry.md (the CloudWatch-agent-on-VM/AKS procedure)
Send your application's own telemetry from Google Cloud (the logs/metrics/traces your service emits, via the CloudWatch agent on a GCE instance/GKE cluster)references/cloudwatch-omni/gcp-ingestion/gcp-ingestion.md (intent triage), then references/cloudwatch-omni/gcp-ingestion/custom-telemetry.md (the CloudWatch-agent-on-GCE/GKE procedure)
Connect Slack to a Space for the first timereferences/cloudwatch-omni/slack-integration.md
Connect the AWS DevOps Agent to a Space (Settings → Integrations → AWS DevOps Agent), an empty agent-space picker, or Investigations reporting the AWS DevOps Agent is not connectedreferences/cloudwatch-omni/devops-agent-integration.md. Creating the DevOps Agent space itself and running or chatting with investigations belong to the aws-agents-for-devsecops plugin
Whether a custom MCP tool server can be registered (Omni has none)references/cloudwatch-omni/custom-mcp-integration.md
Enable or configure CloudWatch Omni Intelligence for a Space — attach an optional customer-managed KMS key (put-intelligence-configuration), connect an intelligence integration (AWS_INTEGRATION, AWS_CONFIG_SLREC, EXTERNAL_AGENT), check current config, or troubleshoot enablement (404, AccessDenied, empty graph)references/cloudwatch-omni/intelligence-setup.md

Routing Rules

  1. If the user is asking what Omni is, what a Domain or Space or grant means, where to start, or the end-to-end order of steps from nothing — rather than asking to perform one setup step — route to references/cloudwatch-omni/app-basics.md and answer the sequence from its "Setup order" section (not from a single procedure file such as collector.md, which covers one step). It also carries the boundary against aws-observability. A question about one concept's rules — a Space's Region relative to its Domain, the roles create-space needs — belongs to the procedure file for that concept (spaces-and-domains.md), which the routing table names.

  2. If the request is about instrumenting an AI agent project (adding OTel to a framework such as LangChain, LangGraph, Strands, CrewAI, OpenAI Agents, or Vercel AI), it is Omni — route to references/cloudwatch-omni/omni-agents-instrumentation/omni-agents-instrumentation.md. There is no Application Signals path for an agent framework.

  3. If the request is about instrumenting a general application (a service on EC2, ECS, EKS, or Lambda in Python, Node.js, Java, or .NET — not an AI-agent framework), decide the product before opening any procedure file — the two paths are mutually exclusive on a workload:

    • Names Application Signals, ServiceEvents, a "monitored service", the service map, the amazon-cloudwatch-observability add-on, the CloudWatch Agent's application_signals configuration, or port 4316 → the CloudWatch path: references/cloudwatch/application-signals-onboarding.md, then the matching references/cloudwatch/appsignals-guides/<platform>-<language>.md.

    • Names Omni, Application Observability, a Space, a Domain, or a Dataset — or explicitly rules Application Signals out ("plain OTel", "no add-on", "no agent sidecar") → the Omni path: references/cloudwatch-omni/instrumentation/instrumentation.md.

    • Naming the CloudWatch Agent alone decides nothing: it is also the Omni path's default collector. An agent with an opentelemetry section or OTLP receivers on 4317/4318 is the Omni collector, and its delivery problems belong to rule 6.

    • Names neither → rule 4.

  4. If an instrumentation, ADOT, or collector request names neither product (neither Omni or a Space, nor Application Signals, ServiceEvents, or the amazon-cloudwatch-observability add-on), probe for a Space in the target Region before choosing. list-spaces is account-global: the --region flag only selects the endpoint, and the response lists every Space in the account, each with its own region, so filter to the target Region rather than trusting a non-empty list: aws cloudwatchomni list-spaces --region <region> --query "items[?region=='<region>']". A Space in that Region → the Omni path, references/cloudwatch-omni/instrumentation/instrumentation.md. An empty filtered list → the customer has not adopted Omni in that Region, so Application Signals is the live product for them: references/cloudwatch/application-signals-onboarding.md. Either way the request stays in this skill — the probe picks the folder, not the skill. If the probe errors with an unknown service, that is the CLI model, not evidence Omni is absent — fall back to the customer's wording and ask only if still inconclusive.

  5. If the request is about Space/Domain creation or configuration, route to the matching setup reference. An authorization error that appears the moment a just-created Space is used is part of this — it is a space access role trust-policy problem (create-space never verifies the role can be assumed), so route to references/cloudwatch-omni/spaces-and-domains.md → "If the Space was created but cannot be used", not to the access-grants reference.

  6. If the user asks about getting telemetry to a destination — telemetry not yet reaching CloudWatch — deploy an OTel Collector on EC2/ECS/EKS so an instrumented workload has somewhere to send OTLP, and wire the app's OTEL_EXPORTER_OTLP_ENDPOINT to it: references/cloudwatch-omni/instrumentation/collector.md. The same file covers an OTLP collector that is already deployed but whose telemetry does not arrive, in whole or for one signal (its Verify section and the platform guide's troubleshooting table). The collector exports straight to CloudWatch's own per-signal OTLP endpoints. If instead the telemetry is already in CloudWatch log groups and needs forwarding into the Dataset, route to references/cloudwatch-omni/data-forwarding-and-centralization.md. Both the collector's OTLP export and CloudWatch's OTLP endpoints authenticate with SigV4 (AWS credentials), including OIDC-federated credentials for a workload outside AWS (see references/cloudwatch-omni/azure-ingestion/custom-telemetry.md or references/cloudwatch-omni/gcp-ingestion/custom-telemetry.md). A purely token-based ingestion path for a sender that cannot obtain AWS credentials at all is not covered by these skills; do not improvise one, and say so plainly.

  7. If the request is about getting Azure or Google Cloud telemetry into CloudWatch, route by cloud — references/cloudwatch-omni/azure-ingestion/azure-ingestion.md for Azure, references/cloudwatch-omni/gcp-ingestion/gcp-ingestion.md for Google Cloud — and decide by intent. If the customer wants the telemetry their own application produces (the logs/metrics/traces from their code), that is supported via the CloudWatch agent on an Azure VM or AKS cluster, or on a GCE instance or GKE cluster — follow the reference. If they want telemetry their cloud's resources emit on their own (the equivalent of AWS VPC flow logs / Route 53 logs: Azure resource and platform logs, or Google Cloud Audit Logs), that is not supported — say so and do not attempt a setup. If the request names no cloud, ask which one before giving any steps.

  8. If the user asks to connect, enable, or authorize Slack for a Space for the first time (including granting the operator permission to use it), route to references/cloudwatch-omni/slack-integration.md. Using Slack after it is connected (posting findings to a channel, mentioning the assistant, or searching Slack) happens in Slack and the console and is not covered by these skills; Slack as an alert notification target is covered by aws-observability's Omni alerts reference.

  9. Application Signals, ServiceEvents, and Dynamic Instrumentation are CloudWatch features, and they split by setup versus use — not by skill. Enabling them on a service that does not have them yet is setup and belongs here, under references/cloudwatch/: Application Signals onboarding and ServiceEvents in references/cloudwatch/application-signals-onboarding.md (with the CI/CD metadata chain in references/cloudwatch/application-signals-cicd-metadata.md), and switching Dynamic Instrumentation on at instrumentation time in that same file's Step 5d. They must never appear in an Omni instrumentation change — for that they remain out of scope, and rule 3 is how you tell the two paths apart. Using them once the service reports — reading the service map, alarming on Application Signals metrics, or placing breakpoints and reading snapshots with Dynamic Instrumentation — is day-to-day work: STOP and route to aws-observability.

  10. If the user already has a working Space, or a service already reporting to Application Signals, and is asking about queries/dashboards/alarms/alerts/investigation, STOP and route to aws-observability.

  11. If the user asks to register their own MCP tool server, connect a custom MCP server, or set up MCP authentication: CloudWatch Omni does not let customers add a custom MCP server. There is no console screen for it and the integration type is not enabled for customer use, so the attempt is refused. Say so plainly and stop; do not describe a setup flow, and do not offer a substitute. See references/cloudwatch-omni/custom-mcp-integration.md.

  12. If the user asks to connect GitHub, link a GitHub organization or repositories, or enrich the application map from source code: CloudWatch Omni has no GitHub integration. Say so plainly and stop — do not walk through a setup. Do not offer a substitute: the Application Signals GitHub Action and the CloudWatch Logs GitHub audit-log source are separate CloudWatch features, not a way to connect GitHub to Omni, and a custom MCP server is not a GitHub integration. A GitHub-related feature found in public documentation is not evidence of an Omni GitHub integration.

  13. If the user asks to enable or configure CloudWatch Omni Intelligence — attach or remove a customer-managed KMS key for intelligence data, add an intelligence integration (AWS_INTEGRATION, AWS_CONFIG_SLREC, or EXTERNAL_AGENT), read the current intelligence configuration, or troubleshoot why it will not turn on (a 404 UnknownOperationException, an AccessDeniedException, or an empty context graph) — route to references/cloudwatch-omni/intelligence-setup.md. That reference is the source of truth for the KMS ARN rules (full key ARN only, kms:Decrypt/kms:GenerateDataKey, exactly one of --kms-key-arn/--remove-kms-key, and that revoking the key makes intelligence data unrecoverable), the per-integration extra IAM, the two AccessDenied causes, and why "not enabled" is a 404 rather than an AccessDenied. Reading or interpreting the intelligence data once it is on is day-to-day use: STOP and route to the aws-observability skill — triaging insights, observations, or anomalies goes to its intelligence.md reference, which covers the ListInsights / ListObservations / GetContextGraph operations and the 404-vs-403-vs-local error rule; a pure topology or blast-radius question goes to its context-graph.md reference. For Slack specifically, route to references/cloudwatch-omni/slack-integration.md; for a custom MCP server, route to references/cloudwatch-omni/custom-mcp-integration.md (not supported). Do not offer GitHub, PagerDuty, Teams, MODEL_PROVIDER, or CUSTOM_MCP as intelligence integration types.

  14. If the request names neither product — "add observability to my API", "how should I begin monitoring my workload", with no mention of Omni, a Space, a Domain, or of a CloudWatch feature — do not assume either one. Which product a customer wants to set up is their intent, not something the account's current state tells you, so ask, framed product versus product: CloudWatch Omni (Application/Agent Observability — Domains, Spaces, grants, a Dataset) or CloudWatch (log groups, alarms, Log Insights, Application Signals). Both answers are served here, from different reference folders, so this is a question about which product to set up — not about which skill to use, and not a reason to hand the request to aws-observability. In the same message, explain the boundary so they can choose — it is setup versus use: creating or configuring a Domain, Space, grant, or Access Profile, getting telemetry flowing for the first time, instrumenting an application or agent for Omni, and onboarding a service to Application Signals are all first-time setup and belong here; querying telemetry, building dashboards, configuring alarms or Omni alerts, investigating a live problem, and debugging with Dynamic Instrumentation are day-to-day use and belong to aws-observability. Do not start walking through Domain/Space creation or Application Signals onboarding until they confirm which product; having asked, stop and wait.

  15. If the user asks to connect the AWS DevOps Agent to a Space, or the connect card or Investigations shows it is not connected, route to references/cloudwatch-omni/devops-agent-integration.md. These skills cover only that Omni-side connection. Creating or configuring the DevOps Agent space, and running, following, or chatting with its investigations from a coding agent, belong to the agent's dedicated aws-agents-for-devsecops plugin; point the customer there rather than reconstructing that workflow.

Files

references/cloudwatch-omni/spaces-and-domains.md

Setting up a Domain and a Space

A Domain is the identity boundary: it carries the authorization provider and owns the endpoint customers reach Omni through. A Space is the workspace that holds telemetry and runs inside one account and Region. Setup is always Domain first, then Space, because the Space is created against a domain ID.

Always state these, in any answer drawn from this file: the quotas (one Domain per account, one Space per account per Region); that the domain name becomes the endpoint URL; that create-space never verifies the role can be assumed; and, before any delete, that deleting a Space is destructive and needs the customer's confirmation.

Two questions this file answers in full, each with every item below:

  • Can a Space be in a different Region from its Domain? — depends on the Domain's provider: yes under an IAM-only Domain; no under an Identity Center Domain, whose Spaces must be in the Domain's own Region; Identity Center plus Spaces in several Regions is what the org-scoped Domain is for. Never a bare "yes".

  • The Space was created successfully but fails with an authorization error the moment it is used. — create-space checked only that the role ARN was present and in the caller's account, never that the role can be assumed, so a wrong trust policy is accepted at create time; check the space access role's trust policy for the cloudwatch.amazonaws.com principal, all three of sts:AssumeRole, sts:TagSession, and sts:SetContext (assume-role alone is accepted and fails in use), and both confused-deputy conditions — aws:SourceAccount equal to the account, aws:SourceArn matching the cloudwatch space/ resource with Region and space ID wildcarded, because the space ID does not exist when the role is created; a successful create is not proof the role is right, so read the Space back with get-space to verify; and recreating the Space is not the first remedy — a new Space with the same role fails the same way.

Contents

  • Which path

  • What you get when setup completes

  • Prerequisites

  • Step 1 — Interview the customer first

  • Step 2 — Create the Domain

  • Step 3 — Create the space access role

  • Step 4 — Create the Space

  • Verifying the setup

  • Cleanup

  • Troubleshooting

  • Security considerations

  • Additional resources

Which path

Two decisions change which operations you call. Settle both before touching anything.

Who owns the Domain:

The customer wantsPath
A Domain for a single accountAccount-scoped — create-domain, this file
A Domain shared across an AWS OrganizationOrg-scoped — create-domain-for-organization, management account only. See references/cloudwatch-omni/org-domains.md

Which authorization provider:

The customer authenticates withidentityProvidersExtra setup
IAM identities only["IAM"]None
IAM Identity Center["IAM", "IDC"]An Identity Center instance ARN, and the Domain MUST be created in that instance's primary Region

Constraints:

  • You MUST establish account-scoped versus org-scoped before calling anything. An org customer who gets an account-scoped Domain has to delete it and start over, and an account Domain blocks the org Domain from being created.

  • You MUST NOT mix the two operation families. create-domain and create-domain-for-organization produce different Domains with different deletion operations.

What you get when setup completes

  • A domain ID shaped d- followed by up to 25 lowercase alphanumerics, a domain ARN, and a domain endpoint URL. The endpoint URL derives from the domain name, which is why the name is not cosmetic.

  • A space ID (a UUID), a space ARN, and the Space's Region.

Quotas to state up front:

  • One Domain per account. A second create-domain conflicts.

  • One Space per account per Region. A second Space in the same Region conflicts; a Space in a different Region is a different Space.

Constraints:

  • You MUST tell the customer the domain name becomes part of the endpoint URL before they choose it.

  • You MUST state both quotas explicitly in any setup plan or answer you give — one Domain per account, and one Space per account per Region. Naming them is not optional detail: a customer who expects several Spaces in one Region will read the resulting conflict as a failure.

Prerequisites

  • The AWS Region, confirmed with the customer rather than inferred.

  • For an Identity Center Domain, the instance ARN and its primary Region. The Domain must be created in that Region.

  • iam:PassRole on the space access role, for whoever creates the Space. Without it the create fails after the role already exists.

Region rules differ by provider, and the difference matters:

  • An IAM-only Domain supports Spaces in Regions other than the Domain's.

  • An Identity Center Domain requires the Space in the same Region as the Domain. This is not relaxable, and replicating the Identity Center instance to more Regions does not relax it: for an account-scoped Domain, create-space compares the Space's Region with the Domain's and never consults replication.

  • If the customer needs Identity Center and Spaces in more than one Region, the org-scoped Domain is the way to do it: it accepts a Space in any Region the Identity Center instance is replicated to — see references/cloudwatch-omni/org-domains.md.

  • The two rejections read differently. An account-scoped Domain's names the Domain's Region. One saying Identity Center is not replicated to the Region comes from an org-scoped Domain, where replication is the rule: answer it from references/cloudwatch-omni/org-domains.md (Region rules), not with the account-scoped options below.

Never answer "yes, Spaces can be in other Regions" without naming which provider that holds for. It is true for IAM-only and false for account-scoped Identity Center.

When an account-scoped Identity Center customer asks for a Space outside the Domain's Region, say it cannot be done under that Domain and lay out all three options, each with its cost. Lead with the first, the only one that keeps the Domain they already have:

  1. A Space in the Domain's own Region, under the Domain they already have.

  2. An org-scoped Domain. The account-scoped Domain blocks creating one, so it has to be deleted first, along with its Spaces and their telemetry. That is the customer's decision: present it as a trade-off, not as a step to carry out.

  3. An IAM-only Domain, which allows Spaces in other Regions but gives up Identity Center sign-in.

Stop at the options. Do not write out the deletion or migration steps for option 2 until the customer has chosen it: those steps destroy the existing Domain's Spaces.

Constraints:

  • You MUST NOT promise a cross-Region Space under an account-scoped Identity Center Domain. If the customer needs Identity Center together with Spaces in more than one Region, the org-scoped Domain path supports that — see references/cloudwatch-omni/org-domains.md.

Operations you will call

Every operation is an aws <service> <operation> CLI command — the service name in kebab-case, the operation in kebab-case, and each input-shape member passed as a --kebab-key flag. Run it through the aws___call_aws tool when that tool is available; otherwise run the same command in a shell. Policy documents appear below as standalone JSON blocks — pass each as the corresponding flag value (--assume-role-policy-document).

aws cloudwatchomni operations:

IntentCommand
Check whether a Domain already existsaws cloudwatchomni list-domains
Create the Domainaws cloudwatchomni create-domain
Read the Domain backaws cloudwatchomni get-domain
Check whether a Space already existsaws cloudwatchomni list-spaces
Create the Spaceaws cloudwatchomni create-space
Read the Space backaws cloudwatchomni get-space
Delete the Spaceaws cloudwatchomni delete-space
Delete the Domainaws cloudwatchomni delete-domain

aws iam operations:

IntentCommand
Create the space access roleaws iam create-role
Attach a managed policyaws iam attach-role-policy
Detach a managed policyaws iam detach-role-policy
Delete the roleaws iam delete-role

aws sso-admin operations:

IntentCommand
Find the customer's Identity Center instancesaws sso-admin list-instances

aws sts operations:

IntentCommand
Confirm the calling identityaws sts get-caller-identity

Report the caller identity before starting:

aws sts get-caller-identity

Step 1 — Interview the customer first

Ask these in one message and wait for answers. Do not ask piecemeal, and do not default silently.

  1. Region?

  2. Domain name? It becomes part of the endpoint URL. Lowercase letters, digits, and single hyphens between them; 3–63 characters.

  3. Authorization provider — IAM, Identity Center, or both?

  4. If Identity Center: the instance ARN, and confirmation that the Region from question 1 is that instance's primary Region.

  5. Space name? Same character rules as the domain name; 3–64 characters.

  6. Space access role — should the agent create a new role with the correct trust policy and managed policy, or will the customer supply an existing role ARN? Recommend creating one.

  7. AgentCore evaluation role ARN? create-space requires this as well as the space access role, and the agent cannot create it. Ask for an existing ARN, or offer to look for a reusable one — see Step 3.

  8. Encryption — service-owned, or a customer managed KMS key? If a customer managed key, the key ARN. It must be a symmetric ENCRYPT_DECRYPT key in the caller's account and Region, and its key policy must allow cloudwatch.amazonaws.com to perform kms:Decrypt and kms:GenerateDataKey.

Confirm the choices back in one line, then execute.

If the customer does not know their Identity Center instance ARN, look it up for them rather than sending them away to find it:

aws sso-admin list-instances

Each entry carries the instance ARN and its identity store ID. The public reference for this operation is sso-admin list-instances.

Constraints:

  • You SHOULD recommend creating the role rather than reusing one. The Space cannot function correctly unless the role's trust policy and permissions are right, and a purpose-built role is easier to verify and to clean up.

  • You MUST confirm the key policy grants both KMS actions before offering customer managed encryption. A key the service cannot use produces a Space that cannot write.

Step 2 — Create the Domain

Check whether a Domain already exists first

One Domain per account. A second create-domain in the same account conflicts, so check before creating and tell the customer the limit.

aws cloudwatchomni list-domains

If a Domain comes back, do NOT create another. Report the existing Domain to the customer — its name and ID from the summary, and its endpoint URL from get-domain --domain-id <id> (summaries do not carry it) — and confirm they want to use it. On confirmation, take its domainId and continue from Step 3.

Constraints:

  • You MUST run this check before create-domain.

  • You MUST state the one-Domain-per-account limit to the customer as part of this step, not only when the check finds one. A customer who does not know the limit reads the resulting conflict as a failure.

  • You MUST confirm with the customer before reusing an existing Domain. It may belong to someone else in the account, and its authorization provider may not be the one they asked for.

  • If the check cannot be completed — access denied, or an ambiguous response — you MUST treat the result as inconclusive, not negative. Report that and stop. You MUST NOT create a Domain on that basis.

Create it

For an IAM-only Domain there is no extra configuration:

aws cloudwatchomni create-domain --name <domain-name> --identity-providers IAM

For an Identity Center Domain, identityProviderConfiguration becomes required and carries the instance ARN. The Domain must be created in the instance's primary Region, which the service verifies:

aws cloudwatchomni create-domain --name <domain-name> --identity-providers IAM IDC --identity-provider-configuration '{"identityCenterConfiguration": {"identityCenterInstanceArn": "<idc-instance-arn>"}}'

If the customer does not have the Identity Center instance ARN to hand, do not leave <idc-instance-arn> as a placeholder for them to fill — offer to look it up with list-instances on sso-admin (see Step 1), which returns each instance's ARN and identity store ID.

Capture domainId, domainArn, and domainEndpointUrl from the domain object in the response. domainId is the input to create-space in Step 4.

Constraints:

  • You MUST create an Identity Center Domain in the instance's primary Region. Creating it elsewhere is rejected, and the rejection describes the Region rather than the mistake.

  • identityProviders accepts one or two values from IAM and IDC, and they must be distinct. You MUST NOT send a repeated value.

  • You MUST capture domainEndpointUrl and give it to the customer. It is how they reach Omni, and it is not derivable from the domain name alone.

  • If the customer does not have the Identity Center instance ARN, You SHOULD offer to look it up with list-instances on sso-admin rather than leaving <idc-instance-arn> for them to resolve.

Step 3 — Create the space access role

Only if the customer chose "create a new role" in Step 1. If they supplied an existing role ARN, do NOT modify it — pass it straight through to Step 4 and, if the create fails, use the Troubleshooting table rather than editing their role.

This is the role the service assumes to operate on the Space.

Constraints:

  • You SHOULD run the list-spaces check from Step 4 before creating a role. If a Space already exists in the target Region, no role is needed, and creating one leaves an unused IAM role behind.

Create the role

Call create-role with AssumeRolePolicyDocument set to this trust policy. The aws:SourceAccount and aws:SourceArn conditions are confused-deputy protection — keep both.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudwatch.amazonaws.com"
      },
      "Action": ["sts:AssumeRole", "sts:TagSession", "sts:SetContext"],
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "<account-id>"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:cloudwatch:*:<account-id>:space/*"
        }
      }
    }
  ]
}
aws iam create-role --role-name <role-name> --assume-role-policy-document <trust-policy-json>

Constraints:

  • All three sts actions are required. sts:TagSession and sts:SetContext carry the session context the Space needs; a role trusted for sts:AssumeRole alone is accepted at create time and fails later when the Space is used.

  • The aws:SourceArn pattern MUST stay wildcarded across Region and space ID (space/*). The space ID does not exist yet when the role is created, so a narrower pattern cannot match.

  • You MUST create the role in the same account as the caller. create-space rejects a dataAccessRoleArn from another account.

Attach the managed policy

If the customer supplied the role rather than you creating it, ask before attaching anything to it — this policy or the optional one below — and change nothing else about it. They may be reusing it, and widening someone else's role is not yours to do.

Attach it with the IAM attach-role-policy operation. Do not write an inline policy instead, and do not substitute a *FullAccess policy — the Space's permissions are defined by this managed policy, plus the optional inference policy below when the customer needs it.

aws iam attach-role-policy --role-name <role-name> --policy-arn arn:aws:iam::aws:policy/CloudWatchOmniSpaceAccessPolicy

Constraints:

  • You MUST NOT substitute a *FullAccess policy or hand-write a broad inline policy. The Space's permissions are defined by this managed policy.

  • You MUST NOT attach either policy to a role the customer supplied without asking (the note at the top of this step).

Optional: let Omni invoke Bedrock models

CloudWatchOmniSpaceAccessPolicy deliberately grants no model inference, so a Space that only views telemetry cannot call Bedrock. Omni features that run a model through the space access role, such as Agent Playground and evaluations run from Omni, need the separate managed policy CloudWatchOmniModelInferencePolicy. It allows bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream on foundation models and inference profiles in the caller's own account, plus the matching Bedrock Mantle inference actions.

Ask whether the customer will use those features. Attach it only if they will:

aws iam attach-role-policy --role-name <role-name> --policy-arn arn:aws:iam::aws:policy/CloudWatchOmniModelInferencePolicy

Constraints:

  • You MUST NOT attach it by default. Every model call it permits is billed to the customer's account, so it is their choice, not part of the base setup.

  • A Bedrock AccessDeniedException from Agent Playground or an Omni-run evaluation on a Space set up without it is this policy missing, not a broken role. Offer to attach it rather than widening the base policy or adding an inline Bedrock grant.

Also resolve the AgentCore evaluation role

create-space requires a second role ARN, agentCoreEvaluationRoleArn, which is not the space access role and is not created here. Resolve it now rather than at the call:

  1. Reuse an existing role. List roles and offer any whose name starts with AgentCoreEvaluationRole or AgentCoreEvalRole, or whose trust policy principal is bedrock-agentcore.amazonaws.com. An account already running evaluations usually has one — show the matches and let the customer pick.

    aws iam list-roles
  2. Otherwise have the customer create one — the AgentCore Evaluations console ("Create and use a new service role") or the AgentCore CLI/SDK (auto_create_execution_role=True) — then use the ARN it returns.

Constraints:

  • You MUST have both role ARNs before calling create-space. Omitting either is rejected by the client before the request is sent.

  • You MUST NOT hardcode this role's IAM policy. The console and CLI build the authoritative policy on creation.

  • You MUST NOT attach the Space's managed policy to it. It is a different role with a different trust principal.

When the customer asks what this role is — typically because create-space just asked them for it mid-setup — answer with all of the following, because each one changes what they do next: it is a second, separate role from the space access role and is not created as part of Space setup; offer to reuse one first by listing roles and surfacing matches on the name prefixes or the bedrock-agentcore.amazonaws.com trust principal, so they can pick; otherwise they create it through the AgentCore Evaluations console's new-service-role option or the AgentCore CLI/SDK auto-create option and bring back the ARN; both role ARNs must be in hand before create-space, since omitting either is rejected by the client before any request is sent; you will not hand-write its IAM policy (the console and CLI build the authoritative one); and you will not attach the Space's managed policies to it, because it is a different role with a different trust principal.

Step 4 — Create the Space

Check whether a Space already exists first

One Space per account per Region. A second Space in the same Region conflicts; a Space in a different Region is a different Space. Check before creating, scope the check to the target Region, and tell the customer the limit.

aws cloudwatchomni list-spaces --domain-id <domain-id>

If a Space already exists in the target Region, do NOT create another. Report it to the customer — its name, ID, and Region — and confirm they want to use it.

Constraints:

  • You MUST run this check before create-space.

  • You MUST state the one-Space-per-account-per-Region limit to the customer as part of this step. It is what determines whether they need a Space in more than one Region.

  • A Space in a different Region is a different Space and does not conflict. You MUST compare Regions rather than treating any returned Space as a conflict.

  • If the check cannot be completed, you MUST treat the result as inconclusive, not negative, report that, and stop.

Create it

create-space takes TWO required role ARNs, not one. Alongside --data-access-role-arn it requires --agent-core-evaluation-role-arn. Both must be in the caller's account, and omitting either is rejected by the client before the request is sent. If you do not already have both from Step 1 and Step 3, resolve the AgentCore evaluation role there before calling.

aws cloudwatchomni create-space --name <space-name> --domain-id <domain-id> \
  --data-access-role-arn arn:aws:iam::<account-id>:role/<role-name> \
  --agent-core-evaluation-role-arn arn:aws:iam::<account-id>:role/<agentcore-eval-role-name>

--domain-id takes the Domain's ID only (d- followed by up to 25 base-36 characters); it does not accept the Domain's name or ARN. Passing a name or ARN fails with 400 ValidationException (domainId must match d-[0-9a-z]{1,25}). If you have a name or ARN, resolve it to the ID with list-domains first.

For customer managed encryption, add encryptionConfiguration:

"encryptionConfiguration": {"encryptionStrategy": "CUSTOMER_MANAGED", "kmsKeyArn": "<kms-key-arn>"}

Omit encryptionConfiguration entirely for service-owned encryption; that is equivalent to "encryptionStrategy": "AWS_OWNED".

The customer managed key's key policy must allow the service to use it. This statement belongs on the key, not on the space access role:

{
  "Effect": "Allow",
  "Principal": {
    "Service": "cloudwatch.amazonaws.com"
  },
  "Action": ["kms:Decrypt", "kms:GenerateDataKey"],
  "Resource": "*"
}

Capture spaceId, spaceArn, region, and status from the space object in the response.

A successful create does not mean the role works. create-space checks only that dataAccessRoleArn is present and in the caller's account — it never tries to assume it. A role with a wrong trust policy produces a Space that is created successfully and fails the moment anything uses it.

Constraints:

  • You MUST use encryptionConfiguration; it is the only create-time encryption input. create-space has no top-level kmsKeyArn member (the CLI has no --kms-key-arn flag). There is no top-level kmsKeyArn on read either: get-space always reports encryptionConfiguration, and list-spaces summaries carry no encryption fields at all.

  • A customer managed key MUST be a symmetric ENCRYPT_DECRYPT key in the caller's account and Region.

  • You MUST NOT author or modify the KMS key policy yourself. Show the customer the statement above and direct them to whoever administers the key.

  • create-space does not verify that the role can actually be assumed. It checks only that the ARN is present and in the caller's account, so a role with a wrong trust policy creates a Space that fails in use. You MUST NOT treat a successful create as proof the role is correct — verify per the next section.

Verifying the setup

Read both resources back rather than trusting the create responses:

aws cloudwatchomni get-domain --domain-id <domain-id>

aws cloudwatchomni get-space --space-id <space-id>

Confirm the Domain reports the expected endpoint URL, and the Space reports ACTIVE in the expected Region with the role ARN you passed.

Then report to the customer, in one line: the domain endpoint URL, the space ID, the space ARN, and the Region.

Constraints:

  • You MUST NOT begin dependent setup — such as telemetry forwarding — until the Space reports ACTIVE.

Cleanup

Before any delete step, in every answer from this section: say plainly that deleting a Space destroys its telemetry and the deletion cannot be undone, and ask the customer to confirm before you run anything. State this first, ahead of the ordering and the API details — an answer that gets the order right but never warns the customer is wrong.

Confirm with the customer before running anything in this section. Deleting a Space is destructive and its telemetry goes with it.

Order matters. Delete the Space first.

  1. Confirm first, then delete the Space. Deleting a Space is destructive: the Space's telemetry goes with it and cannot be recovered. Get the customer's explicit confirmation before running this call.

    aws cloudwatchomni delete-space --space-id <space-id>
  2. Delete the Domain. This fails while any Space still exists under it:

    aws cloudwatchomni delete-domain --domain-id <domain-id>
  3. The space access role — branch on who created it:

    • The agent created it in Step 3: detach the managed policy with detach-role-policy, then delete-role. A role with a policy attached cannot be deleted.

    • The customer supplied it: do NOT delete or modify it. Tell them the Space is gone and the role is untouched.

Constraints:

  • You MUST delete Spaces before the Domain. delete-domain returns a conflict naming the number of remaining Spaces, and the fix is always to delete those first — never to retry the Domain delete.

  • Deleting a Space is destructive. You MUST confirm with the customer first and say plainly that the Space's telemetry goes with it.

  • You MUST NOT poll get-space after delete-space to confirm removal. Once delete returns success the Space is gone, and a follow-up read can fail in ways that look like the delete did not work.

Troubleshooting

Rule: When a call returns an error, surface the error code and message verbatim, then map to the mitigation below. Do NOT invent error text, do NOT paraphrase what the service returned, and do NOT synthesize a mitigation for an error that is not listed.

Error signalCauseMitigation to surface
ConflictException on create-domainA Domain already exists in this account, or an org Domain covers itRead it with list-domains, confirm with the customer, and continue from Step 3. Do NOT retry the create
ConflictException on create-spaceA Space already exists in this account and RegionRead it with list-spaces and compare Regions. A different Region is a different Space
ValidationException naming the Region on create-domainIdentity Center Domain not being created in the instance's primary RegionAsk the customer for the instance's primary Region and create the Domain there. list-instances on sso-admin shows the instances they can reach
ValidationException on create-space naming the Domain's RegionSpace Region differs from the Domain's, and the Domain uses Identity CenterCreate the Space in the Domain's Region. If the customer needs Identity Center across several Regions, the org-scoped Domain path supports that
ValidationException that dataAccessRoleArn must be in the caller's accountRole ARN belongs to a different accountAsk the customer for a role in this account; do NOT attempt a cross-account role
AccessDeniedException naming bedrock:InvokeModel (or a bedrock-mantle action) from Agent Playground or an Omni-run evaluationThe space access role has no model-inference permission; CloudWatchOmniSpaceAccessPolicy grants noneAsk whether the customer wants Omni to run models, and if so attach CloudWatchOmniModelInferencePolicy to the space access role (see Step 3). Do NOT add an inline Bedrock grant
ParamValidationError naming a missing required parameter on create-spaceagentCoreEvaluationRoleArn (or dataAccessRoleArn) was omitted — both are required and the client rejects the call before sendingResolve the AgentCore evaluation role as described in Step 4 and pass both ARNs
ValidationException on encryptionConfigurationencryptionStrategy and kmsKeyArn inside encryptionConfiguration do not agreeSend the key ARN nested inside encryptionConfiguration only with encryptionStrategy CUSTOMER_MANAGED; omit the block entirely for AWS_OWNED
AccessDeniedException naming iam:PassRoleCaller may create the Space but cannot pass the roleAsk the customer to add iam:PassRole on that specific role ARN to their calling identity
AccessDeniedException on the operation itselfCaller lacks cloudwatch:CreateDomain or cloudwatch:CreateSpaceAsk the customer to add the specific action to their calling role
ResourceNotFoundException on create-spacedomainId typo, or the Domain is in another account or RegionRe-read the Domain with list-domains and use the exact domainId
ConflictException on delete-domain naming remaining SpacesSpaces still exist under the DomainDelete every Space first, then retry. Do NOT retry the Domain delete on its own

If the error does not match a row above, quote it verbatim, say it is unmapped, and ask the customer how to proceed.

If the Space was created but cannot be used

An authorization error after a successful create-space almost always means the space access role's trust policy is wrong, not that access is missing. The exception is a denial naming bedrock:InvokeModel or a bedrock-mantle action from Agent Playground or an Omni-run evaluation, on a Space that otherwise works: that is the optional model-inference policy missing, not the trust policy. See Step 3 (Optional: let Omni invoke Bedrock models).

create-space validates only that dataAccessRoleArn is non-blank and in the caller's account. It never attempts to assume the role, so a role missing sts:TagSession or sts:SetContext, naming the wrong service principal, or carrying condition keys that do not match is accepted at create time and fails in use. Note the asymmetry: the organization path does verify its role by performing a real sts:AssumeRole at create time, so a reader who did that flow first will reasonably expect this one to validate too.

Telling this apart from a missing grant is a matter of timing:

  • The Space was created and then failed in use — suspect the role's trust policy. Check the service principal, all three sts actions, and both condition keys.

  • Nobody could ever reach the Space, from the start, for everyone — suspect missing access grants. See references/cloudwatch-omni/access-grants.md.

You MUST check the trust policy before proposing new grants. Creating a grant to fix a trust-policy problem leaves the customer with the same error and two things to unwind.

What to check on the space access role, against the trust policy in Step 3:

  1. The principal is the service, cloudwatch.amazonaws.com — not an account or a user.

  2. All three actions are allowed: sts:AssumeRole, sts:TagSession, and sts:SetContext. A role trusted for sts:AssumeRole alone is the classic case: accepted at create time, denied the first time the Space assumes it.

  3. Both confused-deputy conditions are present and match: aws:SourceAccount equal to the account, and aws:SourceArn matched with ArnLike against arn:aws:cloudwatch:*:<account-id>:space/* — Region and space ID wildcarded. A condition that spells out the space ID cannot have been right when the role was created, because the ID did not exist yet; a condition pinned to one Region breaks the moment a Space is created elsewhere.

Then read the Space back with get-space and confirm it reports ACTIVE with the role ARN you expect. A successful create-space response is not evidence the role is correct — the create never exercised it — so the read-back after the fix is the check.

Do not recreate the Space as the first remedy. The role is what is wrong; a new Space created with the same role fails the same way, and if telemetry has started arriving the delete is destructive. Fix the trust policy on the existing role instead.

Expectations that look like faults
  • create-space succeeded but using the Space fails with an authorization error. The create does not verify the role is assumable. Check the trust policy's principal, all three sts actions, and both condition keys.

  • Agent Playground or an Omni-run evaluation is denied bedrock:InvokeModel while the rest of the Space works. The base policy grants no model inference by design. The optional CloudWatchOmniModelInferencePolicy is missing; the role is not broken.

  • A Space encrypted with a customer managed key cannot write. The key policy does not allow cloudwatch.amazonaws.com the required KMS actions. Nothing about the Space or the role is wrong.

  • A second Space in the same Region conflicts. One Space per account per Region. This is the quota, not an error in the request.

Security considerations

  • Keep both aws:SourceAccount and aws:SourceArn conditions on the space access role's trust policy. They are the confused-deputy protection.

  • The aws:SourceArn wildcard covers Region and space ID because neither is known when the role is created. Do not widen it further — the account ID and the space/ resource type MUST stay pinned.

  • If the customer supplied the role, attach only the managed policies named in Step 3 (the base policy, plus the optional inference policy if they asked for it) and change nothing else about its existing permissions.

  • Do not attach *FullAccess policies to the space access role. Its permissions come from the Omni managed policy and nothing else.

  • A Space encrypted with a customer managed key needs the key policy to grant the service kms:Decrypt and kms:GenerateDataKey. Do not author or modify the key policy; if it needs changing, direct the customer to their key administrator.

  • Access to query a Space is granted separately through access grants and access profiles, so read access can be given without the ability to change the Space.

Additional resources

  • references/cloudwatch-omni/org-domains.md — Domains shared across an AWS Organization

  • references/cloudwatch-omni/instrumentation/collector.md — deploying a collector that exports to CloudWatch's OTLP endpoints, for telemetry not yet reaching CloudWatch

  • references/cloudwatch-omni/data-forwarding-and-centralization.md — forwarding telemetry that is already in CloudWatch log groups into the Dataset

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs Python

Security

What our scanner noticed· Medium risk

  • References to credential files
  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS
Publisher
AWS (Official)
Source
aws/agent-toolkit-for-aws · skills/specialized-skills/operations-skills/setting-up-cloudwatch-observability · commit 0a218f8
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS or AWS.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download setting-up-cloudwatch-observability.zip