Azure DNSのエイリアスレコードでZone Apex (Naked Domain / Root Domain) にAzureの各種サービスのパブリックなエンドポイントを設定する

本記事では、Microsoft AzureのフルマネージドDNSサービス「Azure DNS」のZone ApexにAzureの各種サービスのパブリックなエンドポイントを設定したい場合の対応方法についてまとめます。

# Zone Apexの定義とCNAMEの規約について
本題に入る前に、記事中で扱うDNSの用語等について簡単に整理します。詳細は [Zone Apex (Naked Domain) CDN | J-Stream CDN情報サイト](https://tech.jstream.jp/blog/cdn/zone_apex_cdn/) に非常に分かりやすくまとまっています。

- Zone Apex (ゾーン アペックス / ゾーン エイペックス) というのは `www.example.com` ではなく `example.com` のようにサブドメインを含まないドメイン名を指します。別名としてNaked Domain (ネイキッド ドメイン) やRoot Domain (ルート ドメイン) などが使われています
- DNSを含むインターネットの標準化に関する文書群「RFC; Request for Comments」の一つ「[RFC1912 - Common DNS Operational and Configuration Errors](https://www.ietf.org/rfc/rfc1912.txt)」の「2.4 CNAME records」の中で「CNAMEレコードは他のデータと共存できない (A CNAME record is not allowed to coexist with any other data)」と規定されています
- Zone Apexには通常 `IN NS ns.example.jp` のようなNSレコード (権威DNSサーバー) を定義します
- よって**Zone Apexに対してCNAMEレコードを設定することはできません**

最後の一文が重要なポイントです。上記はDNS全般に関する規約ですので、Azure DNSを使う場合でもAWSの類似サービスであるRoute 53を使う場合でも留意する必要があります。

# Azure DNSでの対応方法 - エイリアスレコード
Azure DNSの**エイリアスレコード**という機能を用いることで上記の課題に対応することができます。エイリアスレコードはAzure DNSの付加的な機能で、A/AAAA/CNAMEレコードセットに対してオン/オフの設定ができます。エイリアスレコードをオンにすることでAzureのパブリックIPアドレスなどのAzureリソース (Azureでは静的、動的を問わずパブリックIPアドレスはリソースの一つとして扱われます) をレコードに設定でき、DNSの名前解決の問い合わせ時にリソースに紐づく実体のIPアドレスが動的に解決され、問い合わせ元に返却されます。

# Zone Apexへのエイリアスレコードの追加
以下はZone Apexのエイリアスレコードを追加する場合のAzure DNSのレコードセット追加画面の入力例です。Zone Apexレコードは [名前] を空白のままにする必要があります。[エイリアスのレコードセット] で はい、[エイリアスの種類] で Azureリソース を選択した上で、[Azureリソース] で任意のAzureリソースを選択します。TTLに任意の値を入力して [OK] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/87e72565-4b6e-f643-3b87-e698e94bfd0e.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/843b8f1c-65a3-cfb3-d81a-dd2dccabd5a8.png)

これにより、レコードセットの一覧に以下の1レコード目のように [名前] が *@* になっているレコードが追加されます ( [種類] が *NS* 及び *SOA* のレコードは元々存在しているレコードです)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/2bc3527f-c2ad-7fc9-a7a2-fc2e40d25170.png)

この状態で `dig` コマンドを用いた名前解決を行った結果が以下です。ANSWER SECTIONを見て頂くと、1回の問い合わせでIPアドレスが返却されていることが分かります。

```bash:エイリアスレコード名前解決
$ dig nakazax.com

; <<>> DiG 9.11.3-1ubuntu1.9-Ubuntu <<>> nakazax.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59563
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nakazax.com.                   IN      A

;; ANSWER SECTION:
nakazax.com.            60      IN      A       52.229.34.228

;; Query time: 66 msec
;; SERVER: 192.168.10.1#53(192.168.10.1)
;; WHEN: Mon May 04 16:45:26 JST 2020
;; MSG SIZE  rcvd: 56
```

以下は参考ですがCNAMEレコードに対する名前解決を行った結果です。ANSER SECTIONで複数回の名前解決が行われていることが分かります。

```bash:CNAMEレコード名前解決
$ dig app-nakazax-qiita.azurewebsites.net

; <<>> DiG 9.11.3-1ubuntu1.9-Ubuntu <<>> app-nakazax-qiita.azurewebsites.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61327
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;app-nakazax-qiita.azurewebsites.net. IN        A

;; ANSWER SECTION:
app-nakazax-qiita.azurewebsites.net. 30 IN CNAME waws-prod-am2-287.sip.azurewebsites.windows.net.
waws-prod-am2-287.sip.azurewebsites.windows.net. 1788 IN CNAME waws-prod-am2-287.cloudapp.net.
waws-prod-am2-287.cloudapp.net. 10 IN   A       13.69.68.17

;; Query time: 98 msec
;; SERVER: 192.168.10.1#53(192.168.10.1)
;; WHEN: Mon May 04 16:51:17 JST 2020
;; MSG SIZE  rcvd: 179
```

# エイリアスレコードでポイント可能なAzureリソース
以下はエイリアスレコードでポイント可能なAzureリソースのまとめです。エイリアスレコードでポイント可能 = Zone Apexに設定可能ということになります。詳細は「[エイリアス レコードの概要 - Azure DNS | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/dns/dns-alias)」を参照ください。

- Azure Traffic Manager プロファイル
- Azure CDN エンドポイント
- Azure Front Door フロントエンドホスト
- パブリックIPアドレスリソース

# パブリックIPアドレスリソースを関連付け可能なAzureリソース
以下はパブリックIPアドレスリソースを関連付け可能なAzureリソースのまとめです。パブリックIPアドレスリソース = エイリアスレコードでポイント可能 = Zone Apexに設定可能ということになります。対象のサービスはどんどん増えて行くと思いますので「[Azure DNS を他の Azure サービスで使用する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/dns/dns-for-azure-services)」や「[Azure パブリック IP アドレスの作成、変更、削除 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-network-public-ip-address)」などの公式ドキュメントを都度参照ください。

- Azure Application Gateway
- Azure Load Balancer
- Azure Cloud Services
- Azure Virtual Machines (VM)
- Azure Kubernetes Service (AKS)

### 追加の参考リンク
-  [Azure Application Gateway に関してよく寄せられる質問 - Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/application-gateway/application-gateway-faq#does-application-gateway-support-static-ip)
-  [Azure Load Balancer components - Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/load-balancer/components#frontend-ip-configurations)
-  [ロード バランサーで静的 IP を使用する - Azure Kubernetes Service - Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/aks/static-ip)

# Azure App Service
Azure App Serviceは他のリソースと少々方法が異なり、「外部IPアドレス」を用いることでZone Apexに設定することができます。詳細は「[Azure アプリへのカスタム ドメイン名のマッピング](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-web-tutorial-custom-domain)」を参照ください。

以上です。