Try it free

Create AWS connection via API

  • Latest Dynatrace
  • How-to guide

A single Dynatrace environment allows up to 500 connections. If you need to exceed this, please contact Dynatrace support for more information.

Use this guide to create a new AWS connection using our public APIs when

  • You can't deploy the CloudFormation stack, which automates the entire connection creation.
  • You're looking to integrate the new connection creation programmatic API constructs into your own automation GitOps processes and pipelines.
  • You're restricted by compliance to not use any ready-made IaC assets.

This guide covers only topology and metrics integration via API. Logs and events integration is not supported.

Prerequisites

  • An AWS account with AWS admin access

  • An EC2 with internet access (Dynatrace APIs)

  • Settings platform tokens for the API programmatic access

  • If this is the first time that an AWS connection is created inside this Dynatrace environment, do one of the following options:

    • Option 1: Go to Settings Settings and select Collect and capture > Cloud and virtualization > AWS.

      Do this at least once, and keep it open for about 10 minutes.

    • Option 2: Submit the following API call. Be sure to replace the placeholders as described below.

      For more info on this API call, see Hub capabilities API - POST an extension 2.0 to environment.

      curl -X POST \
      "https://${your-environment-url}/api/v2/hub/extensions2/com.dynatrace.extension.da-aws/actions/addToEnvironment" \
      --header "Authorization: Api-Token ${your-Api-Token}" \
      --header "Accept: application/json"

      Replace the following placeholders with your values and run the API request:

      • ${your-environment-url}: Your full Dynatrace Classic environment URL, for example, xyz12345.live.dynatrace.com.
      • ${your-Api-Token}: An access token with the needed permission scope.

Create AWS connection and IAM monitoring role

1. Create platform tokens

  1. Create the programmatic access permission policy, in the policy statement use this policy:

    ALLOW
    settings:objects:read,
    settings:objects:write
    WHERE settings:schemaId = "builtin:hyperscaler-authentication.connections.aws";
    ALLOW
    extensions:definitions:read,
    extensions:configurations:read,
    extensions:configurations:write
    WHERE extensions:extension-name = "com.dynatrace.extension.da-aws";
    ALLOW
    data-acquisition:events:ingest,
    data-acquisition:logs:ingest,
    data-acquisition:metrics:ingest;
  2. Create a service user, assign the above newly created policy to this service user.

  3. Create a platform token for service user. Assign the below token scopes:

    settings:objects:read
    settings:objects:write
    extensions:definitions:read
    extensions:configurations:read
    extensions:configurations:write
  4. Optional Create a platform token for service user (choose your existing created service user, created at step 3). Assign the below token scopes:

    data-acquisition:events:ingest
    data-acquisition:logs:ingest
    data-acquisition:metrics:ingest

    The ingest platform token is optional, and is only needed if you plan to ingest push-based telemetry (logs or events) into Dynatrace. To complete the connection and monitoring configuration creation the ingest platform token is not needed.

2. Create AWS connection

  1. Prepare this command:

    curl -X 'POST' \
    'https://${your-environment-url}/platform/classic/environment-api/v2/settings/objects' \
    -H 'accept: application/json; charset=utf-8' \
    -H 'authorization: Bearer ${your-bearer-token}' \
    -H 'Content-Type: application/json; charset=utf-8' \
    -d '[
    {
    "schemaId": "builtin:hyperscaler-authentication.connections.aws",
    "value": {
    "name": "${connection-name}",
    "type": "awsRoleBasedAuthentication",
    "awsRoleBasedAuthentication": {
    "roleArn": "",
    "consumers": [
    "SVC:com.dynatrace.da"
    ]
    }
    }
    }
    ]'
  2. Replace the following placeholders with your values and run the command:

    • ${your-environment-url}: Your full Dynatrace environment URL, for example, xyz12345.apps.dynatrace.com.
    • ${your-bearer-token}: Set the platform settings token you have created as part of the prerequisites.
    • ${connection-name}: Set the connection name, for example, my-prod-east45.

    Do not set any value for "roleArn": "" at this point.

  3. The response should look similar to this:

    [
    {
    "code": 200,
    "objectId": "vu9U3hXa3q0AAAABADJidWlsdGluOmh5cGVyc2NhbGVyLWF1dGhlbnRpY2F0aW9uLmNvbm5lY3Rpb25zLmF3cwAGdGVuYW50AAZ0ZW5hbnQAJDMwZTg0YzgyLWNhYm05tYE2Mi1hNDg2LWJhYmFiY2ZlM2NiML7vVN4V2t6t"
    }
    ]
  4. Save the dynamically generated objectId value. We'll use this as the value for the IAM monitoring ExternalId within the role's trust policy.

