AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  Name:
    Type: String
  HttpMethod:
    Type: String
    AllowedValues:
      - GET
      - HEAD
      - POST
      - OPTIONS
      - PUT
      - DELETE
      - PATCH
  InvocationLimit:
    Type: Number
    Default: 100
  ApiSecret:
    Type: String
    Description: Secret name for API key
  OrganizationId:
    Type: String
    Description: Organization ID

Resources:
  ApiDestination:
    Type: AWS::Events::ApiDestination
    Properties:
      Name: !Sub 'destination-${Name}'
      ConnectionArn: !GetAtt Connection.Arn
      Description: !Sub 'destination-${Name}'
      HttpMethod: !Ref HttpMethod
      InvocationEndpoint: !Sub '{{resolve:secretsmanager:${ApiSecret}:SecretString:ApiEndpoint}}'
      InvocationRateLimitPerSecond: !Ref InvocationLimit

  Connection:
    Type: AWS::Events::Connection
    Properties:
      AuthorizationType: API_KEY
      AuthParameters:
        ApiKeyAuthParameters:
          ApiKeyName: !Sub '{{resolve:secretsmanager:${ApiSecret}:SecretString:ApiKeyName}}'
          ApiKeyValue: !Sub '{{resolve:secretsmanager:${ApiSecret}:SecretString:ApiKeyValue}}'
      Description: !Sub 'connection-${Name}'
      Name: !Sub 'connection-${Name}'

  ProducerRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub 'rule-producer-${Name}'
      Description: 'Config rule for producer'
      EventPattern:
        source:
          - aws.config
        detail-type:
          - Config Configuration Item Change
        detail:
          messageType:
            - ConfigurationItemChangeNotification
          configurationItem:
            resourceType:
              - '*'
      State: 'ENABLED'
      Targets:
        - Id: !Sub 'root-account-${Name}'
          Arn: !GetAtt EventBus.Arn
          RoleArn: !GetAtt ProducerRole.Arn
        - Id: !Sub 'log-${Name}'
          Arn: !GetAtt ProducerLogGroup.Arn

  ProducerLogGroup:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/events/eventbridge/producer-${Name}'
      RetentionInDays: 7
      Tags:
        - Key: Name
          Value: !Sub 'eventbridge-producer-${Name}'

  ProducerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'role-producer-${Name}'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: AllowEventsToEventBridge
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              Effect: Allow
              Action:
                - events:PutEvents
              Resource: !GetAtt EventBus.Arn
        - PolicyName: AllowEventsToBeLogged
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              Effect: Allow
              Action:
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource: '*'

  ApiRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub 'api-rule-${Name}'
      Description: Rule to send events to API destination
      EventBusName: !GetAtt EventBus.Arn
      EventPattern:
        source:
          - aws.config
      State: 'ENABLED'
      Targets:
        - Id: !Sub 'apitarget-${Name}'
          Arn: !GetAtt ApiDestination.Arn
          RoleArn: !GetAtt ApiRole.Arn
        - Id: !Sub 'log-${Name}'
          Arn: !GetAtt ConsumerLogGroup.Arn

  ConsumerLogGroup:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/events/eventbridge/consumer-${Name}'
      RetentionInDays: 7

  ApiRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'role-apidestination-${Name}'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub 'policy-apidestination-${Name}'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: events:InvokeApiDestination
                Resource: !GetAtt ApiDestination.Arn
        - PolicyName: AllowEventsToBeLogged
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              Effect: Allow
              Action:
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource: '*'

  EventBusPolicy:
    Type: AWS::Events::EventBusPolicy
    Properties:
      EventBusName: !Ref EventBus
      StatementId: AllowAllAccountsInOrganizationToPutEvents
      Action: 'events:PutEvents'
      Principal: '*'
      Condition:
        Key: aws:PrincipalOrgID
        Type: StringEquals
        Value: !Ref OrganizationId

  EventBus:
    Type: AWS::Events::EventBus
    Properties:
      Name: !Sub 'eventbus-${Name}'

  LogPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyName: log-policy-EventBridge
      PolicyDocument: !Sub '{"Statement": [{"Action": ["logs:CreateLogStream","logs:PutLogEvents"],"Effect": "Allow","Principal": {"Service": ["events.amazonaws.com","delivery.logs.amazonaws.com"]},"Resource": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/events/*:*","Sid": "TrustEventsToStoreLogEvent"}],"Version": "2012-10-17"}'
