About AWS DevOps Agent
AWS DevOps Agent is an AI-powered operational service designed to investigate production incidents, correlate telemetry and infrastructure changes, identify likely root causes, and recommend preventive improvements.
The service can work with AWS resources, observability platforms, code repositories, CI/CD systems, runbooks, and ticketing systems.
AWS DevOps Agent acts as an operational assistant for DevOps and Site Reliability Engineering teams.
It can:
- Discover AWS resources and their relationships
- Build an application topology
- Correlate logs, metrics, traces, deployments, and configuration changes
- Investigate incidents
- Produce root-cause analysis
- Recommend remediation and preventive actions
- Integrate with external observability and engineering tools
AWS defines an Agent Space as the logical boundary controlling what the agent can access. Each Agent Space has its own AWS account access, external integrations, operator permissions, investigation data, and chat history.
An Agent Space should normally align with an application, business service, platform, or on-call ownership boundary.
Supported AWS Regions
AWS DevOps Agent can investigate resources across Regions after an AWS account is associated with the Agent Space. You do not need to create a separate Agent Space in every workload Region.
However, the Agent Space itself must be created in a supported Region.
At the time of writing, supported Regions include:
us-east-1
us-west-2
ca-central-1
sa-east-1
ap-south-1
ap-southeast-1
ap-southeast-2
ap-northeast-1
eu-central-1
eu-west-1
eu-west-2
Production operations are available in all supported Regions, while some preview capabilities can have more limited Regional availability.
For European workloads, eu-west-1 or eu-central-1 may be appropriate depending on latency, data residency, and organizational requirements.
Deployment requirements
Before starting, ensure you have:
- Terraform 1.0 or later
- AWS CLI installed
- AWS CLI credentials configured
- Permission to create IAM roles and policies
- Permission to create AWS DevOps Agent resources
- One AWS account for the Agent Space
- Optionally, one or more additional workload accounts
Check the installed tools:
1) terraform version
terraform version
Terraform v1.15.8
2) AWS CLI version
aws --version
aws-cli/2.24.0 Python/3.12.6 Windows/11 exe/AMD64
3) Verify AWS identity:
aws sts get-caller-identity`
Expected output:
{
"UserId": "AIDAXXXXXXXXXXXXXXXX",
"Account": "123456789876",
"Arn": "arn:aws:iam::123456789876:user/terraform-admin"
}
For local testing, an AWS CLI profile can be used:
aws configure --profile devops-agent-admin
For production CI/CD, use temporary credentials through OpenID Connect or an AWS role instead of storing long-lived access keys.
Terraform project structure
A small environment, can use the following structure:
aws-devops-agent-terraform/
├── backend.tf
├── versions.tf
├── providers.tf
├── variables.tf
├── locals.tf
├── data.tf
├── iam-agent.tf
├── iam-operator.tf
├── devops-agent.tf
├── associations.tf
├── outputs.tf
├── terraform.tfvars.example
└── README.md
For a larger environment, extract the deployment into a reusable module:
aws-devops-agent-terraform/
├── modules/
│ └── devops-agent/
│ ├── main.tf
│ ├── iam.tf
│ ├── variables.tf
│ └── outputs.tf
└── environments/
├── production/
└── non-production/
Steps
Step 1: Configure the Terraform versions
Create versions.tf:
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
awscc = {
source = "hashicorp/awscc"
version = "~> 1.0"
}
time = {
source = "hashicorp/time"
version = "~> 0.13"
}
}
}
The awscc provider is important because AWS DevOps Agent resources are exposed through AWS Cloud Control.
The time provider can be used to handle IAM propagation delays before creating the Agent Space.
Step 2: Configure the providers
Create providers.tf:
provider "aws" {
region = var.aws_region
profile = var.aws_profile
default_tags {
tags = local.common_tags
}
}
provider "awscc" {
region = var.aws_region
profile = var.aws_profile
}
For local development, profile is acceptable. In CI/CD, remove the profile and let the provider obtain temporary credentials from the pipeline environment:
provider "aws" {
region = var.aws_region
default_tags {
tags = local.common_tags
}
}
provider "awscc" {
region = var.aws_region
}
Avoid putting access keys directly inside the provider, as shown below:
provider "aws" {
access_key = "AKIA..."
secret_key = "..."
}
Step 3: Define variables
Create variables.tf:
variable "aws_region" {
description = "AWS Region in which the Agent Space will be created."
type = string
default = "eu-west-1"
validation {
condition = contains([
"us-east-1",
"us-west-2",
"ca-central-1",
"sa-east-1",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1",
"eu-central-1",
"eu-west-1",
"eu-west-2"
], var.aws_region)
error_message = "The selected Region is not currently supported by AWS DevOps Agent."
}
}
variable "aws_profile" {
description = "Optional AWS CLI profile for local deployment."
type = string
default = null
}
variable "agent_space_name" {
description = "Name of the AWS DevOps Agent Space."
type = string
validation {
condition = length(trimspace(var.agent_space_name)) > 2
error_message = "The Agent Space name must contain at least three characters."
}
}
variable "agent_space_description" {
description = "Description of the Agent Space and its operational boundary."
type = string
}
variable "environment" {
description = "Deployment environment."
type = string
default = "production"
validation {
condition = contains(["development", "test", "staging", "production"], var.environment)
error_message = "Environment must be development, test, staging, or production."
}
}
variable "application_name" {
description = "Application or platform monitored by the Agent Space."
type = string
}
variable "additional_tags" {
description = "Additional tags applied to supported resources."
type = map(string)
default = {}
}
Step 4: Create common tags
Create locals.tf:
locals {
common_tags = merge(
{
Application = var.application_name
Environment = var.environment
ManagedBy = "Terraform"
Repository = "aws-devops-agent-terraform"
Service = "AWS-DevOps-Agent"
},
var.additional_tags
)
}
Tags help with:
- Ownership
- Cost allocation
- Incident routing
- Compliance
- Terraform resource discovery
- Operational governance
Step 5: Retrieve the current AWS account
Create data.tf:
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}
data "aws_region" "current" {}
These data sources prevent hardcoding the AWS account ID, partition, and Region.
Step 6: Create the DevOps Agent IAM role
AWS DevOps Agent needs an IAM role that the service can assume.
Create iam-agent.tf:
data "aws_iam_policy_document" "devops_agent_assume_role" {
statement {
sid = "AllowAWSDevOpsAgent"
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["aidevops.amazonaws.com"]
}
condition {
test = "StringEquals"
variable = "aws:SourceAccount"
values = [data.aws_caller_identity.current.account_id]
}
}
}
resource "aws_iam_role" "devops_agent" {
name_prefix = "DevOpsAgentRole-AgentSpace-"
description = "Role assumed by AWS DevOps Agent for ${var.application_name}"
assume_role_policy = data.aws_iam_policy_document.devops_agent_assume_role.json
tags = local.common_tags
}
# Attach the AWS-managed DevOps Agent access policy
resource "aws_iam_role_policy_attachment" "devops_agent_access" {
role = aws_iam_role.devops_agent.name
policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/AIDevOpsAgentAccessPolicy"
}
# AWS DevOps Agent can also require permission to create or use the AWS Resource Explorer service-linked role.
# Create a narrowly scoped inline policy:
data "aws_iam_policy_document" "resource_explorer_service_linked_role" {
statement {
sid = "AllowResourceExplorerServiceLinkedRole"
effect = "Allow"
actions = [
"iam:CreateServiceLinkedRole"
]
resources = ["*"]
condition {
test = "StringEquals"
variable = "iam:AWSServiceName"
values = ["resource-explorer-2.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy" "resource_explorer_service_linked_role" {
name = "AllowResourceExplorerServiceLinkedRole"
role = aws_iam_role.devops_agent.id
policy = data.aws_iam_policy_document.resource_explorer_service_linked_role.json
}
Check the current AWS-managed policy names in the official AWS documentation before deployment. Service policies can evolve as capabilities are added.
Step 7: Create the operator web application role
The operator role controls what engineers can do through the AWS DevOps Agent web application.
Create iam-operator.tf:
data "aws_iam_policy_document" "operator_assume_role" {
statement {
sid = "AllowAWSDevOpsAgentOperatorApp"
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["aidevops.amazonaws.com"]
}
condition {
test = "StringEquals"
variable = "aws:SourceAccount"
values = [data.aws_caller_identity.current.account_id]
}
}
}
resource "aws_iam_role" "operator" {
name_prefix = "DevOpsAgentRole-WebappAdmin-"
description = "Operator web application role for ${var.application_name}"
assume_role_policy = data.aws_iam_policy_document.operator_assume_role.json
tags = local.common_tags
}
resource "aws_iam_role_policy_attachment" "operator_access" {
role = aws_iam_role.operator.name
policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/AIDevOpsOperatorAppAccessPolicy"
}
Separating the agent role from the operator role is important:
- The agent role controls what infrastructure and telemetry the agent can inspect.
- The operator role controls what human operators can do in the Agent Space web application.
Do not combine these responsibilities into a single role.
Step 8: Handle IAM propagation
IAM is eventually consistent. The DevOps Agent service validates the role trust policies while the Agent Space is being created.
Add a small delay:
resource "time_sleep" "wait_for_iam_propagation" {
create_duration = "30s"
depends_on = [
aws_iam_role_policy_attachment.devops_agent_access,
aws_iam_role_policy_attachment.operator_access,
aws_iam_role_policy.resource_explorer_service_linked_role
]
}
The official AWS Terraform example also accounts for IAM propagation. If role validation still fails, waiting briefly and rerunning terraform apply can allow Terraform to continue from the existing IAM resources.
Step 9: Create the Agent Space
Create devops-agent.tf:
resource "awscc_devopsagent_agent_space" "this" {
name = var.agent_space_name
description = var.agent_space_description
operator_app = {
enabled = true
role_arn = aws_iam_role.operator.arn
}
depends_on = [
time_sleep.wait_for_iam_propagation
]
}
The exact resource schema can change as the AWS Cloud Control resource evolves. Validate the current arguments with:
terraform providers schema -json
You can also inspect the resource documentation:
terraform init
terraform providers
Step 10: Associate the monitoring account
The account association connects the current AWS account to the Agent Space.
Create associations.tf:
resource "awscc_devopsagent_association" "monitoring_account" {
agent_space_id = awscc_devopsagent_agent_space.this.agent_space_id
association_type = "AWS"
configuration = {
account_id = data.aws_caller_identity.current.account_id
role_arn = aws_iam_role.devops_agent.arn
source_type = "MONITOR"
}
depends_on = [
awscc_devopsagent_agent_space.this
]
}
Because AWS Cloud Control schemas can differ between provider releases, compare the property names with the current Terraform Registry schema before publishing or applying the configuration.
The official AWS sample is the safest baseline for the exact awscc_devopsagent_association configuration. AWS confirms that this association links the monitoring account to the Agent Space.
Step 11: Define outputs
Create outputs.tf:
output "agent_space_id" {
description = "AWS DevOps Agent Space ID."
value = awscc_devopsagent_agent_space.this.agent_space_id
}
output "agent_space_arn" {
description = "AWS DevOps Agent Space ARN."
value = awscc_devopsagent_agent_space.this.agent_space_arn
}
output "agent_space_name" {
description = "AWS DevOps Agent Space name."
value = var.agent_space_name
}
output "devops_agent_role_arn" {
description = "IAM role assumed by AWS DevOps Agent."
value = aws_iam_role.devops_agent.arn
}
output "operator_role_arn" {
description = "Operator web application IAM role."
value = aws_iam_role.operator.arn
}
output "monitoring_account_id" {
description = "AWS monitoring account ID."
value = data.aws_caller_identity.current.account_id
}
Step 12: Configure the environment
Create terraform.tfvars.example:
aws_region = "eu-west-1"
aws_profile = "devops-agent-admin"
agent_space_name = "payments-production"
agent_space_description = "AWS DevOps Agent Space for the production payments platform"
application_name = "payments-platform"
environment = "production"
additional_tags = {
Owner = "Platform-Engineering"
CostCenter = "CC-1234"
Criticality = "High"
}
Copy the file:
cp terraform.tfvars.example terraform.tfvars
Never commit terraform.tfvars when it contains account-specific or sensitive data.
Add it to .gitignore:
.terraform/
*.tfstate
*.tfstate.*
*.tfplan
terraform.tfvars
crash.log
override.tf
override.tf.json
*_override.tf
*_override.tf.json
Commit .terraform.lock.hcl so that the same provider versions are used across development and CI/CD environments.
Step 13: Deploy the Agent Space
Format the code:
terraform fmt -recursive
Initialize Terraform:
terraform init
Validate the configuration:
terraform validate
Create a saved plan:
terraform plan \
-out=tfplan
Review the plan carefully and apply it:
terraform apply tfplan
After deployment, inspect the outputs:
terraform output
Example:
agent_space_id = "abc123"
agent_space_arn = "arn:aws:aidevops:eu-west-1:123456789876:agentspace/abc123"
agent_space_name = "payments-production"
operator_role_arn = "arn:aws:iam::123456789876:role/DevOpsAgentRole-WebappAdmin-.
Step 14: Verify the deployment
Use the AWS CLI:
aws devops-agent get-agent-space \
--agent-space-id "$(terraform output -raw agent_space_id)" \
--region "$(terraform output -raw aws_region 2>/dev/null || echo eu-west-1)"
Alternatively:
AGENT_SPACE_ID=$(terraform output -raw agent_space_id)
aws devops-agent get-agent-space \
--agent-space-id "$AGENT_SPACE_ID" \
--region eu-west-1
You can also verify that the IAM roles exist:
aws iam get-role \
--role-name "$(terraform output -raw devops_agent_role_arn | awk -F/ '{print $NF}')"
Then open the AWS DevOps Agent console and confirm:
- The Agent Space is active.
- The operator app is enabled.
- The current AWS account is associated.
- Resource discovery has started.
- Application topology is being populated.
Deployment Best Practices
1) Use a remote Terraform backend
Do not store production Terraform state only on an engineer’s laptop.
Example S3 backend:
terraform {
backend "s3" {
bucket = "company-terraform-state-prod"
key = "platform/aws-devops-agent/terraform.tfstate"
region = "eu-west-1"
encrypt = true
use_lockfile = true
}
}
The backend bucket should have:
- Versioning enabled
- Encryption enabled
- Public access blocked
- Strict bucket policy
- Access logging where required
- State locking enabled
- Backup and recovery procedures
Bootstrap the backend separately because Terraform cannot use a backend that does not yet exist.
2) Protect observability data
The agent can process logs, metrics, traces, ticket metadata, resource tags, and other operational information.
Do not place:
- Passwords
- API keys
- Authentication tokens
- Customer personal information
- Payment card information
- Private certificates
inside logs, tags, or incident descriptions.
AWS notes that personally identifiable information is not automatically removed when data is summarized. Sensitive information should therefore be redacted before it enters observability systems.
Common Terraform issues
1) Resource type not found
Example:
Error: Invalid resource type
The provider hashicorp/aws does not support resource type
"aws_devopsagent_agent_space".
Cause:
AWS DevOps Agent resources use the AWS Cloud Control provider.
Solution:
required_providers {
awscc = {
source = "hashicorp/awscc"
version = "~> 1.0"
}
}
Use:
awscc_devopsagent_agent_space
awscc_devopsagent_association
The official AWS documentation requires the awscc provider for these resources.
2) IAM trust policy validation failure
Example:
The operator role trust policy is invalid
Possible causes:
- IAM propagation delay
- Incorrect service principal
- Incorrect source account
- Incorrect Agent Space ARN
- An Organizations SCP blocking the operation
Resolution:
- Confirm the trust policy.
- Confirm the current account ID.
- Wait briefly for IAM propagation.
- Run terraform apply again.
- Check CloudTrail for denied API calls.
- Review Organizations SCPs and permission boundaries.
3) Access denied while creating the Agent Space
Check the caller identity:
aws sts get-caller-identity
Then verify the deployment principal can:
- Create IAM roles
- Attach IAM policies
- Pass the required IAM roles
- Create AWS DevOps Agent resources
- Create account associations
- Create service-linked roles when required
Also check whether an SCP blocks:
aidevops:*
iam:CreateServiceLinkedRole
iam:PassRole
Do not grant unrestricted administrator access permanently merely to bypass a policy problem.
Cleanup
To remove the environment:
terraform plan -destroy -out=destroy.tfplan
terraform apply destroy.tfplan
Or:
terraform destroy
Destroying an Agent Space can permanently remove its investigation history, recommendations, and associated data. Therefore, review retention requirements before deletion.
Top comments (0)