If the API call fails, validate that

  1. You have the needed service user and platform token permissions to access the settings API.
  2. Your settings platform token is valid, and assigned to the correct Dynatrace account/environment.

3. Create AWS IAM monitoring role

The IAM monitoring role consists of the following:

ConstructDescription

DynatraceMonitoringPolicy

First IAM managed policy: AWS service API enumeration for rich metadata (topology) and CloudWatch API permissions.

DynatraceMonitoringPolicy-2

Second IAM managed policy: Additional AWS service API enumeration for rich metadata (topology).

DynatraceMonitoringRole

Cross-account IAM role that Dynatrace must assume in order for the connection to remain in healthy state.

Create DynatraceMonitoringPolicy IAM policy

  1. Follow the AWS documentation to create the (managed) policy.

  2. Paste this entire JSON block into the policy editor:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "TopologyInventory",
    "Effect": "Allow",
    "Action": [
    "account:GetAccountInformation",
    "acm-pca:ListCertificateAuthorities",
    "aoss:BatchGetCollection",
    "aoss:ListCollections",
    "apigateway:GET",
    "apprunner:DescribeAutoScalingConfiguration",
    "apprunner:DescribeService",
    "apprunner:DescribeVpcConnector",
    "apprunner:DescribeVpcIngressConnection",
    "apprunner:ListAutoScalingConfigurations",
    "apprunner:ListServices",
    "apprunner:ListTagsForResource",
    "apprunner:ListVpcConnectors",
    "apprunner:ListVpcIngressConnections",
    "athena:GetWorkGroup",
    "athena:ListWorkGroups",
    "autoscaling:DescribeAutoScalingGroups",
    "autoscaling:DescribeWarmPool",
    "bedrock:GetAgent", "bedrock:GetAgentAlias",
    "bedrock:GetGuardrail", "bedrock:GetKnowledgeBase",
    "bedrock:ListAgentAliases", "bedrock:ListAgents",
    "bedrock:ListGuardrails", "bedrock:ListKnowledgeBases",
    "cloudfront:GetDistribution", "cloudfront:ListDistributions",
    "cloudfront:ListTagsForResource",
    "cloudhsm:DescribeClusters",
    "cloudtrail:GetEventSelectors", "cloudtrail:GetTrail",
    "cloudtrail:GetTrailStatus", "cloudtrail:ListTrails",
    "cloudtrail:LookupEvents",
    "dax:DescribeClusters", "dax:DescribeSubnetGroups",
    "directconnect:DescribeConnections",
    "directconnect:DescribeVirtualInterfaces",
    "dms:DescribeReplicationInstances",
    "dynamodb:DescribeContinuousBackups",
    "dynamodb:DescribeKinesisStreamingDestination",
    "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive",
    "dynamodb:ListTables",
    "ec2:DescribeAddresses", "ec2:DescribeAvailabilityZones",
    "ec2:DescribeClientVpnEndpoints",
    "ec2:DescribeCustomerGateways", "ec2:DescribeDhcpOptions",
    "ec2:DescribeEgressOnlyInternetGateways",
    "ec2:DescribeIamInstanceProfileAssociations",
    "ec2:DescribeInstances", "ec2:DescribeInternetGateways",
    "ec2:DescribeLaunchTemplateVersions",
    "ec2:DescribeLaunchTemplates", "ec2:DescribeNatGateways",
    "ec2:DescribeNetworkAcls", "ec2:DescribeNetworkInterfaces",
    "ec2:DescribeRegions", "ec2:DescribeRouteTables",
    "ec2:DescribeSecurityGroups", "ec2:DescribeSnapshots",
    "ec2:DescribeSubnets",
    "ec2:DescribeTransitGatewayAttachments",
    "ec2:DescribeTransitGatewayConnects",
    "ec2:DescribeTransitGatewayMulticastDomains",
    "ec2:DescribeTransitGatewayRouteTables",
    "ec2:DescribeTransitGateways", "ec2:DescribeVolumes",
    "ec2:DescribeVpcEndpointServiceConfigurations",
    "ec2:DescribeVpcEndpoints",
    "ec2:DescribeVpcPeeringConnections", "ec2:DescribeVpcs",
    "ec2:DescribeVpnConnections", "ec2:DescribeVpnGateways",
    "ecr-public:DescribeRepositories",
    "ecr-public:GetRepositoryPolicy",
    "ecr:DescribeRepositories", "ecr:GetRepositoryPolicy",
    "ecs:DescribeCapacityProviders", "ecs:DescribeClusters",
    "ecs:DescribeContainerInstances", "ecs:DescribeServices",
    "ecs:DescribeTaskDefinition", "ecs:DescribeTasks",
    "ecs:ListClusters", "ecs:ListContainerInstances",
    "ecs:ListServices", "ecs:ListTaskDefinitions",
    "ecs:ListTasks",
    "eks:DescribeCluster", "eks:DescribeNodegroup",
    "eks:ListClusters", "eks:ListNodegroups",
    "elasticache:DescribeCacheClusters",
    "elasticache:DescribeCacheParameterGroups",
    "elasticache:DescribeCacheParameters",
    "elasticache:DescribeCacheSubnetGroups",
    "elasticache:DescribeServerlessCaches",
    "elasticbeanstalk:DescribeApplications",
    "elasticbeanstalk:DescribeEnvironmentResources",
    "elasticbeanstalk:DescribeEnvironments",
    "elasticfilesystem:DescribeAccessPoints",
    "elasticfilesystem:DescribeFileSystems",
    "elasticfilesystem:DescribeMountTargets",
    "elasticloadbalancing:DescribeListeners",
    "elasticloadbalancing:DescribeLoadBalancerAttributes",
    "elasticloadbalancing:DescribeLoadBalancerPolicies",
    "elasticloadbalancing:DescribeLoadBalancers",
    "elasticloadbalancing:DescribeRules",
    "elasticloadbalancing:DescribeTargetGroupAttributes",
    "elasticloadbalancing:DescribeTargetGroups",
    "elasticloadbalancing:DescribeTargetHealth",
    "es:DescribeDomains", "es:ListDomainNames",
    "events:DescribeEventBus", "events:ListEventBuses",
    "firehose:DescribeDeliveryStream",
    "firehose:ListDeliveryStreams",
    "iam:GenerateCredentialReport",
    "iam:GetAccountAuthorizationDetails",
    "iam:GetAccountPasswordPolicy",
    "iam:GetAccountSummary", "iam:GetCredentialReport",
    "iam:ListAccountAliases", "iam:ListInstanceProfiles",
    "iam:ListMFADevices", "iam:ListServerCertificates",
    "kafka:ListClustersV2",
    "kms:DescribeKey", "kms:GetKeyRotationStatus",
    "kms:ListAliases", "kms:ListKeys",
    "lambda:GetAlias", "lambda:GetFunction",
    "lambda:GetPolicy", "lambda:ListAliases",
    "lambda:ListEventSourceMappings",
    "lambda:ListFunctions",
    "logs:DescribeLogGroups",
    "logs:DescribeSubscriptionFilters",
    "mq:DescribeBroker", "mq:DescribeConfiguration",
    "mq:ListBrokers", "mq:ListConfigurations",
    "organizations:DescribeOrganization",
    "rds:DescribeOptionGroups", "rds:ListTagsForResource",
    "redshift-serverless:ListNamespaces",
    "redshift-serverless:ListWorkgroups",
    "redshift:DescribeClusterSubnetGroups",
    "redshift:DescribeClusters",
    "redshift:DescribeLoggingStatus",
    "route53:GetHostedZone", "route53:ListHealthChecks",
    "route53:ListHostedZones",
    "s3:GetAccelerateConfiguration", "s3:GetBucketAcl",
    "s3:GetBucketLogging", "s3:GetBucketNotification",
    "s3:GetBucketPolicy",
    "s3:GetBucketPublicAccessBlock",
    "s3:GetBucketRequestPayment",
    "s3:GetBucketVersioning",
    "s3:GetEncryptionConfiguration",
    "s3:ListAllMyBuckets",
    "sns:GetTopicAttributes", "sns:ListTopics",
    "sqs:GetQueueAttributes", "sqs:ListQueues",
    "states:DescribeStateMachine",
    "states:ListStateMachines",
    "storagegateway:DescribeGatewayInformation",
    "storagegateway:ListGateways",
    "tag:GetResources", "tag:GetTagKeys",
    "tag:GetTagValues",
    "wafv2:GetWebACL", "wafv2:ListWebACLs"
    ],
    "Resource": "*"
    },
    {
    "Sid": "CloudWatchMonitoring",
    "Effect": "Allow",
    "Action": [
    "cloudwatch:GetMetricData",
    "cloudwatch:ListMetrics"
    ],
    "Resource": "*"
    }
    ]
    }

