LoginSignup
1
0

EC2のWebサーバーのIPアドレスを固定せず、起動時にRoute53のレコードを自動更新(自作DDNS?)

Last updated at Posted at 2024-04-20

作業の経緯

実験用のAWSのEC2上のWebサーバーでhttpsを有効化するため、固定IPアドレス(Elastic IP)を使用しています。
サーバーは使用する時だけ起動してコスト削減を図っているのですが、ElasticIPはずっと課金されてしまうため、これを節約したいというのが今回の経緯です。

この記事で使用したEC2インスタンスはかなり古いモノですので、メタデータのバージョンがIMDSv1です。
IMDSv1は現在非推奨となっており、今年中には新しいインスタンスでIMDSv2が強制されるようになるはずですが、IMDSv2ではパブリックIPアドレスの取得方法が変わっています。
この手順は今後確かめて、改めて掲載しようと思います。

作業前の状態

  • EC2インスタンスでWebサーバーを構築
  • ElasticIPを確保して上記インスタンスに割り当て
  • お名前.comで独自ドメインを取得してRoute53サービスに権限を移譲
  • Route53のホストゾーンにサーバー名を登録
  • Let's Encryptで上記サーバー名の証明書を作成

作業後のイメージ

  • ElasticIPを解放してサーバーのIPアドレスを動的割り当てとする
  • サーバー起動時にパブリックIPアドレスを取得する
  • 取得したパブリックIPアドレスでRoute53のレコードを自動更新する

作業手順

パブリックIPアドレスの取得

EC3インスタンス上でパブリックIPアドレスを取得するには、以下のURLでメタデータを取得します。
このIPアドレスはメタデータを取得するために特別に割り当てられているようです。

curl -H "Metadata-Flavor: AWS-V2" http://169.254.169.254/latest/meta-data/public-ipv4

レコード更新のための権限付与

IAMポリシーの作成

Route53のレコードを更新するためのIAMポリシーを作成する必要があります。

  • IAMサービスを開く
  • [アクセス管理]-[ポリシー]を開く
  • [ポリシーの作成]を選択
  • サービスの選択でRoute53を選ぶ
  • アクションの選択でChangeResourceRecordSetsを選ぶ
  • リソースARNにarn:aws:route53:::hostedzone/[ホストゾーンID]を選ぶ(ホストゾーンIDはRoute53サービスで自分のゾーンを選ぶと表示されている)
  • ポリシー名を付けて保存
IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": "arn:aws:route53:::hostedzone/<ホストゾーンID>"
        }
    ]
}

IAMロールの作成

EC2にポリシーを割り当てるためにIAMロールを作成します。

  • IAMサービスを開く
  • [アクセス管理]-[ロール]を開く
  • [ロールの作成]を選択
  • 信頼されたエンティティタイプで[AWSサービス]を選択
  • ユースケースで[EC2]を選ぶ
  • 許可ポリシーとして、前項で作成したポリシーを選択する
  • ロール名を付けて保存

EC2インスタンスへの割り当て

  • EC2サービスを開く
  • Webサーバーのインスタンスを選択
  • [アクション]-[セキュリティ]-[IAMロールの変更]を選択
  • 前項で作成したIAMロールを選択する

※もともとEC2にIAMロールを割り当てている場合は、そのロールに前述の手順で作成したポリシーを割り当てるか、新しいIAMロールに必要なポリシーを割り当てる必要があります。

Route53のレコード更新

AWS-CLIのインストール

Route53のレコードを更新するには、AWS-CLIコマンドを使用します。
私が使っているUbuntuのAMIにはデフォルトでAWS-CLIが入っていないのでインストールします。

sudo apt install aws

Route53レコード更新

AWS-CLIのコマンドは以下のような感じです。

aws route53 change-resource-record-sets --hosted-zone-id <Route53のゾーンID> --change-batch {"Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "<サーバーのFQDN>",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "<パブリックIPv4アドレス>"
          }
        ]
      }
    }
  ]
}

自動更新のスクリプト作成

レコードの更新を自動化するため、スクリプトを作成します。

update.sh
#!/bin/bash

PUBIP=`curl -H "Metadata-Flavor: AWS-V2" http://169.254.169.254/latest/meta-data/public-ipv4`

ZONEID=${1:-"<ホストゾーンID>"}

JSON="{\"Changes\": [
    {
      \"Action\": \"UPSERT\",
      \"ResourceRecordSet\": {
        \"Name\": \"<サーバーのFQDN>\",
        \"Type\": \"A\",
        \"TTL\": 300,
        \"ResourceRecords\": [
          {
            \"Value\": \"$PUBIP\"
          }
        ]
      }
    }
  ]
}"

このシェルスクリプトを実行すると、EC2インスタンスのパブリックIPアドレスをホストゾーンのサーバー名のAレコードに登録します。

chmod +x update.sh
./update.sh <ホストゾーンID>

サービス登録

サーバー起動時にシェルを自動実行するため、サービス定義を作成して登録します。

/etc/systemd/system/dns-update.service
[Unit]
Description=Update Route53 Record to my address.
After=network.target

[Service]
Type=simple
User=root
ExecStart=/home/ubuntu/update.sh

[Install]
WantedBy=multi-user.target
sudo systemctl enable dns-update

以上で、サーバー起動時にパブリックIPアドレスを取得して更新するはずです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0