Route53のレコードセットに AWS CloudFormation を利用しました

# 背景
いつもは、Route53 レコードセットをマネージドコンソールから手動設定しています。
先日、EC2インスタンスの構成をAWS CloudFormationでテンプレート化したこともあり今回もテンプレート化にチャレンジした記録です。

* [[軽作業用インスタンス構築に AWS CloudFormation を利用しました]](https://qiita.com/yodyman/items/48897045807f225a362d)

# 今回実現したいこと
「sample.com.」の各種レコードセットを実施したい
* Aレコード設定
  * IPアドレス指定
  * エイリアス指定
* CNAMEレコード設定
* 加重レコード設定
* 位置情報レコード設定
 
公式サイトの「[Route 53 テンプレートスニペット](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/quickref-route53.html)」を参照

# テンプレート
今回もYAML形式で記述しました

[[AWS公式サイト AWS CloudFormation テンプレート形式]](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-formats.html)

# メタデータ
```sample.yaml
ホストゾーンのドメイン名、TTLをグルーピングしました
#------------------------------------------------------------------------------
# metadata
#------------------------------------------------------------------------------
Metadata:
  LICENSE: Apache License, Version 2.0
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: 'Input domain host zone information'
        Parameters:
          - HostZoneName
          - TTLNormal
```

# パラメータ
```sample.yaml
#------------------------------------------------------------------------------
# parameter
#------------------------------------------------------------------------------
Parameters:
  #-- host zone
  HostZoneName:
    Type: String
    Default: 'sample.com.'
  TTLNormal:
    Type: String
    Default: '3600'
```

# リソース

## Aレコード設定 IPアドレス
```sample.yaml
#------------------------------------------------------------------------------
# resource
#------------------------------------------------------------------------------
Resources:
  #-- A record ip address
  #-- sample1.sample.com
  Sample1SampleCom:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneName: !Sub "${HostZoneName}"
      Name: 'sample1.sample.com.'
      Type: A
      TTL:  !Sub "${TTLNormal}"
      ResourceRecords:
        - '設定したいIPアドレスを追加ください'
```

## Aレコード設定 エイリアス
AliasTargetのHostedZoneIdには、AliasTargetのDNSNameに対するものとなります。
「sample.com」の HostedZoneIdではないのでご注意ください。
CloudFormationの動きとしては、AliasTargetで指定されるHostedZoneIdに存在するDNSNameをチェックしているようです。

```sample.yaml
  #-- A record alias
  #-- sample2.sample.com
  Sample2SampleCom:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneName: !Sub "${HostZoneName}"
      Name: 'sample2.sample.com.'
      Type: A
      AliasTarget: # set alias dnsname's hostedzoneid, it is not sample.com hostedzoneid.
        DNSName: 'エイリアスしたいDNSを指定ください'
        HostedZoneId: 'エイリアスしたいDNSのホストゾーンIDを指定ください'
```

## CNAMEレコード設定
```sample.yaml
  #-- CNAME record
  #-- sample3.sample.com
  Sample3SampleCom:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneName: !Sub "${HostZoneName}"
      Name: 'sample3.sample.com.'
      Type: CNAME
      TTL:  !Sub "${TTLNormal}"
      ResourceRecords:
        - '設定したいドメインを追加ください'
```

## 加重レコード設定
新規をnew record、既存をold recordとし、徐々に新規のウェイトを増やす想定のケースです。

```sample.yaml
  #-- Weighted Routing
  #-- sample4.sample.com
  Sample4SampleCom:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneName: !Sub "${HostZoneName}"
      RecordSets:
        - Name: 'sample4.sample.com.'
          Type: A
          SetIdentifier: 'new record'
          Weight: 1
          AliasTarget: # set alias dnsname's hostedzoneid, it is not sample.com hostedzoneid.
            DNSName: 'エイリアスしたいDNSを指定ください'
            HostedZoneId: 'エイリアスしたいDNSのホストゾーンIDを指定ください'
        - Name: 'sample4.sample.com.'
          Type: A
          SetIdentifier: 'old record'
          Weight: 9
          AliasTarget: # set alias dnsname's hostedzoneid, it is not sample.com hostedzoneid.
            DNSName: 'エイリアスしたいDNSを指定ください'
            HostedZoneId: 'エイリアスしたいDNSのホストゾーンIDを指定ください'
```

## 位置情報レコード設定
デフォルトをA api、EUをB apiにルーティングされるように位置情報ルーティングを設定する

```sample.yaml
  #-- GeoLocation Routing
  #-- default geo location can access A api
  #-- eu can access B api
  Sample5SampleCom:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneName: !Sub "${HostZoneName}"
      RecordSets:
        - Name: 'sample5.sample.com.'
          Type: A
          SetIdentifier: 'A api'
          GeoLocation:
            CountryCode: '*' # デフォルト指定として、全ての国を指定する. ContinentCodeに * は、指定できない
          AliasTarget: # set alias dnsname's hostedzoneid, it is not sample.com hostedzoneid.
            DNSName: 'エイリアスしたいDNSを指定ください'
            HostedZoneId: 'エイリアスしたいDNSのホストゾーンIDを指定ください'
        - Name: 'sample5.sample.com.'
          Type: A
          SetIdentifier: 'B api'
          GeoLocation:
            ContinentCode: 'EU' # EU限定で B api にルーティングされるように指定する
          AliasTarget: # set alias dnsname's hostedzoneid, it is not sample.com hostedzoneid.
            DNSName: 'エイリアスしたいDNSを指定ください'
            HostedZoneId: 'エイリアスしたいDNSのホストゾーンIDを指定ください'
```

# はまったこと
* エリアスターゲットのHostedZoneIdを「sample.com.」HostedZoneIdと間違えないようにする
* 位置情報ルーティングのデフォル(*) の指定は、ContinentCodeではなくCountryCodeを指定

# メモ・考察
* 更新頻度も多くないので今回の数程度であれば、手動でもとも思う
* 込み入ったコードにならないので便利だと思いました

# 参考
* ユーザーガイド
  * [AWS::Route53::RecordSet](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html)
  * [AWS::Route53::RecordSet GeoLocation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset-geolocation.html)
  * [AWS::Route53::RecordSetGroup](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-route53-recordsetgroup.html)