AWSTemplateFormatVersion: "2010-09-09"
Description: "A cloudformation template for deploying NephoSec's custom Wiz integration for sending custom email notifications based on Wiz findings."
#TODO - Currently cannot manage SES identity authorization policy via cloudformation
#https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/1576

Parameters:
#  SesIdentityArn:
#    Type: String
#    Description: "The ARN of the SES Identity that the lambda function will use to send email. For use when SES identity is already configured."

  EmailIdentity:
    Type: String
    Description: "The email address that will be used for sending email notifications. YOU MUST HAVE ACCESS TO THE INBOX!"
    #https://devops.stackexchange.com/questions/2914/allowedpattern-for-emails-in-cloudformation-template
    ConstraintDescription: '[^@]+@[^@]+\.[^@]+'

  ExistingSESIdentity:
    Type: String
    AllowedValues: [
      "true",
      "false"
    ]
    Description: "Select true if the SES identity (Email address) provided above already exists. Otherwise select false and cloudformation will create/manage the SES identity."

  SenderFirstName:
    Type: String
    Description: "The first name of the PoC for license related issues (i.e. users are receiving expired license notifications so contact this PoC."

  SenderLastName:
    Type: String
    Description: "The last name of the PoC for license related issues (i.e. users are receiving expired license notifications so contact this PoC."

  SNSRoleExternalID:
    Type: String
    Description: "This string is an unique ID provided by Wiz when creating an SNS integration. It is used to restrict who can assume this IAM role after creation."

  SNSRoleAccountID:
    Type: String
    Description: "This is an AWS account ID provided by Wiz when creating an SNS integration. It is used to restrict who can assume this IAM role after creation."

Conditions:
  CreateSESIdentity: !Equals
    - !Ref ExistingSESIdentity
    - false

Outputs:
  SNSTopicArn:
    Value: !Ref NephoSecCustomEmailIntegrationSNSTopic
    Description: The ARN of the SNS Topic

  SESIdentityPrincipalArn:
    Value: !GetAtt "NephoSecCustomEmailIntegrationLambdaRole.Arn"
    Description: The Principal ARN for the SES identity policy.

  SESIdentityResourceARN:
    Value: !Sub "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${EmailIdentity}"
    Description: The Resource ARN for the SES identity policy.

  SNSIntegrationRoleArn:
    Value: !GetAtt "NephoSecCustomEmailIntegrationSNSRole.Arn"
    Description: "This role ARN is needed for creating a Wiz SNS Integration."

