Amplify Gen2でカスタムドメインを指定してみた

2024.04.23

NTT東日本の中村です。

先日、Amplify Gen2でHostingのデプロイを行ったのですが、カスタムドメインが近日公開予定のステータスであることを書きました。

その後、社内メンバーから「APIを使ってAmplify Gen2でもカスタムドメインに対応できるよ!」という記事を教えてもらいました。
習熟用のアプリなので、正式対応を待とうと思っていたのですが、近日公開からかなり日が経っていることもあり、先駆者に習って私も試してみることにしました。

プレビュー版のサービスの近日公開をハックしているので、この手法が正解かどうか分からないのですが、ひとまず目的は果たすことができました。

アプリの概要

習熟用に動かしていたReactのWebアプリを改修し、Gen2のホスティングに載せ替えたものになります。

移行前の構成

Amplify Gen1、React(SPA)、CloudFront+S3ホスティング

シンプルな構成です。Route 53でドメインを管理し、CloudFrontに紐づけています。

新しい構成

Amplify Gen2、NextJS Server Components、Amplify Hosting

前述の通り、Gen2はカスタムドメインに正式対応できていません。 サービス影響に問題がないことから、暫定で前段にCloudFrontを配置し、リダイレクトで対応していました。
Amplify HostingもマネージドのCloudFrontが備わっているため、CloudFrontの2段構成(CloudFront chaining)となっています。

なお、CloudFront chainingはAmplifyにWAFを適用したい時等の手法として、ガイダンスが存在します。
将来的にWAFはAmplifyに直接統合できると良いと思います。Issueでも議論がされていますね。

とはいえ、現時点ではドメイン問題の回避にCloudFrontを設置しているので、APIでカスタムドメイン対応を行うことで 不要なCloudFrontを取り除くように対応を進めました。

カスタムドメインを追加する

マネジメントコンソールからAmplifyアプリにアクセスし、appIdを控えておきます。

同じリージョンのCloudShellを起動して、AWS CLIから設定を行います。 masterブランチにassociateされるように、sub-domain-settingsを設定しました。

aws amplify create-domain-association --app-id d2zphogehoge --domain-name example.com --sub-domain-settings '[{"branchName":"master", "prefix":""}]'

domainStatusを見ると、作成中であることが分かります。

{
    "domainAssociation": {
        "domainAssociationArn": "arn:aws:amplify:ap-northeast-1:*******:apps/d2zphogehoge/domains/example.com",
        "domainName": "example.com",
        "enableAutoSubDomain": false,
        "domainStatus": "CREATING",
        "subDomains": [
            {
                "subDomainSetting": {
                    "prefix": "",
                    "branchName": "master"
                },
                "verified": false,
                "dnsRecord": "* CNAME <pending>"
            }
        ],
        "certificate": {
            "type": "AMPLIFY_MANAGED"
        }
    }
}

get-domain-associationコマンドでステータス進捗を確認すると、失敗していました。 Route 53と前段のCloudFrontの削除を忘れていたため、Conflictしています。

aws amplify get-domain-association --app-id d2zphogehoge --domain-name example.com
{
    "domainAssociation": {
        "domainAssociationArn": "arn:aws:amplify:ap-northeast-1:*******:apps/d2zphogehoge/domains/example.com",
        "domainName": "example.com",
        "enableAutoSubDomain": false,
        "domainStatus": "FAILED",
        "statusReason": "com.amazonaws.services.cloudfront.model.CNAMEAlreadyExistsException: One or more of the CNAMEs you provided are already associated with a different resource. (Service: AmazonCloudFront; Status Code: 409; Error Code: CNAMEAlreadyExists; Request ID: 271259d8-cf24-4097-b45a-b5b13c5ca955; Proxy: null)",
        "certificateVerificationDNSRecord": "_cd546acadcfe52eb878922ff4651657f.example.com. CNAME _80d7e02c999175c7eec095629ed67e78.mhbtsbpdnt.acm-validations.aws.",
        "subDomains": [
            {
                "subDomainSetting": {
                    "branchName": "master"
                },
                "verified": false,
                "dnsRecord": " CNAME hogehoge.cloudfront.net"
            }
        ],
        "certificate": {
            "type": "AMPLIFY_MANAGED",
            "certificateVerificationDNSRecord": "_cd546acadcfe52eb878922ff4651657f.example.com. CNAME _80d7e02c999175c7eec095629ed67e78.mhbtsbpdnt.acm-validations.aws."
        }
    }
}

Routeの設定のクリアと、前段のCloudFrontの削除に加え 先ほど作成に失敗したassociationを削除する必要があります。

# 削除 
aws amplify delete-domain-association --app-id d2zphogehote --domain-name example.com

# 消えたことを確認
aws amplify list-domain-associations --app-id d2zphogehote
{
    "domainAssociations": []
}

改めてcreate-domain-associationを行い、domainStatusがPENDING_DEPLOYMENT→AVAILABLEに変化し、紐づけが完了しました。
ブラウザでドメインの紐づけは比較的早く確認できましたが、domainStatusがAVAILABLEに変化するまで、15分ほど掛かりました。

一通り挙動を確認しましたが、Webアプリも問題ないようです。

aws amplify list-domain-associations --app-id d2zphogehoge
{
    "domainAssociations": [
        {
            "domainAssociationArn": "arn:aws:amplify:ap-northeast-1:********:apps/d2zphogehote/domains/example.com",
            "domainName": "example.com",
            "enableAutoSubDomain": false,
            "domainStatus": "AVAILABLE",
            "certificateVerificationDNSRecord": "_cd546acadcfe52eb878922ff4651657f.example.com. CNAME _80d7e02c999175c7eec095629ed67e78.mhbtsbpdnt.acm-validations.aws.",
            "subDomains": [
                {
                    "subDomainSetting": {
                        "branchName": "master"
                    },
                    "verified": false,
                    "dnsRecord": " CNAME hogehoge.cloudfront.net"
                }
            ],
            "certificate": {
                "type": "AMPLIFY_MANAGED",
                "certificateVerificationDNSRecord": "_cd546acadcfe52eb878922ff4651657f.example.com. CNAME _80d7e02c999175c7eec095629ed67e78.mhbtsbpdnt.acm-validations.aws."
            }
        }
    ]
}

まとめ

非公式ではありますが、APIを使って、Amplify Gen2でカスタムドメインを適用できることを確認できました。 カスタムドメインがネックで実装に踏み切れないメンバーもいたので、ひとまず安心できるかと思います。