Create DynatraceMonitoringPolicy-2 IAM policy

  1. Follow the AWS documentation to create the (managed) policy.

  2. Paste this entire JSON block into the policy editor:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "TopologyInventory",
    "Effect": "Allow",
    "Action": [
    "acm:ListCertificates",
    "airflow:GetEnvironment", "airflow:ListEnvironments",
    "apigateway:GetStage",
    "appstream:DescribeFleets",
    "appstream:ListTagsForResource",
    "appsync:ListGraphqlApis",
    "backup:GetBackupPlan",
    "backup:GetBackupVaultNotifications",
    "backup:ListBackupPlans", "backup:ListBackupVaults",
    "cassandra:GetKeyspace", "cassandra:GetTable",
    "cassandra:ListKeyspaces", "cassandra:ListTables",
    "cassandra:ListTagsForResource", "cassandra:Select",
    "codebuild:BatchGetProjects", "codebuild:ListProjects",
    "cognito-idp:DescribeUserPool",
    "cognito-idp:ListUserPools",
    "connect:DescribeInstance",
    "connect:ListInstanceStorageConfigs",
    "connect:ListInstances",
    "datasync:DescribeTask", "datasync:ListTasks",
    "ec2:DescribeFlowLogs",
    "ec2:DescribeIpamPools", "ec2:DescribeIpamScopes",
    "ec2:DescribeIpams",
    "elasticmapreduce:DescribeCluster",
    "emr-containers:DescribeManagedEndpoint",
    "emr-containers:DescribeVirtualCluster",
    "emr-serverless:GetApplication",
    "events:ListRules",
    "execute-api:GetStage",
    "fsx:DescribeFileSystems",
    "fsx:DescribeStorageVirtualMachines",
    "fsx:DescribeVolumes",
    "globalaccelerator:ListAccelerators",
    "globalaccelerator:ListTagsForResource",
    "glue:GetJobs",
    "kafka:DescribeClusterV2",
    "kafka:DescribeConfiguration",
    "kafka:DescribeVpcConnection",
    "kafka:ListConfigurations",
    "kafka:ListVpcConnections",
    "kafkaconnect:DescribeConnector",
    "kafkaconnect:ListConnectors",
    "kinesis:DescribeStreamSummary", "kinesis:ListStreams",
    "kinesisanalytics:DescribeApplication",
    "kinesisanalytics:ListApplications",
    "kinesisanalytics:ListTagsForResource",
    "logs:DescribeDeliveryDestinations",
    "network-firewall:DescribeFirewall",
    "network-firewall:DescribeFirewallPolicy",
    "network-firewall:ListFirewallPolicies",
    "network-firewall:ListFirewalls",
    "rds:DescribeDBClusterSnapshots",
    "rds:DescribeDBClusters", "rds:DescribeDBInstances",
    "rds:DescribeDBSnapshots",
    "rds:DescribeDBSubnetGroups",
    "route53:GetHealthCheck",
    "route53resolver:ListResolverEndpoints",
    "s3:ListBuckets",
    "sagemaker:DescribeEndpoint",
    "sagemaker:DescribeFeatureGroup",
    "sagemaker:DescribeInferenceComponent",
    "sagemaker:DescribeLabelingJob",
    "sagemaker:DescribePipeline",
    "sagemaker:ListEndpoints",
    "sagemaker:ListFeatureGroups",
    "sagemaker:ListInferenceComponents",
    "sagemaker:ListLabelingJobs",
    "sagemaker:ListPipelines"
    ],
    "Resource": "*"
    }
    ]
    }

