EC2起動時にRoute53のレコードを更新させたい
ElasticIPを設定しておけばいいと思われるがIPv4アドレスに課金する動きがあったりして、ElasticIPだけでは不安になってくるのでRoute53を毎回更新しておけばいろいろと都合が良さそうなので。
今回はRockyLinux9で設定。
インスタンスにはあらかじめIAMロールを設定しておく
route53:ChangeResourceRecordSets が付与されていれば良いと思われるが適時調整要。
バッチファイルを作成して配置
SELinuxの関係で/usr/libexecに配置して実行権限を付与。
chmod +x /usr/libexec/update-route53.sh
作成したバッチファイル
#!/bin/bash
set -euo pipefail
#インスタンスメタデータからIPアドレスを取得
ipv4=`/bin/curl -s http://169.254.169.254/latest/meta-data/public-ipv4/`
ipv6=`/bin/curl -s http://169.254.169.254/latest/meta-data/ipv6/`
#ZONEIDはあらかじめ設定
zoneid=
#ホスト名を自動取得できない場合は設定を行う
#hostname=`hostname`
hostname=<ホスト名をFQDNで>
#インストールしたAWS-Cliのフルパスを設定しておく
awscli=/usr/local/bin/aws
# JSON をスクリプト内に直接埋め込み
cat <<EOF > /tmp/ipv4upsert.json
{
"Comment": "Update A record",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${hostname}.",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "${ipv4}"
}
]
}
}
]
}
EOF
cat <<EOF > /tmp/ipv6upsert.json
{
"Comment": "Update AAAA record",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${hostname}.",
"Type": "AAAA",
"TTL": 300,
"ResourceRecords": [
{
"Value": "${ipv6}"
}
]
}
}
]
}
EOF
#更新実行
${awscli} route53 change-resource-record-sets --hosted-zone-id ${zoneid} --change-batch file:///tmp/ipv4upsert.json
${awscli} route53 change-resource-record-sets --hosted-zone-id ${zoneid} --change-batch file:///tmp/ipv6upsert.json
while true; do
ipv4result=$(dig +short @8.8.8.8 "${hostname}" A)
/bin/logger "Route53:更新 期待値: ${ipv4}, dig結果: ${ipv4result}"
if [ "$ipv4" = "$ipv4result" ]; then
logger "Route53:更新 IPv4の更新完了"
break
fi
/bin/logger "Route53:更新 IPv4の更新未完了のため5秒待機します"
sleep 5
done
while true; do
ipv6result=$(dig +short @8.8.8.8 "${hostname}" AAAA)
/bin/logger "Route53:更新 期待値: ${ipv6}, dig結果: ${ipv6result}"
if [ "$ipv6" = "$ipv6result" ]; then
/bin/logger "Route53:更新 IPv6の更新完了"
break
fi
/bin/logger "Route53:更新 IPv6の更新未完了のため5秒待機します"
sleep 5
done
#後始末
rm -f /tmp/ipv4upsert.json
rm -f /tmp/ipv6upsert.json
systemdで使用するユニットファイルを作成する
vi /etc/systemd/system/route53-update.service
[Unit]
Description=Update Route53 A/AAAA Records with Instance IPs
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/libexec/update-route53.sh
TimeoutStartSec=180
[Install]
WantedBy=multi-user.target
ユニットファイルを取り込んで実行設定
systemctl daemon-reexec
systemctl daemon-reload
systemctl enable route53-update.service
バッチファイルの解説
systemdで実行することを意図しているため、ログはsyslogなどに流す。(loggerコマンドを使用)
AWS-Cliは以下のようにインストールする
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
Route53の更新には多少の時間を要するため、更新されたことを確認できるまで次に進ませない。
while true; do
ipv4result=$(dig +short @8.8.8.8 "${hostname}" A)
/bin/logger "Route53:更新 期待値: ${ipv4}, dig結果: ${ipv4result}"
if [ "$ipv4" = "$ipv4result" ]; then
logger "Route53:更新 IPv4の更新完了"
break
fi
/bin/logger "Route53:更新 IPv4の更新未完了のため5秒待機します"
sleep 5
done
while true; do
ipv6result=$(dig +short @8.8.8.8 "${hostname}" AAAA)
/bin/logger "Route53:更新 期待値: ${ipv6}, dig結果: ${ipv6result}"
if [ "$ipv6" = "$ipv6result" ]; then
/bin/logger "Route53:更新 IPv6の更新完了"
break
fi
/bin/logger "Route53:更新 IPv6の更新未完了のため5秒待機します"
sleep 5
done