AWSTemplateFormatVersion: '2010-09-09'
Description: 'Dynatrace Data Acquisition - AWS events ingest  (v1.0.2 2026-03-05 11:57)'

Metadata:
  Version:
    Number: v1.0.2
    ReleaseDate: 2026-03-05 11:57

Parameters:
  pDynatraceUrl:
    Type: String
    Description: 'Your Dynatrace environment url'
    AllowedPattern: '^https:\/\/.+[^\/]$'
  pDtIngestToken:
    Type: String
    Description: 'Dynatrace platform token for events ingest'
    AllowedPattern: '(^dt0s16\.[A-Z0-9]{8}\.[A-Z0-9]{64}$)'
    NoEcho: true
  pEventBridgeBusName:
    Type: String
    Description: 'Name of the Amazon EventBridge bus from which to consume the events from'
    AllowedPattern: '^[a-zA-Z0-9._-]*$'
    MinLength: 1
    MaxLength: 256
    Default: 'default'
  pEventSources:
    Type: CommaDelimitedList
    Description: 'Comma-separated list of values of event sources to forward to Dynatrace (e.g. aws.ec2,aws.s3,aws.lambda)'
    Default: 'aws.health'
  pMonitoringConfigId:
    Type: String
    Description: 'ID of the Dynatrace AWS connection. Used only for visibility purposes.'
    Default: 'unknown'

Conditions:
  cCustomEventBus: !Not [ !Equals [ 'default', !Ref pEventBridgeBusName ]]
  cProductionEnvironment: !Equals [ !Select [ 2, !Split [ ".", !Select [ 1, !Split [ "://", !Ref pDynatraceUrl ] ] ] ], 'dynatrace' ]

Resources:
  DynatraceConnection:
    Type: AWS::Events::Connection
    Properties:
      Name: !Sub
        - 'DynatraceConnection-${DynatraceEnvironmentId}-${AWS::Region}-${DeploymentHash}'
        - { DeploymentHash: !Select [ 0, !Split [ '-', !Select [ 2, !Split [ '/', !Ref AWS::StackId ] ] ] ], DynatraceEnvironmentId: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ] }
      AuthorizationType: API_KEY
      AuthParameters:
        ApiKeyAuthParameters:
          ApiKeyName: Authorization
          ApiKeyValue: !Sub 'Bearer ${pDtIngestToken}'
        InvocationHttpParameters:
          HeaderParameters:
            - IsValueSecret: false
              Key: Dt-Tenant
              Value: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ]

  DynatraceApiDestination:
    Type: AWS::Events::ApiDestination
    Properties:
      Name: !Sub
        - 'DynatraceApiDestination-${DynatraceEnvironmentId}-${AWS::Region}-${DeploymentHash}'
        - { DeploymentHash: !Select [ 0, !Split [ '-', !Select [ 2, !Split [ '/', !Ref AWS::StackId ] ] ] ], DynatraceEnvironmentId: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ] }
      ConnectionArn: !GetAtt DynatraceConnection.Arn
      HttpMethod: POST
      InvocationEndpoint: !If
        - cProductionEnvironment
        - !Sub
          - 'https://${Subdomain}.da.dynatrace.com/api/aws/eventbridge/v1/events'
          - Subdomain: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "://", !Ref pDynatraceUrl ] ] ] ]
        - !Sub
          - 'https://${Subdomain}.da.dynatracelabs.com/api/aws/eventbridge/v1/events'
          - Subdomain: !Select [ 0, !Split [ ".apps", !Select [ 0, !Split [ ".dynatracelabs.com", !Select [ 1, !Split [ "://", !Ref pDynatraceUrl ] ] ] ] ] ]
      InvocationRateLimitPerSecond: 100

  DynatraceEventBridgeRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub
        - 'DynatraceEventBridgeRole-${DynatraceEnvironmentId}-${AWS::Region}-${DeploymentHash}'
        - { DeploymentHash: !Select [ 0, !Split [ '-', !Select [ 2, !Split [ '/', !Ref AWS::StackId ] ] ] ], DynatraceEnvironmentId: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ] }
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: 'events.amazonaws.com'
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: AllowInvokeHttpApi
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'events:InvokeApiDestination'
                Resource: !Sub ${DynatraceApiDestination.Arn}
      Tags:
        - Key: 'dt:CreatedBy'
          Value: 'Dynatrace'
        - Key: 'dt:EnvironmentID'
          Value: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ]

  DynatraceEventBridgeRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub
        - 'DynatraceEventBridgeRule-${DynatraceEnvironmentId}-${AWS::Region}-${DeploymentHash}'
        - { DeploymentHash: !Select [ 0, !Split [ '-', !Select [ 2, !Split [ '/', !Ref AWS::StackId ] ] ] ], DynatraceEnvironmentId: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ] }
      EventBusName: !If [ cCustomEventBus, !Ref pEventBridgeBusName, !Ref AWS::NoValue ]
      EventPattern:
        source: !Ref pEventSources
      Targets:
        - Arn: !GetAtt DynatraceApiDestination.Arn
          RoleArn: !GetAtt DynatraceEventBridgeRole.Arn
          Id: dynatrace
          RetryPolicy:
            MaximumRetryAttempts: 185
            MaximumEventAgeInSeconds: 86400
      Tags:
        - Key: 'dt:CreatedBy'
          Value: 'Dynatrace'
        - Key: 'dt:EnvironmentID'
          Value: !Select [ 0, !Split [ ".", !Select [ 1, !Split [ "https://", !Ref pDynatraceUrl ] ] ] ]

Outputs:
  DynatraceEventIngestTokenSecret:
    Value: !GetAtt DynatraceConnection.SecretArn
    Description: ARN of SecretsManager secret storing Dynatrace event ingest platform token
