AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Fetch & analyse tweets using AWS Comprehend

# Global Settings
Globals:
  Function:
    Timeout: 3
    Tags:
      application-id: "tweet-analysis"
  Api:
    Auth:
      ApiKeyRequired: true

Resources:

  ##
  ### START API GATEWAY CONFIGURATION ###
  ##

  # Create Api version v1
  V1Stage:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId: !Ref V1StageDeployment
      Description: Api version 1
      RestApiId: !Ref ServerlessRestApi
      StageName: v1
      Tags:
        - Key: "application-id"
          Value: "tweet-analysis"
        - Key: "Name"
          Value: "tweet-analysis::rest-api::v1"

  # Deploy Api version 1
  V1StageDeployment:
    Type: AWS::ApiGateway::Deployment
    Properties:
      Description: Deployment of Api version 1
      RestApiId: !Ref ServerlessRestApi

  # Create PaidUsagePlan usage plan
  PaidUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    Properties:
      ApiStages:
        - ApiId: !Ref ServerlessRestApi
          Stage: !Ref V1Stage
      Description: Api usage plan
      Quota:
        Limit: 10000
        Period: MONTH
      Throttle:
        BurstLimit: 100
        RateLimit: 20
      UsagePlanName: PaidUsagePlan
      Tags:
        - Key: "application-id"
          Value: "tweet-analysis"
        - Key: "Name"
          Value: "tweet-analysis::rest-api::paid-usage-plan"

  # Create Api key for PaidUsagePlan
  PaidApiKey:
    Type: AWS::ApiGateway::ApiKey
    Properties:
      Description: Api key for paid usage plan
      Enabled: true
      StageKeys:
        - RestApiId: !Ref ServerlessRestApi
          StageName: !Ref V1Stage
      Tags:
        - Key: "application-id"
          Value: "tweet-analysis"
        - Key: "Name"
          Value: "tweet-analysis::rest-api::key"

  # Attach the created api key to the usage plan
  PaidUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    Properties:
      KeyId: !Ref PaidApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref PaidUsagePlan

  # Create custom domain in Api Gateway
  Domain:
    Type: AWS::ApiGateway::DomainName
    Properties:
      RegionalCertificateArn: !Ref DomainCertificate
      DomainName: tweet-analysis.dennistech.io
      SecurityPolicy: TLS_1_2
      EndpointConfiguration:
        Types:
        - REGIONAL
      Tags:
        - Key: "application-id"
          Value: "tweet-analysis"
        - Key: "Name"
          Value: "tweet-analysis::api-custom-domain"

  ##
  ### END API CONFIGURATION ###
  ##

  ##
  ### START DOMAIN CONFIGURATION ###
  ##

  # Create domain SSL certificate
  DomainCertificate:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: tweet-analysis.dennistech.io
      ValidationMethod: DNS
      DomainValidationOptions:
        - DomainName: tweet-analysis.dennistech.io
          HostedZoneId: Z0937998E3C5GEK4NHO9
      Tags:
        - Key: "application-id"
          Value: "tweet-analysis"
        - Key: "Name"
          Value: "tweet-analysis::domain-certificate::dennistech.io"

  # Map tweet-analysis.dennistech.io to the regional domain generated by Api Gateway
  DomainMapping:
    Type: AWS::Route53::RecordSet
    Properties:
      Name: tweet-analysis.dennistech.io
      Comment: Map domain to the regional domain generated by Api Gateway
      HostedZoneId: Z0937998E3C5GEK4NHO9
      Type: A
      AliasTarget:
        DNSName: !GetAtt Domain.RegionalDomainName
        EvaluateTargetHealth: true
        HostedZoneId: !GetAtt Domain.RegionalHostedZoneId

  # Configure mapping in API Gateway custom domain to point to v1 stage
  PathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref Domain
      RestApiId: !Ref ServerlessRestApi
      Stage: v1

  ##
  ### END DOMAIN CONFIGURATION ###
  ##

  ##
  ### START FUNCTION CONFIGURATION ###
  ##

  # Define lambda functions
  GetTweetSentimentFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: GetTweetSentimentFunction
      Description: Fetch tweets and analyse sentiment using AWS Comprehend
      CodeUri: src/
      Handler: handlers/sentiment.get_tweet_sentiment
      Runtime: python3.9
      Policies:
        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn:
              arn:aws:secretsmanager:eu-west-2:339008578167:secret:tweet-analysis-keys-gKo6DQ
      Layers:
        - !Ref TweetAnalysisSharedFunctions
      Events:
        CallGetTweetSentiment:
          Type: Api
          Properties:
            Path: /sentiment
            Method: get
            RequestParameters:
              - method.request.querystring.twitterUser:
                  Required: false
              - method.request.querystring.numberOfTweets:
                  Required: false
      Tags:
        Name: "tweet-analysis::get-tweet-sentiment-function"

  # Define dependencies
  TweetAnalysisSharedFunctions:
    Type: AWS::Serverless::LayerVersion
    Properties:
      Description: Shared functions across lambda functions
      CompatibleRuntimes:
        - python3.9
      ContentUri: dependencies/

  ##
  ### END FUNCTION CONFIGURATION ###
  ##
