AWSTemplateFormatVersion: '2010-09-09'
Description: LC Classified Cloudfront stack

Parameters:
  DisplayName:
    Description: Display name
    Type: String
    Default: lc-classified-cloudfront
  CloudfrontHostedZoneId:
    Description: Cloudfront Hosted zone ID
    Type: String
    Default: Z2FDTNDATAQYW2
  Environment:
    Type: String
    Default: dev
    AllowedValues:
    - dev
    - dev2
    - rec
    - rec2
    - prod
  TagBloc:
    Description: Tag bloc metier
    Type: String
    Default: classified
  TagApp:
    Description: Tag application
    Type: String
    Default: lcpab
  TagComp:
    Description: Tag composant
    Type: String
    Default: classified

Mappings:
  EnvironmentMap:
    dev:
      CertificateArn: arn:aws:acm:us-east-1:629307289374:certificate/3e2219cc-c2d0-432a-a29f-76e75c83698e
      Cname: ["lc-classified.dev-carboatservices.fr"]
      HostedZoneName: dev-carboatservices.fr
      ApiGatewayRestApi: 6rdvjf0sug
      DefaultTTL: 0
      MaxTTL: 0
      RuleIDJoubert: fcc66aa1-062b-4c63-a7f3-43c36213a06d
      RuleIDVPC: 630d1d64-d24e-470d-839b-176e5d633fea
    dev2:
      CertificateArn: arn:aws:acm:us-east-1:629307289374:certificate/edbf94b6-b651-4782-a236-f0c10875e76e
      Cname: ["lc-classified.dev2-carboatservices.fr"]
      HostedZoneName: dev2-carboatservices.fr
      ApiGatewayRestApi: knfiww2865
      DefaultTTL: 0
      MaxTTL: 0
      RuleIDJoubert: fcc66aa1-062b-4c63-a7f3-43c36213a06d
      RuleIDVPC: 630d1d64-d24e-470d-839b-176e5d633fea
    rec:
      Cname: ["lc-classified.rec-carboatservices.fr"]
      CertificateArn: arn:aws:acm:us-east-1:395174950964:certificate/00c901c6-d7ab-44e3-b0df-716542027a18
      HostedZoneName: rec-carboatservices.fr
      ApiGatewayRestApi: a1syj82sig
      DefaultTTL: 60
      MaxTTL: 60
      RuleIDJoubert: 66b53e97-617d-423a-b4dd-3a24d5ac0dc1
      RuleIDVPC: 39c8d012-b9d1-4fdc-99c3-a56adf70ac3d
    rec2:
      Cname: ["lc-classified.rec2-carboatservices.fr"]
      CertificateArn: arn:aws:acm:us-east-1:395174950964:certificate/fef0cd0a-797b-4340-a07b-ad5c7b50da48
      HostedZoneName: rec2-carboatservices.fr
      ApiGatewayRestApi: 96i4fc9lu1
      DefaultTTL: 60
      MaxTTL: 60
      RuleIDJoubert: 66b53e97-617d-423a-b4dd-3a24d5ac0dc1
      RuleIDVPC: 39c8d012-b9d1-4fdc-99c3-a56adf70ac3d
    prod:
      Cname: ["lc-classified.carboatservices.fr"]
      CertificateArn: arn:aws:acm:us-east-1:395174950964:certificate/6cf5caf4-27dc-4a23-a619-e31e26706b7e
      HostedZoneName: carboatservices.fr
      ApiGatewayRestApi: 853l2fpahb
      DefaultTTL: 300
      MaxTTL: 300
      RuleIDJoubert: 66b53e97-617d-423a-b4dd-3a24d5ac0dc1
      RuleIDVPC: d65b7f63-3dea-4afd-8a77-7d6330467a28

