diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index b2b09993..a4c0c381 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -20,7 +20,8 @@ tools-for-devops-agent/ ├── llms.txt # Structured repo overview for AI tools ├── .gitignore # Root-level ignores ├── cloudformation/ -│ └── devops-agent-skill-policies.yaml # IAM policies skills require +│ ├── devops-agent-skill-policies/ # IAM policies skills require +│ └── devops-agent-alarm-investigations/ # CloudWatch alarm → DevOps Agent webhook ├── docs/ # GitHub Pages (mkdocs) documentation site ├── skills/ │ ├── .gitignore # Allowlist for DevOps Agent supported extensions only @@ -200,7 +201,7 @@ Only these extensions are permitted inside **skill** directories (enforced by `s 6. Test the skill with DevOps Agent before submitting. 7. Update the root `README.md` skills table with the new skill's name, agent types, author, and docs link. 8. Update the `llms.txt` file at the repo root — add the new skill to the "Available Skills" section following the existing format: `- [Skill Name](skills//SKILL.md): One-line description`. -9. If the skill requires IAM permissions beyond the `AIDevOpsAgentAccessPolicy` managed policy, add a new parameter, condition, and inline policy resource to `cloudformation/devops-agent-skill-policies.yaml`, and update the `SkillPolicySummary` output. +9. If the skill requires IAM permissions beyond the `AIDevOpsAgentAccessPolicy` managed policy, add a new parameter, condition, and inline policy resource to `cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml`, and update the `SkillPolicySummary` output. ## Zipping for Upload diff --git a/.kiro/steering/project-conventions.md b/.kiro/steering/project-conventions.md index 443d1ece..143a5d45 100644 --- a/.kiro/steering/project-conventions.md +++ b/.kiro/steering/project-conventions.md @@ -20,7 +20,8 @@ tools-for-devops-agent/ ├── llms.txt # Structured repo overview for AI tools ├── .gitignore # Root-level ignores ├── cloudformation/ -│ └── devops-agent-skill-policies.yaml # IAM policies skills require +│ ├── devops-agent-skill-policies/ # IAM policies skills require +│ └── devops-agent-alarm-investigations/ # CloudWatch alarm → DevOps Agent webhook ├── docs/ # GitHub Pages (mkdocs) documentation site ├── skills/ │ ├── .gitignore # Allowlist for DevOps Agent supported extensions only @@ -199,7 +200,7 @@ Only these extensions are permitted inside **skill** directories (enforced by `s 6. Test the skill with DevOps Agent before submitting. 7. Update the root `README.md` skills table with the new skill's name, description, agent types, author, and docs link. 8. Update the `llms.txt` file at the repo root — add the new skill to the "Available Skills" section following the existing format: `- [Skill Name](skills//SKILL.md): One-line description`. -9. If the skill requires IAM permissions beyond the `AIDevOpsAgentAccessPolicy` managed policy, add a new parameter, condition, and inline policy resource to `cloudformation/devops-agent-skill-policies.yaml`, and update the `SkillPolicySummary` output. +9. If the skill requires IAM permissions beyond the `AIDevOpsAgentAccessPolicy` managed policy, add a new parameter, condition, and inline policy resource to `cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml`, and update the `SkillPolicySummary` output. ## Maintaining llms.txt diff --git a/README.md b/README.md index c85743ba..2284811a 100644 --- a/README.md +++ b/README.md @@ -46,13 +46,13 @@ Most permissions are already covered by the AWS managed policy [`AIDevOpsAgentAc ```bash aws cloudformation deploy \ - --template-file cloudformation/devops-agent-skill-policies.yaml \ + --template-file cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml \ --stack-name devops-agent-skill-policies \ --parameter-overrides ExistingRoleName= \ --capabilities CAPABILITY_NAMED_IAM ``` -The template supports enabling/disabling policies per skill, optional region restrictions, and can either attach to an existing role or create a new one. See [`cloudformation/devops-agent-skill-policies.yaml`](cloudformation/devops-agent-skill-policies.yaml) for details. +The template supports enabling/disabling policies per skill, optional region restrictions, and can either attach to an existing role or create a new one. See [`cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml`](cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml) for details. ## Contributing diff --git a/cloudformation/devops-agent-alarm-investigations/README.md b/cloudformation/devops-agent-alarm-investigations/README.md new file mode 100644 index 00000000..9223ed2a --- /dev/null +++ b/cloudformation/devops-agent-alarm-investigations/README.md @@ -0,0 +1,80 @@ +# DevOps Agent alarm investigations + +Forwards **one** Amazon CloudWatch alarm to an AWS DevOps Agent generic webhook, so the +alarm opens an investigation. **One stack = one alarm** — deploy it again per alarm. + +No Lambda and no code: an Amazon EventBridge rule scoped to the alarm ARN matches +`CloudWatch Alarm State Change` with `state.value = ALARM`, an input transformer builds +the incident payload, and an EventBridge API destination POSTs it. The API key lives in an +EventBridge connection, which sends it as `Authorization: Bearer `. An IAM role grants +the rule `events:InvokeApiDestination` on that one destination. + +The payload carries only the alarm ARN and the raised state — no alarm name, reason, or +metric data. DevOps Agent enriches from the ARN. + +## Before you deploy + +The webhook is created in the console (there is no `CreateWebhook` API) and its API key is +shown only once, so it must exist first: + +1. Create the Agent Space. +2. Console → **Capabilities → Agent Space Webhook → Generate webhook**, authentication type + **API key**. Copy the URL and the key — the key is not retrievable later. +3. Deploy this stack with that URL, that key, and the alarm ARN. + +Lost the key? Rotate the webhook from the Capabilities tab; rotation keeps the URL and +issues a new key. Update the stack afterwards — the connection re-reads the key only when +the stack is updated. + +## Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `WebhookUrl` | *(required)* | HTTPS URL of the generic webhook. | +| `WebhookApiKey` | *(required)* | The API key from webhook creation. `NoEcho`, so it is masked in stack events and `describe-stacks`. | +| `AlarmArn` | *(required)* | ARN of the single alarm to forward. | +| `InvocationRateLimitPerSecond` | `300` | Cap on webhook invocations per second — 300 is the per-destination quota, so the stack adds no throttling. Lower it only to deliberately rate-limit the webhook. | +| `DevOpsAgentAlarmIntegrationTag` | *(stack name)* | Value of the `DevOpsAgent` tag on the rule and role. Identification and cost allocation only; does not affect routing. | + +## Deploy + +```bash +aws cloudformation deploy \ + --template-file cloudformation/devops-agent-alarm-investigations/devops-agent-alarm-investigations.yaml \ + --stack-name devops-agent-alarm-investigations- \ + --capabilities CAPABILITY_IAM \ + --parameter-overrides \ + WebhookUrl="https://" \ + WebhookApiKey="" \ + AlarmArn="arn:aws:cloudwatch:::alarm:" +``` + +## Notes + +- **Cross-Region and cross-account alarms.** Deploy this stack once, in the DevOps Agent's + account and Region, and set `AlarmArn` to the alarm's real (possibly remote) ARN. Remote + alarms reach it via ordinary + [bus-to-bus forwarding](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cross-account.html): + a rule in the alarm's own Region/account targeting the agent Region's default bus, plus — + cross-account only — a resource policy on the agent bus allowing `PutEvents` from the + source account. The forwarded event still carries the alarm ARN in `resources`, so this + stack's rule matches it. +- **Region availability.** API destinations to public HTTPS endpoints are not available in + every Region — check + [API destinations as targets](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-api-destinations.html#eb-api-destination-regions). +- **Deduplication.** `incidentId` is the EventBridge event id, constant across retries, so + redeliveries reuse it instead of opening duplicates. Control flapping at the alarm's + datapoints-to-alarm setting. +- **Delivery.** Up to 32 retry attempts over 8 hours; API destinations require a response + within 5 seconds. `MaximumEventAgeInSeconds` stops retries once an event is older than + the window, so a late redelivery cannot open a stale investigation. +- **Monitoring.** There is no log group. The rule publishes `InvocationAttempts`, + `SuccessfulInvocationAttempts`, `RetryInvocationAttempts` and `FailedInvocations` in + `AWS/Events` by `RuleName`. Alarm on `FailedInvocations`; add a dead-letter queue to the + target to inspect events that never landed. +- **Keeping the key in your own secret.** Replace `ApiKeyValue` with + `'{{resolve:secretsmanager:MyWebhookSecret}}'` and drop the `WebhookApiKey` parameter, so + the key never passes through a stack parameter. Same rotation caveat as above. +- **API key versus HMAC.** The webhook also supports HMAC, but EventBridge connections + support only Basic, API key, and OAuth and cannot sign per request — HMAC would need a + signing Lambda in between. This template takes the API key path to stay code-free. diff --git a/cloudformation/devops-agent-alarm-investigations/devops-agent-alarm-investigations.yaml b/cloudformation/devops-agent-alarm-investigations/devops-agent-alarm-investigations.yaml new file mode 100644 index 00000000..80b53322 --- /dev/null +++ b/cloudformation/devops-agent-alarm-investigations/devops-agent-alarm-investigations.yaml @@ -0,0 +1,234 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: > + Forwards a single Amazon CloudWatch alarm to an AWS DevOps Agent webhook so that + alarm opens an investigation. One stack = one alarm: it creates an Amazon + EventBridge rule scoped to that alarm's ARN, an EventBridge connection holding the + webhook API key, an EventBridge API destination pointing at the webhook, and a role + that lets the rule invoke it. No AWS Lambda function is involved. + + Prerequisite: create the Agent Space and its generic webhook with API key + authentication first (console — no API), then pass the webhook URL, the API key, + and the alarm ARN to this stack. + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: AWS DevOps Agent Webhook + Parameters: + - WebhookUrl + - WebhookApiKey + - Label: + default: Alarm + Parameters: + - AlarmArn + - Label: + default: Delivery Tuning (optional) + Parameters: + - InvocationRateLimitPerSecond + - DevOpsAgentAlarmIntegrationTag + ParameterLabels: + WebhookUrl: + default: DevOps Agent generic (API key) webhook URL + WebhookApiKey: + default: Webhook API key (bearer token) + AlarmArn: + default: ARN of the single CloudWatch alarm to forward + InvocationRateLimitPerSecond: + default: Max webhook invocations per second + DevOpsAgentAlarmIntegrationTag: + default: Value for the DevOpsAgent tag (optional; defaults to the stack name) + +Parameters: + WebhookUrl: + Type: String + Description: > + HTTPS URL of the AWS DevOps Agent generic webhook, created in the Agent Space + console with API key authentication. + AllowedPattern: '^https://[A-Za-z0-9.-]+(:[0-9]+)?(/.*)?$' + ConstraintDescription: Must be an HTTPS URL. + + WebhookApiKey: + Type: String + NoEcho: true + Description: > + The API key (bearer token) shown once when you created the webhook. It is stored + in an AWS Secrets Manager secret that EventBridge creates and owns for the + connection. To keep the key in a secret you own instead, see the README. + MinLength: 1 + ConstraintDescription: Must not be empty. + + AlarmArn: + Type: String + Description: > + ARN of the single Amazon CloudWatch alarm this stack forwards. Only ALARM + state changes for this exact alarm are sent to the webhook. + AllowedPattern: '^arn:aws[a-zA-Z-]*:cloudwatch:[a-z0-9-]+:[0-9]{12}:alarm:.+' + ConstraintDescription: Must be a CloudWatch alarm ARN. + + DevOpsAgentAlarmIntegrationTag: + Type: String + Default: '' + Description: > + (Optional) Value applied as the DevOpsAgent tag on the resources this stack + creates (identification / cost allocation only; does not affect routing, which + is determined by the webhook URL). Defaults to the stack name when left empty. + MaxLength: 256 + AllowedPattern: "^[A-Za-z0-9 _.:/=+@-]{0,256}$" + ConstraintDescription: > + Up to 256 characters using letters, numbers, spaces, and _ . : / = + - @ + (the AWS tag-value character set), or empty to use the stack name. + + InvocationRateLimitPerSecond: + Type: Number + Default: 300 + MinValue: 1 + MaxValue: 300 + Description: > + (Optional) Maximum webhook invocations per second for the API destination. The + default of 300 is the per-destination quota, so this stack adds no throttling of + its own: one alarm cannot approach that rate, while a low cap would queue + concurrent events (a flapping alarm overlapping a retry) and delay them. Lower it + only to deliberately rate-limit the webhook. + ConstraintDescription: > + Between 1 and 300. 300 is the default 'Rate of invocations per API destination' + quota; lower this value to throttle, and raise the quota first if you need more. + +Conditions: + # An empty tag value falls back to the stack name. A parameter Default cannot + # itself be an intrinsic, so the fallback is resolved here instead. + HasTagValue: !Not [!Equals [!Ref DevOpsAgentAlarmIntegrationTag, '']] + +Resources: + # Holds the bearer token. EventBridge stores it in a Secrets Manager secret it + # creates and owns for this connection, and adds the header on every invocation. + WebhookConnection: + Type: AWS::Events::Connection + Properties: + Description: !Sub 'API key for the AWS DevOps Agent webhook (${AWS::StackName}).' + AuthorizationType: API_KEY + AuthParameters: + ApiKeyAuthParameters: + # The DevOps Agent webhook expects the token as a bearer token, so the + # header name is Authorization and the value carries the Bearer prefix. + ApiKeyName: Authorization + ApiKeyValue: !Sub 'Bearer ${WebhookApiKey}' + + WebhookApiDestination: + Type: AWS::Events::ApiDestination + Properties: + Description: !Sub 'AWS DevOps Agent webhook (${AWS::StackName}).' + ConnectionArn: !GetAtt WebhookConnection.Arn + InvocationEndpoint: !Ref WebhookUrl + HttpMethod: POST + InvocationRateLimitPerSecond: !Ref InvocationRateLimitPerSecond + + # An API destination target requires a role granting events:InvokeApiDestination. + InvokeWebhookRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: events.amazonaws.com + Action: sts:AssumeRole + Condition: + StringEquals: + aws:SourceAccount: !Ref 'AWS::AccountId' + Policies: + - PolicyName: invoke-devops-agent-webhook + PolicyDocument: + Version: '2012-10-17' + Statement: + - Sid: InvokeWebhookApiDestination + Effect: Allow + Action: events:InvokeApiDestination + Resource: !GetAtt WebhookApiDestination.Arn + Tags: + - Key: ManagedBy + Value: CloudFormation + - Key: DevOpsAgent + Value: !If + - HasTagValue + - !Ref DevOpsAgentAlarmIntegrationTag + - !Ref 'AWS::StackName' + + # Rule scoped to exactly one alarm ARN — the rule itself is the filter, so no + # code is needed to decide whether an event should be forwarded. + AlarmStateChangeRule: + Type: AWS::Events::Rule + Properties: + Description: !Sub 'Forwards ALARM-state changes for ${AlarmArn} to the DevOps Agent webhook.' + EventPattern: + source: + - aws.cloudwatch + detail-type: + - CloudWatch Alarm State Change + resources: + - !Ref AlarmArn + detail: + state: + value: + - ALARM + State: ENABLED + Targets: + - Id: DevOpsAgentWebhook + Arn: !GetAtt WebhookApiDestination.Arn + RoleArn: !GetAtt InvokeWebhookRole.Arn + HttpParameters: + HeaderParameters: + Content-Type: application/json + # incidentId is the EventBridge event id, which is constant across + # retries, so DevOps Agent deduplicates redeliveries of the same event + # instead of opening a new investigation for each attempt. + InputTransformer: + InputPathsMap: + eventId: $.id + eventTime: $.time + alarmArn: $.resources[0] + InputTemplate: | + { + "eventType": "incident", + "incidentId": "", + "action": "created", + "priority": "HIGH", + "title": "CloudWatch alarm in ALARM state", + "description": "CloudWatch alarm entered ALARM state.", + "timestamp": "", + "data": { + "metadata": { + "alarmArn": "", + "state": "ALARM" + } + } + } + RetryPolicy: + MaximumRetryAttempts: 32 + MaximumEventAgeInSeconds: 28800 + Tags: + - Key: ManagedBy + Value: CloudFormation + - Key: DevOpsAgent + Value: !If + - HasTagValue + - !Ref DevOpsAgentAlarmIntegrationTag + - !Ref 'AWS::StackName' + +Outputs: + ApiDestinationArn: + Description: ARN of the API destination that posts to the webhook. + Value: !GetAtt WebhookApiDestination.Arn + + ConnectionArn: + Description: ARN of the EventBridge connection holding the webhook API key. + Value: !GetAtt WebhookConnection.Arn + + EventRuleArn: + Description: ARN of the EventBridge rule scoped to the alarm. + Value: !GetAtt AlarmStateChangeRule.Arn + + ForwardedAlarmArn: + Description: The CloudWatch alarm this stack forwards. + Value: !Ref AlarmArn diff --git a/cloudformation/devops-agent-skill-policies/README.md b/cloudformation/devops-agent-skill-policies/README.md new file mode 100644 index 00000000..12d90985 --- /dev/null +++ b/cloudformation/devops-agent-skill-policies/README.md @@ -0,0 +1,119 @@ +# DevOps Agent skill IAM policies + +Adds the extra IAM permissions individual skills need to a DevOps Agent role, on top +of the AWS managed policy +[`AIDevOpsAgentAccessPolicy`](https://docs.aws.amazon.com/devopsagent/latest/userguide/aws-devops-agent-security-devops-agent-iam-permissions.html). + +Attach the policies to a role you already have, or let the template create one. This +template creates **no** infrastructure — only IAM. + +> This template does **not** create an Agent Space. Deploy the space separately and +> associate the role ARN from this stack's `DevOpsAgentRoleArn` output. + +## Role: existing or new + +| `ExistingRoleName` | Behaviour | +|--------------------|-----------| +| set to a role name | Attaches the inline policies to that existing role. | +| left empty (default) | Creates `DevOpsAgentRole-AgentSpace`, trusting `aidevops.amazonaws.com`, with `AIDevOpsAgentAccessPolicy` attached. | + +The trust policy on the created role is scoped with `aws:SourceAccount` and +`aws:SourceArn` (`arn:aws:aidevops:*::agentspace/*`) for confused-deputy +prevention. + +> **Multiple Agent Spaces:** the created role trusts all Agent Spaces in the account +> (`agentspace/*`), so one role can serve several spaces. Because the new-role name is +> fixed, the create-new path can only run once per account/Region. To give different +> spaces different permission sets, pre-create the roles and deploy this stack once per +> role with `ExistingRoleName`. + +## Parameters + +### Role configuration + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `ExistingRoleName` | `''` | Attach policies to this existing role. Empty creates `DevOpsAgentRole-AgentSpace`. | + +### Skill activation + +Each parameter is `'true'` / `'false'` and defaults to `'true'`. Set a skill to +`'false'` to leave out its policy. + +| Parameter | Skill | Permissions added | +|-----------|-------|-------------------| +| `EnableAwsHealthEvents` | `aws-health-events` | `health:DescribeEventTypes` | +| `EnableSupportCases` | `support-cases` | `support:DescribeCommunications` | +| `EnableRdsOperationReview` | `rds-operation-review` | `rds:DownloadDBLogFilePortion`, `logs:GetLogEvents` | +| `EnableInvestigationCostGuardrail` | `investigation-cost-guardrail` | `pricing:GetProducts` | +| `EnableMskOperations` | `msk-operations` | `kafka:GetBootstrapBrokers` | +| `EnableServiceQuotaCheck` | `service-quota-check` | Service Quotas read + `RequestServiceQuotaIncrease`, `CreateSupportCase`; `cloudwatch:GetMetricData`, `cloudwatch:GetMetricStatistics` | +| `EnableDmsOperationReview` | `database-migration-service-expertise` | `dms:TestConnection` | +| `EnableEcsOperationReview` | `ecs-operation-review` | `compute-optimizer:GetECSServiceRecommendations` | +| `EnableAwsBackupCoverageReview` | `aws-backup-coverage-review` | `backup:GetSupportedResourceTypes`, `config:SelectResourceConfig`, `dsql:ListClusters`, `storagegateway:ListFileShares`, `storagegateway:ListGateways`, `storagegateway:ListVolumes` | +| `EnableAgentCoreObservabilitySetup` | `agentcore-observability-setup` | `bedrock-agentcore:GetAgentRuntime`, `bedrock-agentcore:ListAgentRuntimes`, `xray:GetTraceSegmentDestination`, `logs:DescribeDeliveries`, `logs:DescribeDeliverySources`, `logs:DescribeDeliveryDestinations`, `logs:DescribeResourcePolicies`, `lambda:GetFunctionConfiguration`, `ecs:DescribeTaskDefinition`, `ecs:DescribeServices`, `ecs:ListTasks`, `eks:DescribeCluster` | +| `EnableAgentCoreOpsReview` | `agentcore-ops-review` | `bedrock-agentcore` read-only List/Get for runtimes, memories, gateways, browsers, code interpreters and workload identities; `bedrock-agentcore:ListMemoryRecords`; `ec2:DescribeSubnets` | +| `EnableEksOperationReview` | `aws-eks-operations-review` | None — already covered by the managed policy | +| `EnableEnrichWithSecurityAgent` | `enrich-with-aws-security-agent` | None — already covered by the managed policy | +| `EnableCrmInvestigationGuidelines` | `crm-production-investigation-guidelines` | None — already covered by the managed policy | +| `EnableSkipScheduledMaintenance` | `skip-scheduled-maintenance` | None — no IAM required | + +The last four parameters exist so the skill list stays complete and self-documenting; +toggling them changes nothing in the stack. + +`EnableAwsHealthEvents` and `EnableSupportCases` need an AWS Business or Enterprise +Support plan for the underlying APIs to return data. + +### Optional resource scoping + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `AllowedRegions` | `''` | Comma-delimited Region list. Empty means all Regions. When set, adds a `Deny` on every action outside those Regions, excepting the global services `health`, `support`, and `ce`. | + +## Always applied + +One policy is added regardless of the skill toggles: + +| Policy | Purpose | +|--------|---------| +| `AllowCreateResourceExplorerSLR` | `iam:CreateServiceLinkedRole` for `AWSServiceRoleForResourceExplorer`, required for topology discovery. | + +## Deploy + +Attach to an existing role: + +```bash +aws cloudformation deploy \ + --template-file cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml \ + --stack-name devops-agent-skill-policies \ + --parameter-overrides ExistingRoleName= \ + --capabilities CAPABILITY_NAMED_IAM +``` + +Create a new role instead, restricted to two Regions and without the Support-plan +skills: + +```bash +aws cloudformation deploy \ + --template-file cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml \ + --stack-name devops-agent-skill-policies \ + --capabilities CAPABILITY_NAMED_IAM \ + --parameter-overrides \ + AllowedRegions="us-east-1,eu-west-1" \ + EnableAwsHealthEvents=false \ + EnableSupportCases=false +``` + +## Outputs + +| Output | Description | +|--------|-------------| +| `DevOpsAgentRoleArn` | Role ARN to associate with your Agent Space. | +| `DevOpsAgentRoleName` | Role name. | +| `SkillPolicySummary` | Which skills got an inline policy, which are covered by the managed policy, and which need no IAM. | + +## Adding a skill + +When a new skill needs permissions beyond the managed policy, add a parameter, a +condition, and an `AWS::IAM::Policy` resource following the existing pattern, then +extend the `SkillPolicySummary` output. diff --git a/cloudformation/devops-agent-skill-policies.yaml b/cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml similarity index 100% rename from cloudformation/devops-agent-skill-policies.yaml rename to cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml diff --git a/skills/aws-backup-coverage-review/README.md b/skills/aws-backup-coverage-review/README.md index c800b250..5b2c9bcb 100644 --- a/skills/aws-backup-coverage-review/README.md +++ b/skills/aws-backup-coverage-review/README.md @@ -69,13 +69,13 @@ storagegateway:ListVolumes `sts:GetCallerIdentity` is also used and requires no IAM permission. Deploy them with the `EnableAwsBackupCoverageReview` parameter in -[cloudformation/devops-agent-skill-policies.yaml](https://github.com/aws/tools-for-devops-agent/blob/main/cloudformation/devops-agent-skill-policies.yaml). +[cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml](https://github.com/aws/tools-for-devops-agent/blob/main/cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml). **Each Agent Space has its own IAM role, so apply this to the role of every space where the skill is installed** — use one stack per role: ```bash aws cloudformation deploy \ - --template-file cloudformation/devops-agent-skill-policies.yaml \ + --template-file cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml \ --stack-name devops-agent-skill-policies- \ --parameter-overrides ExistingRoleName= \ EnableAwsBackupCoverageReview=true \ diff --git a/skills/aws-backup-coverage-review/references/backup-best-practices.md b/skills/aws-backup-coverage-review/references/backup-best-practices.md index d1601e9f..6ba88ec7 100644 --- a/skills/aws-backup-coverage-review/references/backup-best-practices.md +++ b/skills/aws-backup-coverage-review/references/backup-best-practices.md @@ -110,7 +110,7 @@ Use these in the Recommendation column, matched by check ID. The review is read-only. The baseline `AIDevOpsAgentAccessPolicy` covers most control-plane reads; the AWS-managed `AWSBackupAuditAccess` policy is the closest managed equivalent for the AWS Backup portion. See the skill README for the exact -action list and `cloudformation/devops-agent-skill-policies.yaml` for the +action list and `cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml` for the deployable policy. ## Canonical AWS documentation URLs diff --git a/skills/database-migration-service-expertise/README.md b/skills/database-migration-service-expertise/README.md index eb920c5f..fb8d0c52 100644 --- a/skills/database-migration-service-expertise/README.md +++ b/skills/database-migration-service-expertise/README.md @@ -31,7 +31,7 @@ You need an existing [Agent Space](https://docs.aws.amazon.com/devopsagent/lates ### 2. IAM permissions for DMS read access -The Agent Space IAM role needs read-only permissions for DMS resources. Nearly all required actions are already covered by the `AIDevOpsAgentAccessPolicy` managed policy attached to the DevOps Agent role. The one exception is `dms:TestConnection`, which must be granted separately — use the [CloudFormation template](https://github.com/aws/tools-for-devops-agent/blob/main/cloudformation/devops-agent-skill-policies.yaml). +The Agent Space IAM role needs read-only permissions for DMS resources. Nearly all required actions are already covered by the `AIDevOpsAgentAccessPolicy` managed policy attached to the DevOps Agent role. The one exception is `dms:TestConnection`, which must be granted separately — use the [CloudFormation template](https://github.com/aws/tools-for-devops-agent/blob/main/cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml). For reference, the complete action set used by this skill: ```json diff --git a/skills/ecs-operation-review/README.md b/skills/ecs-operation-review/README.md index 1b57f7c6..98b4576e 100644 --- a/skills/ecs-operation-review/README.md +++ b/skills/ecs-operation-review/README.md @@ -43,7 +43,7 @@ An existing [Agent Space](https://docs.aws.amazon.com/devopsagent/latest/usergui ### 2. Read-only permissions -The Agent Space IAM role needs read-only (`describe*` / `list*` / `get*`) access to: ECS, CloudWatch, CloudWatch Logs, IAM, Application Auto Scaling, Elastic Load Balancing v2, ECR, EC2/VPC, GuardDuty, and Compute Optimizer. The DevOps Agent managed policy **`AIDevOpsAgentAccessPolicy`** covers all of these except one: it grants no `compute-optimizer` actions, so the PERF8 rightsizing check needs `compute-optimizer:GetECSServiceRecommendations` added. Deploy `cloudformation/devops-agent-skill-policies.yaml` with `EnableEcsOperationReview=true` to attach it as a gated inline policy. Without it the skill still runs — PERF8 is marked N/A under the access-limitation protocol. No cluster-level access entry or kubectl connectivity is required — ECS is assessed entirely through AWS control-plane APIs. +The Agent Space IAM role needs read-only (`describe*` / `list*` / `get*`) access to: ECS, CloudWatch, CloudWatch Logs, IAM, Application Auto Scaling, Elastic Load Balancing v2, ECR, EC2/VPC, GuardDuty, and Compute Optimizer. The DevOps Agent managed policy **`AIDevOpsAgentAccessPolicy`** covers all of these except one: it grants no `compute-optimizer` actions, so the PERF8 rightsizing check needs `compute-optimizer:GetECSServiceRecommendations` added. Deploy `cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml` with `EnableEcsOperationReview=true` to attach it as a gated inline policy. Without it the skill still runs — PERF8 is marked N/A under the access-limitation protocol. No cluster-level access entry or kubectl connectivity is required — ECS is assessed entirely through AWS control-plane APIs. ### 3. AWS Knowledge MCP diff --git a/skills/msk-operations/README.md b/skills/msk-operations/README.md index cf4686dd..a9ff1b48 100644 --- a/skills/msk-operations/README.md +++ b/skills/msk-operations/README.md @@ -49,7 +49,7 @@ The AWS DevOps Agent's primary cloud-source role needs read access to MSK and CloudWatch. All calls except `kafka:GetBootstrapBrokers` are covered by `AIDevOpsAgentAccessPolicy`. `kafka:GetBootstrapBrokers` is granted by the opt-in `EnableMskOperations` parameter (default `true`) in -[`cloudformation/devops-agent-skill-policies.yaml`](https://github.com/aws/tools-for-devops-agent/blob/main/cloudformation/devops-agent-skill-policies.yaml). +[`cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml`](https://github.com/aws/tools-for-devops-agent/blob/main/cloudformation/devops-agent-skill-policies/devops-agent-skill-policies.yaml). The full set of actions the skill uses in practice: ```