AWSTemplateFormatVersion: '2010-09-09'

Description: >
  Script to create S3 bucket, DNS (Route53) and Cloudfront distribution.

###############################################################################
Parameters:
###############################################################################

  DomainName:
    Type: String
    Description: The domain name.
    Default: 'beta.ordbok.aws.uib.no'
    AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
    ConstraintDescription: must be a valid DNS zone name

  AltDomainName:
    Type: String
    Description: The domain name.
    Default: 'beta.ordbok.uib.no'
    AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
    ConstraintDescription: must be a valid DNS zone name

  PriceClass:
    Type: String
    Description: The CloudFront distribution price class
    Default: 'PriceClass_100'
    AllowedValues:
      - 'PriceClass_100'
      #- 'PriceClass_200'
      #- 'PriceClass_All'

  CertificateArn:
    Type: String


###############################################################################
Resources:
###############################################################################
  DNS:
    Type: "AWS::Route53::RecordSet"
    Properties:
      HostedZoneName: !Sub "${DomainName}."
      Name: !Ref DomainName
      Type: A
      AliasTarget:
        HostedZoneId: Z2FDTNDATAQYW2
        DNSName: !GetAtt Distribution.DomainName

  WebBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "${AWS::StackName}.aws.uib.no"
      VersioningConfiguration:
        Status: Enabled
      Tags:
        - Key: Application
          Value: !Ref DomainName


  BucketPolicy:
    Type: "AWS::S3::BucketPolicy"
    Properties:
      Bucket: !Ref WebBucket
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Action: s3:*
            Resource: !Join ['', ['arn:aws:s3:::', !Ref 'WebBucket', /*]]
            Principal:
              CanonicalUser: !GetAtt CloudFrontOriginIdentity.S3CanonicalUserId

  ITAIpSet:
    Type: "AWS::WAF::IPSet"
    Properties:
      IPSetDescriptors:
      - Type: "IPV4"
        Value: "129.177.0.0/16"
      - Type: "IPV4"
        Value: "82.134.66.114/32"
      Name: "allowed IPs"

  ITARule:
    Type: "AWS::WAF::Rule"
    Properties:
      MetricName: "ITARule"
      Name: "ITARule"
      Predicates:
      - Type: "IPMatch"
        Negated: false
        DataId: !Ref ITAIpSet

  ACL:
    Type: "AWS::WAF::WebACL"
    Properties:
      DefaultAction:
        Type: "BLOCK"
      Name: "intern ITA"
      MetricName: "WebACL"
      Rules:
        - Action:
            Type: "ALLOW"
          Priority: 1
          RuleId: !Ref ITARule

  Distribution:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      DistributionConfig:
        Enabled: true
        HttpVersion: http2
        PriceClass: !Ref PriceClass
        DefaultRootObject: index.html
        Origins:
        - DomainName: !Sub "${WebBucket}.s3-${AWS::Region}.amazonaws.com"
          Id: s3ProductionBucket
          S3OriginConfig:
            OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOriginIdentity}"
        - Id: OrdbokCache
          DomainName: "ycyevfqwnk.execute-api.eu-west-1.amazonaws.com"
          OriginPath: "/DEV/cache"
          CustomOriginConfig:
            OriginProtocolPolicy: https-only
            OriginKeepaliveTimeout: 60
        Aliases:
        - !Ref DomainName
        - !Ref AltDomainName
        CustomErrorResponses:
          - ErrorCachingMinTTL: 300
            ErrorCode: 403
            ResponseCode: 200
            ResponsePagePath: /index.html
          - ErrorCachingMinTTL: 300
            ErrorCode: 404
            ResponseCode: 200
            ResponsePagePath: /index.html
        DefaultCacheBehavior:
          AllowedMethods:
          - GET
          - HEAD
          Compress: true
          TargetOriginId: s3ProductionBucket
          ForwardedValues:
            QueryString: 'false'
            Cookies:
              Forward: none
          ViewerProtocolPolicy: redirect-to-https
        CacheBehaviors:
          - PathPattern: "/api/article/*"
            AllowedMethods:
              - HEAD
              - DELETE
              - POST
              - GET
              - OPTIONS
              - PUT
              - PATCH
            MaxTTL: 0
            DefaultTTL: 0
            MinTTL: 0
            TargetOriginId: OrdbokCache
            LambdaFunctionAssociations:
              - EventType: viewer-request
                IncludeBody: false
                LambdaFunctionARN: "arn:aws:lambda:us-east-1:156160966877:function:path_rewrite:2"
            ForwardedValues:
              QueryString: true
              Cookies:
                Forward: all
            ViewerProtocolPolicy: redirect-to-https
        ViewerCertificate:
          AcmCertificateArn: !Ref CertificateArn
          MinimumProtocolVersion: TLSv1.1_2016
          SslSupportMethod: sni-only
        WebACLId: !Ref ACL
      Tags:
        - Key: Application
          Value: !Ref DomainName

  CloudFrontOriginIdentity:
    Type: "AWS::CloudFront::CloudFrontOriginAccessIdentity"
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: "origin identity"
