AWSTemplateFormatVersion: '2010-09-09'
Description: S3 to SNS to SQS notification pipeline with DLQ

Parameters:
  ResourcePrefix:
    Type: String
    Default: vectra
    Description: Prefix for all named resources (e.g., S3 bucket, topic, queue, etc.)

Resources:

  MyBucket:
    Type: AWS::S3::Bucket
    DependsOn:
      - MySNSTopic
      - MySNSTopicPolicy
    Properties:
      BucketName: !Sub "${ResourcePrefix}bucket"
      NotificationConfiguration:
        TopicConfigurations:
          - Event: s3:ObjectCreated:*
            Topic: !Ref MySNSTopic
      LifecycleConfiguration:
        Rules:
          - Id: ExpireObjectsAfterOneDay
            Status: Enabled
            ExpirationInDays: 1
            Prefix: "" # Applies to all objects

  MySNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub "${ResourcePrefix}topic"

  MySNSTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref MySNSTopic
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AllowS3ToPublish
            Effect: Allow
            Principal:
              Service: s3.amazonaws.com
            Action: sns:Publish
            Resource: !Ref MySNSTopic
            Condition:
              ArnLike:
                aws:SourceArn: !Sub "arn:aws:s3:::${ResourcePrefix}bucket"

  MyDeadLetterQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Sub "${ResourcePrefix}dlq"
      MessageRetentionPeriod: 900

  MySQSQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Sub "${ResourcePrefix}queue"
      VisibilityTimeout: 30
      MessageRetentionPeriod: 900
      MaximumMessageSize: 262144
      DelaySeconds: 0
      ReceiveMessageWaitTimeSeconds: 0
      RedrivePolicy:
        deadLetterTargetArn: !GetAtt MyDeadLetterQueue.Arn
        maxReceiveCount: 2

  MySQSQueuePolicy:
    Type: AWS::SQS::QueuePolicy
    Properties:
      Queues:
        - !Ref MySQSQueue
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AllowSNSPublish
            Effect: Allow
            Principal:
              Service: sns.amazonaws.com
            Action: sqs:SendMessage
            Resource: !GetAtt MySQSQueue.Arn
            Condition:
              ArnEquals:
                aws:SourceArn: !Ref MySNSTopic

  MySNSSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref MySNSTopic
      Protocol: sqs
      Endpoint: !GetAtt MySQSQueue.Arn
      RawMessageDelivery: true

  EC2InstanceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${ResourcePrefix}EC2AccessRole"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: !Sub "${ResourcePrefix}EC2S3SQSAccessPolicy"
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Sid: AllowGetS3Objects
                Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "arn:aws:s3:::${ResourcePrefix}bucket/*"
              - Sid: AllowListBucket
                Effect: Allow
                Action:
                  - s3:ListBucket
                Resource: !Sub "arn:aws:s3:::${ResourcePrefix}bucket"
              - Sid: AllowSQSAccess
                Effect: Allow
                Action:
                  - sqs:ReceiveMessage
                  - sqs:DeleteMessage
                  - sqs:GetQueueAttributes
                  - sqs:GetQueueUrl
                Resource:
                  - !Sub "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:${ResourcePrefix}queue"
                  - !Sub "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:${ResourcePrefix}dlq"

  EC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      InstanceProfileName: !Sub "${ResourcePrefix}InstanceProfile"
      Roles:
        - !Ref EC2InstanceRole

Outputs:
  BucketName:
    Description: Name of the S3 bucket
    Value: !Ref MyBucket

  SNSTopicARN:
    Description: ARN of the SNS topic
    Value: !Ref MySNSTopic

  SQSQueueURL:
    Description: URL of the SQS queue
    Value: !Ref MySQSQueue

  DLQURL:
    Description: URL of the Dead Letter Queue
    Value: !Ref MyDeadLetterQueue
