{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "dnsName": {
      "Type": "String",
      "Description": "The full DNS name for the site."
    },
    "hostedZoneId": {
      "Type": "AWS::Route53::HostedZone::Id",
      "Description": "The hostedZone ID"
    }
  },

  "Resources": {
    "S3Bucket": {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "BucketName": { "Ref": "dnsName" },
        "Tags" : [
          {
          "Key": "Service",
          "Value": { "Ref": "dnsName" }
          }
        ]
      }
    },

    "CloudFrontOriginAccessIdentity": {
      "Type" : "AWS::CloudFront::CloudFrontOriginAccessIdentity",
      "Properties" : {
        "CloudFrontOriginAccessIdentityConfig" : {
          "Comment": { "Ref": "dnsName" }
        }
      }
    },

    "S3BucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": { "Ref": "dnsName" },
        "PolicyDocument" : {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid":"Grant a CloudFront Origin Identity access to support private content",
              "Effect":"Allow",
              "Principal":{
                "CanonicalUser": { "Fn::GetAtt": [ "CloudFrontOriginAccessIdentity", "S3CanonicalUserId" ] }
              },
              "Action":"s3:GetObject",
              "Resource": { "Fn::Sub": "arn:aws:s3:::${dnsName}/*" }
            }
          ]
        }
      }
    },

    "AcmCertificate": {
      "Type": "AWS::CertificateManager::Certificate",
      "Properties": {
        "DomainName": { "Fn::Sub": "${dnsName}" },
        "SubjectAlternativeNames": [
          { "Fn::Sub": "*.${dnsName}" }
        ],
        "ValidationMethod": "DNS",
        "DomainValidationOptions": [
          {
            "DomainName": { "Fn::Sub": "${dnsName}" },
            "HostedZoneId": { "Ref": "hostedZoneId" }
          },
          {
            "DomainName": { "Fn::Sub": "*.${dnsName}" },
            "HostedZoneId": { "Ref": "hostedZoneId" }
          }
        ]
      }
    },

    "CloudFrontDistribution": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "DefaultRootObject": "index.html",
          "Aliases": [
            { "Fn::Sub": "tst.${dnsName}" },
            { "Ref": "dnsName" },
            { "Fn::Sub": "*.${dnsName}" }
          ],
          "HttpVersion": "http2and3",
          "PriceClass": "PriceClass_200",
          "Origins": [
            {
              "OriginPath": "/v1",
              "DomainName": { "Fn::Sub": "${dnsName}.s3.amazonaws.com" },
              "Id": "S3",
              "S3OriginConfig": {
                "OriginAccessIdentity": { "Fn::Sub": "origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}" }
              }
            },
            {
              "DomainName": { "Fn::Sub": "${dnsName}.s3.amazonaws.com" },
              "Id": "TST-S3",
              "S3OriginConfig": {
                "OriginAccessIdentity": { "Fn::Sub": "origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}" }
              }
            }
          ],
          "CacheBehaviors": [
            {
              "AllowedMethods": ["GET", "HEAD", "OPTIONS", "PUT", "PATCH", "POST", "DELETE"],
              "Compress": true,
              "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
            "OriginRequestPolicyId": "88a5eaf4-2fd4-4709-b370-b4c650ea3fcf",
              "PathPattern": "PR-*/*",
              "TargetOriginId": "TST-S3",
              "ViewerProtocolPolicy": "redirect-to-https"
            }
          ],
          "Enabled": true,
          "ViewerCertificate": {
            "AcmCertificateArn": { "Ref": "AcmCertificate" },
            "MinimumProtocolVersion": "TLSv1.2_2021",
            "SslSupportMethod": "sni-only"
          },
          "DefaultCacheBehavior": {
            "Compress": true,
            "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
            "OriginRequestPolicyId": "88a5eaf4-2fd4-4709-b370-b4c650ea3fcf",
            "TargetOriginId": "S3",
            "ViewerProtocolPolicy": "redirect-to-https"
          },
          "CustomErrorResponses": [
            {
              "ErrorCode" : 403,
              "ErrorCachingMinTTL" : 300,
              "ResponseCode" : 200,
              "ResponsePagePath" : "/index.html"
            },
            {
              "ErrorCode" : 404,
              "ErrorCachingMinTTL" : 300,
              "ResponseCode" : 200,
              "ResponsePagePath" : "/index.html"
            }
          ]
        }
      }
    },

    "TestRoute53": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "AliasTarget": {
          "DNSName": { "Fn::GetAtt" : [ "CloudFrontDistribution", "DomainName" ] },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": { "Ref": "hostedZoneId" },
        "Name":  { "Fn::Sub": "tst.${dnsName}." },
        "Type": "A"
      }
    },

    "TestRoute53Ipv6": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "AliasTarget": {
          "DNSName": { "Fn::GetAtt" : [ "CloudFrontDistribution", "DomainName" ] },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": { "Ref": "hostedZoneId" },
        "Name":  { "Fn::Sub": "tst.${dnsName}." },
        "Type": "AAAA"
      }
    },

    "ProdRoute53": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "AliasTarget": {
          "DNSName": { "Fn::GetAtt" : [ "CloudFrontDistribution", "DomainName" ] },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": { "Ref": "hostedZoneId" },
        "Name":  { "Fn::Sub": "${dnsName}." },
        "Type": "A"
      }
    },
    "ProdRoute53Ipv6": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "AliasTarget": {
          "DNSName": { "Fn::GetAtt" : [ "CloudFrontDistribution", "DomainName" ] },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": { "Ref": "hostedZoneId" },
        "Name":  { "Fn::Sub": "${dnsName}." },
        "Type": "AAAA"
      }
    },

    "WildcardProdRoute53": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "AliasTarget": {
          "DNSName": { "Fn::GetAtt" : [ "CloudFrontDistribution", "DomainName" ] },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": { "Ref": "hostedZoneId" },
        "Name":  { "Fn::Sub": "*.${dnsName}." },
        "Type": "A"
      }
    },

    "WildcardProdRoute53Ipv6": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "AliasTarget": {
          "DNSName": { "Fn::GetAtt" : [ "CloudFrontDistribution", "DomainName" ] },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": { "Ref": "hostedZoneId" },
        "Name":  { "Fn::Sub": "*.${dnsName}." },
        "Type": "AAAA"
      }
    }
  }
}
