はじめに
AWSのEC2インスタンスは、Elastic IP(EIP)を付与しなければ、インスタンスの停止&起動でIPアドレスが変わってしまいます。
また、EIPアドレスはクォータ引き上げ申請無しで各リージョン5つまでなので、無計画に使っているとあっという間に使い切ってしまいます。
EIPを使用しない場合、停止起動を行う際は、起動後にアクセスする際のアドレスを確認したり手間ですが、EC2インスタンス起動時にRoute53の登録情報を更新しにいくようにすることで固定のEIPを持たなくてもアクセスできるようにします。
作業の流れ
Amazon Linux2上に登録する前提で以下の様な方法で進めていきます。
尚、ドメイン名でアクセスする対象となるEC2インスタンスは事前に作成してある前提とします。
- ドメインの取得
 - Route53にドメインを登録
 - Route53のホストゾーン作成
 - Route53更新用IAMロール作成
 - EC2インスタンスへのIAMロールのアタッチ
 - EC2インスタンスへのシェル追加
 - Route53更新シェルのsystemd登録
 - EC2インスタンスを停止起動して動作確認
 
上記1~5はRoute53やIAMポリシー作成権限がある管理用のIAMユーザ等で実施、6~8は実際にドメイン名でアクセスする対象のEC2インスタンスで実施してください。
ドメインの取得
IPが変わってしまってもアクセスできるようにドメインを取得する必要があります。
Route53でドメインを取得しても良いですし、お名前.com等で取得しても良いです。
今回はRoute53で独自ドメインを取得する方法を記載します。
Route53での独自ドメイン取得
Route53の画面より、登録済みドメイン→ドメインの登録から独自ドメインの取得が可能です。
本画面から登録するのはドメイン自体の登録となるため、EC2インスタンスに割り当てるホスト名を**www.example.com**という名前にする場合、ドメイン名は**example.com**で取得してください。
ドメイン取得可否確認
ドメイン名の選択画面より、お好きなドメイン名を入力し、チェックをクリックすることで、取得可能なドメインの候補が表示されるので、取得したいドメイン名を指定してカートに入れる→画面下の続行で次に進みます。
連絡先の入力
ドメイン管理者の情報を入力し、続行で進みます。
ドメインのお問い合わせ詳細で入力したメールアドレスに検証のためのメールが送付されるため、URLをクリックして検証を完了させておきましょう。
入力した連絡先の確認やドメインの自動更新有無、規約等のチェックを行い、注文を完了をクリックすることでドメイン取得が完了します。
取得完了までしばらく時間がかかるので、焦らず待ちましょう。
尚、注文を完了させた時点で費用が発生するので、注意しましょう。
Route53での独自ドメイン取得(aws cliで実施した場合)
aws cliでのドメイン取得は試していないので、違っているかもしれませんが、今後の自分メモとして残しておきます。
ドメイン取得可否確認
ドメインが取得可能かを確認。Route53はグローバルのサービスのため、リージョンの指定はus-east-1としましょう。
取得可能の場合はAVAILABLE、取得不可の場合はUNAVAILABLEと表示されるので、UNAVAILABLEと表示された場合は別のドメイン名にして繰り返しチェックしましょう。
aws route53domains check-domain-availability --region us-east-1 --domain-name [ドメイン名]
連絡先の入力
画面での入力のように対話形式で行えないため、予めjson形式で連絡先を作成します。
書式はRoute 53 API ReferenceのRegisterDomainのRequest Syntaxに記載があります。
なお、Request Syntaxに書かれているすべての項目に対して記載する必要はなく、最低限Request ParametersでRequiredと書かれている項目のみ記載すればOKです。
以下GUIで入力した項目と同等のjson形式ファイル。
{
   "AdminContact": { 
      "AddressLine1": "string",
      "AddressLine2": "string",
      "City": "string",
      "ContactType": "string",
      "CountryCode": "string",
      "Email": "string",
      "FirstName": "string",
      "LastName": "string",
      "OrganizationName": "string",
      "PhoneNumber": "string",
      "State": "string",
      "ZipCode": "string"
   },
   "AutoRenew": boolean,
   "DomainName": "string",
   "DurationInYears": number,
}
Route53のホストゾーン作成
Route53で正引きできるようにするため、先ほど取得したドメイン名でホストゾーンの作成を行います。
ホストゾーンの作成
先ほど取得したドメイン名でホストゾーンを作成します。
尚、作成のためにcaller-referenceの設定が必須となるため、以下の様に現在時刻を設定、また、後ほど必要となるため、HostedZoneIdを控えておきます。
aws route53 create-hosted-zone --name [ドメイン名] --caller-reference `date +%Y-%m-%d_%H-%M-%S` --hosted-zone-config Comment="[コメント]"
Route53更新用IAMロール作成
EC2インスタンスからRoute53の情報を更新する必要があるので、Route53の更新権限を持つIAMロールを作成します。
インスタンスプロファイル、IAMロールの詳細は以下を参照してください。
「インスタンスプロファイルを理解するついでにポリシーとロールを整理する。」
なお、IAMロールを割り当てるEC2インスタンスではIAMポリシー、IAMロール作成ができないので、CLIで実施する場合は、作成できる権限を持つユーザで行って下さい。
前準備
IAMロール作成に必要な構成を以下に記載します。
| 構成 | 設定 | 
|---|---|
| IAMポリシー名 | Route53UpdatePolicy | 
| IAMロール名 | Route53UpdateRole | 
| インスタンスプロファイル名 | Route53UpdateRole | 
| IAMポリシーファイルパス | /home/ec2-user/r53policy.json | 
| Assumeロールファイルパス | /home/ec2-user/assume.json | 
前回の「インスタンスプロファイルを理解するついでにポリシーとロールを整理する。」の記事と異なり、IAMロール名とインスタンスプロファイル名が同じになっていますが、前回の記事でも記載している通り、IAMロール名とインスタンスプロファイル名を同じにしないとAWSコンソールからインスタンスプロファイルが削除できないため、今回は同じにしています。
IAMポリシーの作成
EC2インスタンスから自分のホスト名が登録されているRoute53のホストゾーンに対してのみ変更権限を持つIAMポリシーファイルを作成します。
[ホストゾーンID]の部分は先ほど作成したホストゾーンのIDを記載して下さい。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": "arn:aws:route53:::hostedzone/[ホストゾーンID]"
        }
    ]
}
作成したIAMポリシーファイルからIAMポリシーを作成します。
create-policy実行後に表示されるArnは控えて下さい。
aws iam create-policy --policy-name Route53UpdatePolicy --policy-document file:///home/ec2-user/r53policy.json
IAMロールの作成
Assumeロールは前回と同じデフォルト設定で作成します。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            }
        }
    ]
}
aws iam create-role --role-name Route53UpdateRole --assume-role-policy-document file:///home/ec2-user/assume.json
IAMロールとIAMポリシーの紐付け
先ほど控えたArnを使ってIAMロールとIAMポリシーを紐付けます。
aws iam attach-role-policy --role-name Route53UpdateRole --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/Route53UpdatePolicy
インスタンスプロファイルの作成とIAMロールの紐付け
EC2インスタンスとIAMロールを紐付けるためのインスタンスプロファイルを作成します。
aws iam create-instance-profile --instance-profile-name Route53UpdateRole
aws iam add-role-to-instance-profile --instance-profile-name Route53UpdateRole --role-name Route53UpdateRole
インスタンスプロファイルとEC2インスタンスの紐付け
起動時にRoute53の更新を行う対象となるEC2インスタンスに今まで作成してきたIAMポリシーを紐付けます。
EC2インスタンスIDは以下コマンドやAWSコンソールから確認しておいて下さい。
aws ec2 describe-instances
aws ec2 associate-iam-instance-profile --instance-id [インスタンスID] --iam-instance-profile Name=Route53UpdateRole
EC2インスタンスへのシェル追加
ここからは実際にホスト名でアクセスするEC2インスタンスで作業します。
最終的にsystemdに登録をして起動時に呼び出すようにするため、以下のパスに各ファイルを作成します。
| ファイル名 | パス | 
|---|---|
| Route53更新シェル | /usr/local/sbin/update_route53.sh | 
| 変数ファイル | /etc/sysconfig/update_r53 | 
以下作業はsudo等でroot権限になってから実施します。
Route53更新シェルの作成
Route53更新シェルを/usr/local/sbin/update_route53.shに作成します。
# !/bin/bash
# 環境変数設定
BATCH_FILE="r53.json"
PUBLIC_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)
# Route53更新用バッチファイル生成
cat << _EOF_ > /tmp/${BATCH_FILE}
{
  "Comment" : "",
  "Changes" : [
    {
      "Action" : "UPSERT",
      "ResourceRecordSet" : {
        "Name" : "${HOST_NAME}",
        "Type" : "A",
        "TTL" : ${TTL},
        "ResourceRecords" : [
          {
            "Value": "${PUBLIC_IP}"
          }
        ]
      }
    }
  ]
}
_EOF_
# Route53更新、後片付け
aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} --change-batch file:///tmp/r53.json
rm -f /tmp/${BATCH_FILE}
実行権限などの設定も行っておきます。
sudo chmod 755 /usr/local/sbin/update_route53.sh
変数ファイルの作成
先ほど作成したRoute53更新用バッチファイル実行時に読み込む変数ファイルを作成します。
自身の環境に合わせて記載するようにして下さい。
| 変数名 | 説明 | 
|---|---|
| HOSTED_ZONE_ID | 更新対象のドメインを登録しているRoute53のHosted Zone ID | 
| HOST_NAME | 更新対象のホスト名 | 
| TTL | Time To Live値(今回は300秒に設定) | 
# Zone情報
HOSTED_ZONE_ID="xxxxxxxxxxxxxx"
HOST_NAME="www.example.com"
TTL="300"
Route53更新シェルのsystemd登録
EC2インスタンス起動時に作成したRoute53更新シェルを実行するようにするため、systemdに登録します。
| ファイル名 | パス | 
|---|---|
| systemd用ファイル | /usr/lib/systemd/system/update_r53.service | 
systemd用ファイル作成
以下の様にsystemd用ファイルを作成します。
パスを変えているようであれば、先ほど作成したRoute53更新シェル、変数ファイルのパスを自身の環境に合わせて記載してください。
[Unit]
Description=Route53 update service
After=network-online.target
[Service]
Restart=no
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/sysconfig/update_r53
ExecStart=/usr/local/sbin/update_route53.sh
[Install]
WantedBy=network-online.target
自動起動の設定
起動時にupdate_r53.serviceが実行されるように自動起動設定を行います。
systemctl enable update_r53.service
systemctl is-enabled update_r53.service
更新確認
設定が完了したら登録したupdate_r53.serviceを起動してAレコードが登録されるか確認してみます。
systemctl start update_r53.service
以下は先ほどIAMロール等を作成したユーザで実施して、Aレコードが登録されているかを確認します。
Aレコードが存在しない場合はどこかで失敗しているので権限等を確認しましょう。
aws route53 list-resource-record-sets --hosted-zone-id [HOSTED_ZONE_ID]
Aレコードが登録されていれば設定が問題なくできているため、登録したホスト名でアクセスしてログインできれば終了です。
おわりに
今回の場合、ドメイン名の取得には多少費用が掛かりますが、一度取得すればEC2インスタンスが増えたとしてもAレコードを増やすだけで済みますし、固定のEIPは複数人のテスト環境で使用しているとすぐに上限に達してしまうため、EIPを節約するためにも有用かと思います。