Resources:
  NephoSecCustomEmailIntegrationSQSQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: NephoSecCustomEmailIntegrationQueue
      VisibilityTimeout: 300
      RedrivePolicy:
        deadLetterTargetArn: !GetAtt NephoSecCustomEmailIntegrationDeadLetterQueue.Arn
        maxReceiveCount: 5

  NephoSecCustomEmailIntegrationDeadLetterQueue:
      Type: AWS::SQS::Queue

  NephoSecCustomEmailIntegrationSQSPolicy:
    Type: AWS::SQS::QueuePolicy
    Properties:
      Queues:
        - !Ref NephoSecCustomEmailIntegrationSQSQueue
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal: "*"
            Action: "SQS:SendMessage"
            Resource: !GetAtt NephoSecCustomEmailIntegrationSQSQueue.Arn
            Condition:
              ArnEquals:
                aws:SourceArn: !Ref NephoSecCustomEmailIntegrationSNSTopic

  NephoSecCustomEmailIntegrationSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: NephoSecCustomEmailIntegrationSNSTopicDisplayName
      TopicName: NephoSecCustomEmailIntegrationTopic

  NephoSecCustomEmailIntegrationSNSSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Protocol: sqs
      Endpoint: !GetAtt NephoSecCustomEmailIntegrationSQSQueue.Arn
      TopicArn: !Ref NephoSecCustomEmailIntegrationSNSTopic
      RawMessageDelivery: true

  NephoSecCustomEmailIntegrationEventSourceMapping:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      EventSourceArn: !GetAtt NephoSecCustomEmailIntegrationSQSQueue.Arn
      FunctionName: !Ref NephoSecCustomEmailIntegrationLambda
      Enabled: true

  #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html
  NephoSecCustomEmailIntegrationLambda:
    Type: AWS::Lambda::Function
    Properties:
      Architectures: ["x86_64"]
      Code:
        ImageUri: !Sub "905418169938.dkr.ecr.${AWS::Region}.amazonaws.com/email-container-test:latest"
      Environment:
        Variables:
          SENDER_ADDRESS: !Ref EmailIdentity
          SENDER_IDENTITY: !Sub "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${EmailIdentity}"
          SENDER_FIRST_NAME: !Ref SenderFirstName
          SENDER_LAST_NAME: !Ref SenderLastName
          SECRET_NAME: !Ref NephoSecCustomEmailIntegrationSecret
          LICENSE_KEY: ""
      Timeout: 180
      DeadLetterConfig:
        TargetArn: !GetAtt NephoSecCustomEmailIntegrationDeadLetterQueue.Arn
      Description: "This lambda handles requests from the a Wiz webhook integration and formats the data into an email template to notify a point of contact about a cloud resource finding."
      FunctionName: "NephoSecCustomEmailIntegrationLambda"
      LoggingConfig:
        LogGroup: !Ref NephoSecCustomEmailIntegrationLambdaLogGroup
      PackageType: Image
      Role: !GetAtt "NephoSecCustomEmailIntegrationLambdaRole.Arn"

  NephoSecCustomEmailIntegrationLambdaRole:
    #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - 'sts:AssumeRole'
      RoleName: "NephoSecCustomEmailIntegrationLambdaRole"

  NephoSecCustomEmailIntegrationRolePolicy:
    #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - 'ses:SendEmail'
              - 'ses:SendTemplatedEmail'
              - 'ses:SendRawEmail'
            Resource:
              - !Sub "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${EmailIdentity}"
          - Effect: Allow
            Action:
              - 'ses:GetTemplate'
            Resource:
              - "*"
          - Effect: Allow
            Action:
              - 'logs:CreateLogStream'
              - "logs:CreateLogGroup"
              - 'logs:PutLogEvents'
            Resource: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/NephoSecCustomEmailIntegrationLambda:*"
          - Effect: Allow
            Action:
              - "ecr:BatchGetImage"
              - "ecr:GetDownloadUrlForLayer"
            Resource: "*"
          - Effect: Allow
            Action:
              - "sqs:ReceiveMessage"
              - "sqs:DeleteMessage"
              - "sqs:GetQueueAttributes"
            Resource: "*"
          - Effect: Allow
            Action:
              - "sqs:SendMessage"
            Resource: "*"
          - Effect: Allow
            Action:
              - "secretsmanager:GetSecretValue"
              - "secretsmanager:DescribeSecret"
              - "secretsmanager:PutSecretValue"
            Resource: !Ref NephoSecCustomEmailIntegrationSecret
      ManagedPolicyName: "NephoSecCustomEmailIntegrationLambdaRolePolicy"
      Roles:
        - !Ref NephoSecCustomEmailIntegrationLambdaRole

  NephoSecCustomEmailIntegrationLambdaLogGroup:
    #https://stackoverflow.com/questions/39231592/specify-log-group-for-an-aws-lambda
    #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-loggroup.html
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: "/aws/lambda/NephoSecCustomEmailIntegrationLambda"
      RetentionInDays: 90

  CustomerSESIdentity:
    #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ses-emailidentity.html#cfn-ses-emailidentity-emailidentity
    Type: AWS::SES::EmailIdentity
    Condition: CreateSESIdentity
    Properties:
      FeedbackAttributes:
        EmailForwardingEnabled: true
      EmailIdentity: !Ref EmailIdentity

  NephoSecCustomEmailIntegrationSecret:
    #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-secret.html
    Type: AWS::SecretsManager::Secret
    Properties:
      "Description": The license file for the NephoSec Wiz Customer Email Integration.
      "KmsKeyId": "alias/aws/secretsmanager"
      "Name": "NSEC-WCEI-License"

  NephoSecCustomEmailIntegrationResourcePolicy:
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-resourcepolicy.html#cfn-secretsmanager-resourcepolicy-blockpublicpolicy
    Type: AWS::SecretsManager::ResourcePolicy
    Properties:
      BlockPublicPolicy: true
      ResourcePolicy: !Sub '{
                              "Version": "2012-10-17",
                              "Statement": [
                                  {
                                      "Effect": "Allow",
                                      "Principal": {
                                          "AWS": "${NephoSecCustomEmailIntegrationLambdaRole.Arn}"
                                      },
                                      "Action": "secretsmanager:GetSecretValue",
                                      "Resource": "${NephoSecCustomEmailIntegrationSecret}"
                                  }
                              ]
                          }'
      SecretId: !Ref NephoSecCustomEmailIntegrationSecret

  NephoSecCustomEmailIntegrationSNSPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - 'sns:Publish'
            Resource:
              - !Ref NephoSecCustomEmailIntegrationSNSRole


  NephoSecCustomEmailIntegrationSNSRole:
    #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - 'sts:AssumeRole'
      RoleName: "WizAccess-SNSIntegration-WizEmailIntegrationModule"