Create (DynatraceMonitoringRole) IAM monitoring role

  1. In the AWS Console, create a cross account IAM role (another AWS account as the trusted entity type).

  2. In the Account ID (the originating account, which is the Dynatrace account), set the ID to: 314146291599.

  3. Check Require External ID and set the ID to the {objectId} value you captured earlier (make sure that you set the entire string).

  4. For permissions, search for DynatraceMonitoringPolicy and add the two created (managed) policies (DynatraceMonitoringPolicy, DynatraceMonitoringPolicy-2).

  5. We recommend tagging the role with Dynatrace:EnvironmentID (your Dynatrace environment ID).

  6. Create the role and capture the Role ARN to complete the connection creation.

    The role trust policy JSON should look like this example:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::314146291599:root"
    },
    "Action": "sts:AssumeRole",
    "Condition": {
    "StringEquals": {
    "sts:ExternalId": "${objectId}"
    }
    }
    }
    ]
    }

4. Update connection with IAM role ARN name

  1. Prepare this command:

    curl -X 'POST' \
    'https://${your-environment-url}/platform/classic/environment-api/v2/settings/objects' \
    -H 'accept: application/json; charset=utf-8' \
    -H 'authorization: Bearer ${your-bearer-token}' \
    -H 'Content-Type: application/json; charset=utf-8' \
    -d '[
    {
    "objectId": "${objectId}",
    "schemaId": "builtin:hyperscaler-authentication.connections.aws",
    "value": {
    "name": "${connection-name}",
    "type": "awsRoleBasedAuthentication",
    "awsRoleBasedAuthentication": {
    "roleArn": "${monitoring-role-arn}",
    "consumers": [
    "SVC:com.dynatrace.da"
    ]
    }
    }
    }
    ]'
  2. Replace the following placeholders with your values and run the command:

    • ${your-environment-url}: Your full Dynatrace environment URL (for example, xyz12345.apps.dynatrace.com).
    • ${your-bearer-token}: Set the platform settings token you have created as part of the prerequisites.
    • ${monitoring-role-arn}: Set the monitoring role ARN name captured on the IAM Role creation step (for example, arn:aws:iam::<YourAWSAccount>:role/DynatraceMonitoringRole).
    • ${objectId}: Set the value of the ${objectId} you captured eariler (make sure that you set the entire string).
    • ${connection-name}: Set to the same connection name used when creating the connection.
  3. The response should look similar to this:

    [
    {
    "code": 200,
    "objectId": "vu9U3hXa3q0AAAABADJidWlsdGluOmh5cGVyc2NhbGVyLWF1dGhlbnRpY2F0aW9uLmNvbm5lY3Rpb25zLmF3cwAGdGVuYW50AAZ0ZW5hbnQAJDMwZTg0YzgyLWNhYm05tYE2Mi1hNDg2LWJhYmFiY2ZlM2NiML7vVN4V2t6t"
    }
    ]

    If the API call fails, verify the following:

    • You have the needed token permissions policy to access to the settings API.
    • Your settings platform token is valid and assigned to the correct Dynatrace environment/account.
    • You have set the same connection name.
    • The IAM role is assumable.
    • The objectId string used in the request is identical to the one set as the role trust policy external ID.