Resources:
####################
## Config for WAF ##
####################
  WafOpenEndpoint:
    Type: AWS::WAF::ByteMatchSet
    Properties:
      Name: !Sub '${DisplayName}-endpoint-${Environment}'
      ByteMatchTuples:
        - FieldToMatch:
            Type: URI
          PositionalConstraint: STARTS_WITH
          TargetString: "/seller-contact-*"
          TextTransformation: LOWERCASE
        - FieldToMatch:
            Type: URI
          PositionalConstraint: STARTS_WITH
          TargetString: "/classified-share-by-email"
          TextTransformation: LOWERCASE
  WAFRuleJoubert:
    Type: "AWS::WAF::Rule"
    Properties:
      Name: !Sub '${DisplayName}-joubert-${Environment}'
      MetricName: !Sub 'lcclassified${Environment}'
      Predicates:
        - DataId: !FindInMap [EnvironmentMap, !Ref Environment, RuleIDJoubert]
          Negated: false
          Type: "IPMatch"
  WAFRuleVpc:
    Type: "AWS::WAF::Rule"
    Properties:
      Name: !Sub '${DisplayName}-vpc-${Environment}'
      MetricName: !Sub 'lcclassified${Environment}'
      Predicates:
        - DataId: !FindInMap [EnvironmentMap, !Ref Environment, RuleIDVPC]
          Negated: false
          Type: "IPMatch"
  WAFRuleEndpoint: 
    Type: "AWS::WAF::Rule"
    Properties: 
      Name: !Sub '${DisplayName}-url-${Environment}'
      MetricName: !Join ["", !Split ["-", !Sub '${DisplayName}-${Environment}']]
      Predicates: 
        - DataId: !Ref "WafOpenEndpoint"
          Negated: false
          Type: "ByteMatch"

  WebACLInternal:
    Type: "AWS::WAF::WebACL"
    Properties:
      DefaultAction:
        Type: BLOCK
      MetricName: !Sub 'lcclassifiedWebACLInternal${Environment}'
      Name: !Sub '${DisplayName}-WebACL-${Environment}'
      Rules:
        - RuleId: !Ref WAFRuleJoubert
          Priority: 1
          Action:
            Type: ALLOW
        - RuleId: !Ref WAFRuleVpc
          Priority: 2
          Action:
            Type: ALLOW
        - RuleId: !Ref WAFRuleEndpoint
          Priority: 3
          Action:
            Type: ALLOW

