Open3

amplify hosting で追加した cloudfront に独自ドメインを設定するまで

ShinkawaShinkawa

amplify hosting add で cloudfront s3 でのホスティングを設定したが、

  • cloudfrontのdistributionには説明が記載されない からぱっとみどの環境のdistributionなのか分かりづらい
  • 同じアカウントのroute53で購入した独自ドメインを設定したい
    という課題があるため、解決していく。
    amplify/backend/hosting/S3AndCloudFront/template.jsonのカスタマイズは推奨されてないかもだから最終的にはamplifyでの管理はやめてcloudformation or cdk で管理することになるかもしれない
ShinkawaShinkawa

cloudfrontのdistributionには説明が記載されない からぱっとみどの環境のdistributionなのか分かりづらい

Cloudfrontのディストリビューションの説明欄に${appName}-${env}を表示させたい

template.jsonを以下のように編集すればいい

amplify/backend/hosting/S3AndCloudFront/template.json
    "CloudFrontDistribution": {
      "Type": "AWS::CloudFront::Distribution",
      "DependsOn": [
        "S3Bucket",
        "OriginAccessIdentity"
      ],
      "Properties": {
        "DistributionConfig": {
+          "Comment": {
+            "Fn::Join": [
+              "",
+              [
+                {
+                  "Ref": "bucketName"
+                },
+                "-",
+                {
+                  "Ref": "env"
+                }
+              ]
+            ]
+          },
          "HttpVersion": "http2",

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-comment

ShinkawaShinkawa

同じアカウントのroute53で購入した独自ドメインを設定したい

細かいことは端折るけど、これでamplify publishで動くことを確認
事前にacmで証明書を発行してそのARNをacmCertificateArnと、customDomainName, hostedZoneIdも設定する必要がある

"Parameters": {
  "bucketName": {
    "Type": "String"
  },
  "env": {
    "Type": "String"
  },
  // カスタムドメイン名を記載します。ここでは "your-domain.com" を例として用います。
  "customDomainName": {
    "Type": "String",
    "Default": "your-domain.com"
  },
  // ACM証明書のARNを記載します。この例では疑似のARNを使用しています。
  "acmCertificateArn": {
    "Type": "String",
    "Default": "arn:aws:acm:region:account-id:certificate/xxxxx-xxxxxx-xxxxxx-xxxxx"
  },
  // Route53ホストゾーンIDを記載します。この例では疑似のHostedZoneIdを使用しています。
  "hostedZoneId": {
    "Type": "String",
    "Default": "ZXXXXXXXXXXXXXXXXX"
  }
},
...
"CloudFrontDistribution": {
    ...
    "Properties": {
      "DistributionConfig": {
        "Aliases": [
          {
           "Fn::If": [
             "IsProdEnv",
             {
               "Ref": "customDomainName"
             },
             {
               "Fn::Join": [
                 "",
                 [
                   {
                     "Ref": "env"
                   },
                   ".",
                   {
                     "Ref": "customDomainName"
                   }
                 ]
               ]
             }
           ]
         }
       ],
        "ViewerCertificate": {
          "AcmCertificateArn": {
            "Ref": "acmCertificateArn"
          },
          ...
        },
          // 自動生成されてる他の設定はそのままにする
          // ex) HttpVersion, Origins, Enabled, DefaultCacheBehavior, DefaultRootObject, CustomErrorResponses
...
"DNSRecord": {
  "Type": "AWS::Route53::RecordSet",
  "Properties": {
    "HostedZoneId": {
      "Ref": "hostedZoneId"
    },
    "Name": {
      "Fn::Join": [
        "",
        [
          {
            "Fn::If": [
              "IsProdEnv",
              {
                "Ref": "customDomainName"
              },
              {
                "Fn::Join": [
                  "",
                  [
                    {
                      "Ref": "env"
                    },
                    ".",
                    {
                      "Ref": "customDomainName"
                    }
                  ]
                ]
              }
            ]
          },
          "."
        ]
      ]
    },
    "Type": "A",
    "AliasTarget": {
      "HostedZoneId": "Z2FDTNDATAQYW2",
      "DNSName": {
        "Fn::GetAtt": [
          "CloudFrontDistribution",
          "DomainName"
        ]
      }
    }
  }
},
...

outputのCloudFrontSecureURLも修正するとamplify publishしたときにcloudfrontのURLではなくcustom domainが出力されるので良い

  "Outputs": {
    "CloudFrontSecureURL": {
      "Value": {
        "Fn::Join": [
          "",
          [
            "https://",
            {
              "Fn::If": [
                "IsProdEnv",
                {
                  "Ref": "customDomainName"
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Ref": "env"
                      },
                      ".",
                      {
                        "Ref": "customDomainName"
                      }
                    ]
                  ]
                }
              ]
            }
          ]
        ]
      }
    },
 ...
 }