AWSTemplateFormatVersion: 2010-09-09
Description: Configures CloudWatch metric stream and Kinesis Data Firehose to send metrics to Oodle
Parameters: 
  OodleApiKey:
    Type: String
    Description: Oodle API key
    NoEcho: true
    MaxLength: 40
  OodleHttpEndpoint:
    Type: String
    Description: Oodle HTTP endpoint URL
Resources:
  S3BackupBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Join ['-', ['oodle-metric-stream-backup' , !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
  Firehose:
    Type: AWS::KinesisFirehose::DeliveryStream
    Properties:
      DeliveryStreamName: !Join ['-', ['OodleFirehose', !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
      DeliveryStreamType: DirectPut
      HttpEndpointDestinationConfiguration:
        RequestConfiguration:
          ContentEncoding: NONE
        EndpointConfiguration:
          Name: Oodle
          Url: !Ref OodleHttpEndpoint
          AccessKey: !Ref OodleApiKey
        BufferingHints:
          IntervalInSeconds: 60
          SizeInMBs: 1
        RetryOptions:
          DurationInSeconds: 60
        S3BackupMode: FailedDataOnly
        S3Configuration:
          CompressionFormat: GZIP
          BucketARN: !GetAtt S3BackupBucket.Arn
          RoleARN: !GetAtt FirehoseRole.Arn
          CloudWatchLoggingOptions:
            Enabled: true
            LogGroupName: !Join ['-', ['/aws/kinesisfirehose/OodleFirehose', !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
            LogStreamName: 'BackupDelivery'
        RoleARN: !GetAtt FirehoseRole.Arn
        CloudWatchLoggingOptions:
          Enabled: true
          LogGroupName: !Join ['-', ['/aws/kinesisfirehose/OodleFirehose', !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
          LogStreamName: 'DestinationDelivery'
  MetricStreamRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument: 
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service:
              - streams.metrics.cloudwatch.amazonaws.com 
            Action: 
              - 'sts:AssumeRole'
            Condition:
              StringEquals:
                'sts:ExternalId': !Ref AWS::AccountId
      Path: /service-role/
      Policies:
        - PolicyName: MetricStreams-FirehosePutRecords
          PolicyDocument: 
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - 'firehose:PutRecord'
                  - 'firehose:PutRecordBatch'
                Resource: !GetAtt Firehose.Arn
      Description: Role to allow a metric stream put metrics into a firehose
      RoleName: !Join ['-', ['OodleMetricStreamRole', !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
  FirehoseRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument: 
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service:
              - firehose.amazonaws.com 
            Action: 
              - 'sts:AssumeRole'
      Path: /service-role/
      Policies:
        - PolicyName: Firehose-S3Access
          PolicyDocument: 
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - 's3:AbortMultipartUpload'
                  - 's3:GetBucketLocation'
                  - 's3:GetObject'
                  - 's3:ListBucket'
                  - 's3:ListBucketMultipartUploads'
                  - 's3:PutObject'
                Resource: 
                  - !GetAtt S3BackupBucket.Arn
                  - !Join ['', [!GetAtt S3BackupBucket.Arn, '/*']]
      Description: Role to allow firehose stream put events into S3 backup bucket
      RoleName: !Join ['-', ['OodleFirehoseRole', !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
  MetricStream:
    Type: AWS::CloudWatch::MetricStream
    Properties:
      Name: !Join ['-', ['OodleMetricStream', !Select [0, !Split ['-', !Select [2, !Split ['/', !Ref 'AWS::StackId' ]]]]]]
      FirehoseArn: !GetAtt Firehose.Arn
      RoleArn: !GetAtt MetricStreamRole.Arn
      OutputFormat: 'opentelemetry1.0'
      IncludeLinkedAccountsMetrics: false
      IncludeFilters:
        - Namespace: AWS/S3
          MetricNames:
            - NumberOfObjects
        - Namespace: AWS/EC2