###########################
## Config for CloudFront ##
###########################
  CloudfrontDistribution:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      DistributionConfig:
        Aliases: !FindInMap [EnvironmentMap, !Ref Environment, Cname]
        Enabled: true
        WebACLId: !Ref WebACLInternal
        HttpVersion: http2
        CustomErrorResponses:
          - ErrorCode: 400
            ErrorCachingMinTTL: 0
          - ErrorCode: 403
            ErrorCachingMinTTL: 0
          - ErrorCode: 404
            ErrorCachingMinTTL: 0
          - ErrorCode: 500
            ErrorCachingMinTTL: 0
          - ErrorCode: 502
            ErrorCachingMinTTL: 0
          - ErrorCode: 503
            ErrorCachingMinTTL: 0
          - ErrorCode: 504
            ErrorCachingMinTTL: 0
        Comment: !Join [' ', [ "lc-classified", !Ref 'Environment']]
        Logging:
          Bucket: !Sub log-cloudfront.${Environment}.s3.amazonaws.com
          IncludeCookies: false
          Prefix: lc-classified
        Origins:
        - DomainName: !Join ['', [!FindInMap [EnvironmentMap, !Ref Environment, ApiGatewayRestApi], ".execute-api.eu-west-1.amazonaws.com"]]
          OriginPath: !Sub /${Environment}
          Id: !Sub lc-classified-apigateway-${Environment}
          CustomOriginConfig:
            HTTPPort: 80
            HTTPSPort: 443
            OriginProtocolPolicy: https-only
            OriginReadTimeout: 10
            OriginSSLProtocols:
            - TLSv1
            - TLSv1.1
            - TLSv1.2
        PriceClass: PriceClass_100
        ViewerCertificate:
          AcmCertificateArn: !FindInMap [EnvironmentMap, !Ref Environment, CertificateArn]
          SslSupportMethod: sni-only
          MinimumProtocolVersion: TLSv1.1_2016
        DefaultCacheBehavior:
          TargetOriginId: !Sub lc-classified-apigateway-${Environment}
          SmoothStreaming: false
          AllowedMethods:
            - HEAD
            - GET
            - OPTIONS
          CachedMethods:
            - HEAD
            - GET
            - OPTIONS
          Compress: true
          MinTTL: 0
          MaxTTL: !FindInMap [EnvironmentMap, !Ref Environment, MaxTTL]
          DefaultTTL: !FindInMap [EnvironmentMap, !Ref Environment, DefaultTTL]
          ForwardedValues:
            Cookies:
              Forward: none
            Headers:
              - Origin
              - X-Client-Source
              - Client-Type
            QueryString: true
            QueryStringCacheKeys:
              - id
              - cuRef
              - vertical
              - abtesting
          ViewerProtocolPolicy: redirect-to-https
        CacheBehaviors:
          - PathPattern: /seller-contact-*
            AllowedMethods:
              - HEAD
              - GET
              - OPTIONS
            Compress: true
            ForwardedValues:
              QueryString: true
              Cookies:
                Forward: all
              Headers:
                - Client-type
                - User-Agent
                - X-Forwarded-For
            DefaultTTL: 0
            MaxTTL: 0
            MinTTL: 0
            SmoothStreaming: false
            TargetOriginId: !Sub lc-classified-apigateway-${Environment}
            ViewerProtocolPolicy: redirect-to-https

          - PathPattern: /sondage
            AllowedMethods:
              - HEAD
              - GET
              - OPTIONS
            Compress: true
            ForwardedValues:
              Cookies:
                Forward: none
              QueryString: true
              QueryStringCacheKeys:
                - vertical
            MinTTL: 0
            MaxTTL: !FindInMap [EnvironmentMap, !Ref Environment, MaxTTL]
            DefaultTTL: !FindInMap [EnvironmentMap, !Ref Environment, DefaultTTL]
            SmoothStreaming: false
            TargetOriginId: !Sub lc-classified-apigateway-${Environment}
            ViewerProtocolPolicy: redirect-to-https

          - PathPattern: /main-informations-price-evolution
            AllowedMethods:
              - HEAD
              - GET
              - OPTIONS
            Compress: true
            ForwardedValues:
              Headers:
                - Client-type
              Cookies:
                Forward: none
              QueryString: true
              QueryStringCacheKeys:
                - id
                - dt
            MinTTL: 0
            MaxTTL: !FindInMap [EnvironmentMap, !Ref Environment, MaxTTL]
            DefaultTTL: !FindInMap [EnvironmentMap, !Ref Environment, DefaultTTL]
            SmoothStreaming: false
            TargetOriginId: !Sub lc-classified-apigateway-${Environment}
            ViewerProtocolPolicy: redirect-to-https
          - AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
            - PUT
            - POST
            - PATCH
            - DELETE
            PathPattern: /classified-share-by-email
            Compress: true
            ForwardedValues:
              QueryString: false
              Cookies:
                Forward: none
              # Headers:
            DefaultTTL: 0
            MaxTTL: 0
            MinTTL: 0
            SmoothStreaming: false
            TargetOriginId: !Sub lc-classified-apigateway-${Environment}
            ViewerProtocolPolicy: redirect-to-https
      Tags:
        - Key: Env
          Value: !Ref Environment
        - Key: Bloc
          Value: !Ref TagBloc
        - Key: Comp
          Value: !Ref TagComp
        - Key: App
          Value: !Ref TagApp

  CloudfrontDNSName:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneName: !Join ['', [!FindInMap [EnvironmentMap, !Ref Environment, HostedZoneName], .]]
      RecordSets:
      - Name: !Join ['.', ['lc-classified', !FindInMap [EnvironmentMap, !Ref Environment, HostedZoneName]]]
        Type: A
        AliasTarget:
          HostedZoneId: !Ref CloudfrontHostedZoneId
          DNSName: !GetAtt [CloudfrontDistribution, DomainName]
