AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation to install Lambda and configure an API Gateway to trigger (fdp-1pd02apd4)
Parameters:
  BucketName:
    Default: S3BucketName
    Description: >-
      Bucket name containing the lambda code for Dynatrace notification
      processing
    Type: String
  BucketKey:
    Default: recieveDynaNotification.zip
    Description: Enter the filename of the lambda code in the S3 Bucket above
    Type: String
  RoleName:
    Default: recieveDynatraceLambdaExecRole
    Description: Enter the name of IAM execution role to be created for lambda execution
    Type: String
  ApiGatewayName:
    Default: recieveDynatraceApi
    Description: Enter the name of the Api Endpoint Name to be created
    Type: String
  ApiStage:
    Default: Dev
    Description: Enter the stage name to execute the test
    Type: String
  ApiKey:
    NoEcho: 'true'
    Description: >-
      Your Dynatrace API Token. If you dont have one create one first in your
      Dynatrace Web UI via Settings -> Integration -> Dynatrace API
    Type: String
  DynatraceTenant:
    Default: xyz90253
    Description: >-
      Your full Dynatrace Tenant URL. For SaaS it is e.g:
      https://<DynatraceTenant>.live.dynatrace.com
    Type: String
Resources:
  SaasInstanceName:
    Type: 'AWS::SSM::Parameter'
    Properties:
      Name: /Dynatrace/SaasInstanceName
      Type: String
      Value: !Join
        - ''
        - - 'https://'
          - !Ref DynatraceTenant
          - .live.dynatrace.com/api/v1/
      Description: Dynatrace SaaS Instance Name
  SaaSApiKey:
    Type: 'AWS::SSM::Parameter'
    Properties:
      Name: /Dynatrace/ApiKey
      Type: String
      Value: !Ref ApiKey
      Description: Dynatrace ApiKey
  S3BucketName:
    Type: 'AWS::SSM::Parameter'
    Properties:
      Name: /Dynatrace/S3BucketName
      Type: String
      Value: !Ref BucketName
      Description: S3 bucket to store temperory wrkfile
  ApprovedInstanceTypes:
    Type: 'AWS::SSM::Parameter'
    Properties:
      Name: /Dynatrace/ApprovedInstanceTypes
      Type: StringList
      Value: 't2.micro,t2.small,t2.medium,t2.large,t2.xlarge'
      Description: List of approved EC2 instance types
  CommonLambdaRole:
    Type: 'AWS::IAM::Role'
    Properties:
      Path: /
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AWSServiceCatalogAdminFullAccess'
        - 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess'
        - 'arn:aws:iam::aws:policy/AmazonSSMFullAccess'
        - 'arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess'
        - 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
      RoleName: !Ref RoleName
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: !Join
            - '-'
            - - !Ref RoleName
              - policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:GetLogEvents'
                  - 'logs:PutLogEvents'
                Resource:
                  !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/"
  recieveDynatraceLambda:
    Type: 'AWS::Lambda::Function'
    Properties:
      Description: Lambda function to process Dynatrace Notifications
      Code:
        S3Bucket: !Ref BucketName
        S3Key: !Ref BucketKey
      Role: !GetAtt
        - CommonLambdaRole
        - Arn
      Handler: recieveDynaNotification.process_event
      FunctionName: recieveDynatraceLambda
      Runtime: python3.7
      MemorySize: 512
      Timeout: 120
      Environment:
        Variables:
          Bucket: !Ref BucketName
  Lambdaeventpermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: 'lambda:InvokeFunction'
      FunctionName: !GetAtt
        - recieveDynatraceLambda
        - Arn
      Principal: 'apigateway.amazonaws.com'
  ApiGatewayRestApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: !Sub '${ApiGatewayName}-${ApiStage}'
      EndpointConfiguration:
        Types:
          - REGIONAL
  ApiGatewayResourceProxyVar:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      ParentId: !GetAtt
        - ApiGatewayRestApi
        - RootResourceId
      PathPart: dynanotify
      RestApiId: !Ref ApiGatewayRestApi
  RequestValidator:
    Type: 'AWS::ApiGateway::RequestValidator'
    Properties:
      Name: myRequestValidator
      RestApiId: !Ref ApiGatewayRestApi
      ValidateRequestBody: true
  dynTraceProblemNotify:
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref ApiGatewayRestApi
      ContentType: application/json
      Description: Dynatrace Problem Notification
      Name: dynTraceProblemNotify
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: dynTraceProblemNotify
        type: object
        properties:
          State:
            type: string
          PID:
            type: string
          ProblemTitle:
            type: string
  ApiGatewayMethodProxyVarAny:
    Type: 'AWS::ApiGateway::Method'
    DependsOn: dynTraceProblemNotify
    Properties:
      HttpMethod: POST
      RequestParameters: {}
      ResourceId: !Ref ApiGatewayResourceProxyVar
      RestApiId: !Ref ApiGatewayRestApi
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            text/plain: Empty
          ResponseParameters:
            method.response.header.Content-Type: true
            method.response.header.Content-Length: true
      ApiKeyRequired: true
      AuthorizationType: NONE
      RequestValidatorId: !Ref RequestValidator
      RequestModels:
        application/json: dynTraceProblemNotify
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS
        Uri: !Sub
          - >-
            arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaarn}/invocations
          - lambdaarn: !GetAtt
              - recieveDynatraceLambda
              - Arn
        RequestTemplates:
          application/json: |-
            #set($inputRoot = $input.path('$'))
            {
            "State" : "$inputRoot.State",
            "PID" : "$inputRoot.PID",
            "ProblemTitle" : "$inputRoot.ProblemTitle"
            }
        IntegrationResponses:
          - StatusCode: 200
            ResponseParameters:
              method.response.header.Content-Type: integration.response.body.headers.Content-Type
              method.response.header.Content-Length: integration.response.body.headers.Content-Length
        PassthroughBehavior: WHEN_NO_TEMPLATES
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    Properties:
      RestApiId: !Ref ApiGatewayRestApi
      StageName: !Ref ApiStage
    DependsOn:
      - ApiGatewayMethodProxyVarAny
  AppLambdaPermissionApiGateway:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName: !GetAtt
        - recieveDynatraceLambda
        - Arn
      Action: 'lambda:InvokeFunction'
      Principal: !Sub 'apigateway.${AWS::URLSuffix}'
      SourceArn: !Sub >-
        arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/*/*
  ApiKeyToUseAtDynatrace:
    Type: 'AWS::ApiGateway::ApiKey'
    DependsOn:
      - ApiGatewayDeployment
    Properties:
      Name: "ApiKeyToUseAtDynatrace"
      Description: "Key to use in Dynatrace for authentication to API Gateway"
      Enabled: "true"
      StageKeys:
        - RestApiId: !Ref ApiGatewayRestApi
          StageName: !Ref ApiStage
  UsagePlanForDynatraceApi:
    Type: 'AWS::ApiGateway::UsagePlan'
    DependsOn:
      - ApiGatewayDeployment
    Properties:
      ApiStages:
        - ApiId: !Ref ApiGatewayRestApi
          Stage: !Ref ApiStage
      Description: "Usage plan for Dynatrace Api"
      Quota:
        Limit: 500
        Period: WEEK
      Throttle:
        BurstLimit: 25
        RateLimit: 50
      UsagePlanName: UsagePlanForDynatraceApi
  UsagePlanKeyForDynatrace:
    Type: AWS::ApiGateway::UsagePlanKey
    DependsOn:
      - UsagePlanForDynatraceApi
    Properties :
      KeyId: !Ref ApiKeyToUseAtDynatrace
      KeyType: API_KEY
      UsagePlanId: !Ref UsagePlanForDynatraceApi