Create monitoring configuration

1. Get API schema version

The monitoring configuration API schema is versioned, which allows our platform to introduce new features and improve your experience.

  1. To construct a valid API call, prepare this API request to get your current active ${APISchemaVersion}:

    curl -X GET \
    "https://${your-environment-url}/platform/extensions/v2/extensions?filter=name='com.dynatrace.extension.da-aws'&add-fields=activeVersion" \
    -H "Accept: application/json" \
    -H "Authorization: Bearer ${your-bearer-token}"
  2. Replace the following placeholders with your values and run the API call:

    • ${your-environment-url}: Your full Dynatrace environment URL (for example, xyz12345.apps.dynatrace.com).
    • ${your-bearer-token}: Set the platform settings token you have created as part of the prerequisites.
  3. The response should look similar to this:

    {
    "items": [
    {
    "extensionName": "com.dynatrace.extension.da-aws",
    "version": "1.0.5",
    "activeVersion": "1.0.0"
    }
    ],
    "totalCount": 1
    }
  4. Use the activeVersion value as the value for ${APISchemaVersion} in the next step.

2. Create monitoring configuration

  1. Prepare this command:

    curl -X POST "https://${your-environment-url}/platform/extensions/v2/extensions/com.dynatrace.extension.da-aws/monitoring-configurations" \
    -H "accept: application/json" \
    -H "Authorization: Bearer ${your-bearer-token}" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d '
    {
    "scope": "integration-aws",
    "value": {
    "enabled": true,
    "description": "${configuration-name}",
    "version": "${APISchemaVersion}",
    "featureSets": [
    "ApplicationELB_essential",
    "AutoScaling_essential",
    "CloudFront_essential",
    "DynamoDB_essential",
    "EBS_essential",
    "EC2_essential",
    "ECS_essential",
    "Firehose_essential",
    "Lambda_essential",
    "NetworkELB_essential",
    "RDS_essential",
    "Route53_essential",
    "S3_essential",
    "SQS_essential"
    ],
    "aws": {
    "deploymentRegion": "${deployment-region}",
    "credentials": [
    {
    "enabled": true,
    "description": "my connection name",
    "connectionId": "${connectionId}",
    "accountId": "${aws-account-id}"
    }
    ],
    "regionFiltering": [
    "${monitored-region-a}",
    "${monitored-region-b}",
    "${monitored-region-n}"
    ],
    "metricsConfiguration": {
    "enabled": true,
    "regions": [
    "${monitored-region-a}",
    "${monitored-region-b}",
    "${monitored-region-n}"
    ]
    },
    "cloudWatchLogsConfiguration": {
    "enabled": false,
    "regions": []
    },
    "configurationMode": "QUICK_START",
    "deploymentScope": "SINGLE_ACCOUNT",
    "deploymentMode": "MANUAL",
    "manualDeploymentStatus": "COMPLETE",
    "automatedDeploymentStatus": "NA"
    }
    }
    }'
  2. Replace the following placeholders with your values and run the command:

    • ${your-environment-url}: Your full Dynatrace environment URL (for example, xyz12345.apps.dynatrace.com).
    • ${your-bearer-token}: Set the platform settings token you have created as part of the prerequisites.
    • ${configuration-name}: Name of the new monitoring configuration. Use only letters, numbers, and hyphens. It must start with a letter.
    • ${APISchemaVersion}: Use the latest API schema version.
    • ${connectionId}: The value of the objectId captured at the initial connection creation.
    • ${aws-account-id}: Numeric AWS account ID to monitor (for example, 123456789012).
    • regionFiltering/${monitored-region-a} … ${monitored-region-n}: AWS Regions from which you poll CloudWatch metrics and topology (monitored regions) (for example, us-east-1, eu-central-1).
    • metricsConfiguration/${monitored-region-a} … ${monitored-region-n}: Forward-compatibility field. This region list must be identical to regionFiltering (for example, us-east-1, eu-central-1).
    • cloudWatchLogsConfiguration.enabled: Keep false; relevant if onboarding via our IaC path.
    • ${deployment-region}: Deployment region for CloudFormation stack. Value cannot be empty but is ignored as CloudFormation deployment is not used for this scenario. Set value to either us-east-1 or one of monitored regions.
  3. The response should look similar to this:

    {
    "objectId": "5c1337ed-ewd9-34e8-9309-f8a20f99cade",
    "code": 201
    }
  4. For both regionFiltering and metricsConfiguration, the us-east-1 region must always be set, as the topology service polls for global AWS resources that reside only on us-east-1.

Related tags
Infrastructure Observability