こんにちは。ドラマーのひろです。
皆さんはこんなシチュエーションないでしょうか。
- EC2のパブリックIPが起動するたび変わってしまって困っている。
- EC2にElastic IPを設定しているが、Elastic IP(EIP)を使用すると費用が掛かってしまうことが気がかり。
EC2のパブリックIPはEIPを使うことで固定できますが、AWS費用を少しでも減らしたいからEIPの使用を停止したい方は少なくないと思います。
そんな方にオススメしたいのが、Route53を使ってDDNS(ダイナミックDNS)のようにパブリックIPが変わるたびにDNSレコードを更新する方法です。
DNSレコード更新用スクリプトを起動時スクリプトに仕込んでおくことで起動した際にパブリックIPが変わっていれば更新することができます。
この方法はEC2がLinuxでもWindowsでも問題なく実践できますので、今後はEIPの使用を卒業し、Route53と起動時スクリプトで対応しましょう。
それでは、手順とソースコードを紹介していきます!
想定時間と作業の流れ
本手順の想定時間は全部で15分あれば完了できる程度です。慣れれば5分程度で出来る作業です。
作業の流れは以下のようになります。
- Route53のホストゾーンIDを確認
- IAMユーザーの作成(初回のみ必要な作業)
- レコード更新用Pythonスクリプトの作成
- 起動時スクリプトに設定
この作業の前提は以下の通りです。
- EC2にPythonをインストール済みであること
- 使用するホストゾーンを用意済みであること
ホストゾーンを作るにはドメイン名を取得しておく必要があります。ドメイン名は1つなんでもいいので持っておくことをオススメします。ドメイン名の登録料金・更新料金は私の場合1年で1200円程度なので、EIPを使うより費用が掛かりません。
AWSのドメイン名の料金表を張っておきます。これから取得される方は用途を考え、安いドメイン名を取得してください。
Route53のホストゾーンIDを確認
AWSコンソールのRoute53ダッシュボードに遷移し、ホストゾーンから「ホストゾーンの詳細」からホストゾーンIDを確認しメモします。
IAMユーザーの作成
この作業は初回のみです。
IAMポリシー作成
AWSコンソールのIAMダッシュボードに遷移し、ポリシーから「ポリシー作成」を押下します。
ポリシー作成画面では以下のように設定します。
- サービス : Route53
- アクセスレベル: ListResourceRecordSets
ChangeResourceRecordSets - リソース : ホストゾーンIDで指定
ポリシー名などは任意で設定してください。
IAMユーザー作成
AWSコンソールのIAMダッシュボードに遷移し、ユーザーから「ユーザー作成」を押下します。
ユーザー作成画面では以下のように設定します。
- アクセスの種類:プログラムによるアクセス
- アクセス許可の設定:既存のポリシーをアタッチ
⇒上記で作成したポリシーを選択
ユーザー名は任意で入力してください。
上記の例ではポリシーを「wellknowledge.org–change-route53-record」で作成しているため、同名のポリシーを選択しています。
ユーザー作成の最後にアクセスキーとシークレットキーがあるので確実にメモしてください。
レコード更新用Pythonスクリプトの作成
requestsライブラリとboto3ライブラリをインストールします。
$ pip install requests
$ pip install boto3
Pythonコードは以下の通りです。
import boto3
import requests
AWS_HOST_ZONE_ID="XXXXXXXXXXX"
AWS_RECORD_NAME="XXXXXXXXXXX"
AWS_ACCESS_KEY="XXXXXXXXXXX"
AWS_SECRET_ACCESS_KEY="XXXXXXXXXXX"
client = boto3.client('route53', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
response = client.list_resource_record_sets(
HostedZoneId=AWS_HOST_ZONE_ID,
StartRecordName=AWS_RECORD_NAME,
StartRecordType='A',
MaxItems='1'
)
now_ip=response['ResourceRecordSets'][0]['ResourceRecords'][0]['Value']
new_ip=requests.get("http://httpbin.org/ip").json()['origin']
if now_ip != new_ip:
response = client.change_resource_record_sets(
HostedZoneId=AWS_HOST_ZONE_ID,
ChangeBatch={
'Changes': [
{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': AWS_RECORD_NAME,
'Type': 'A',
'TTL': 60,
'ResourceRecords': [
{
'Value': new_ip
},
],
}
},
]
}
)
基本的に上記コピペで問題ありません。以下の変数だけ値を入れてください。
- AWS_HOST_ZONE_ID :上記で確認したホストゾーンID
- AWS_RECORD_NAME :任意のドメイン(例:xxxx.yyyy.org)
- AWS_ACCESS_KEY :上記で確認したアクセスキー
- AWS_SECRET_ACCESS_KEY:上記で確認したシークレットキー
起動時スクリプトに設定
こちらの作業はLinuxとWindowsによって違います。環境に合わせて行ってください。
Linuxの場合
スクリプトの配置場所は「/opt/route53update」としていますが、任意で変えてください。
起動時のスクリプトは「/etc/rc.local」なので、そこに作成したpythonコードを実行するように記載していきます。
$ cp
$ sudo mkdir /opt/route53update
$ sudo cp route53-update.py /opt/route53update/
$ sudo vi /etc/rc.local
「/etc/rc.local」に以下を追記してください。
python /opt/route53update/route53-update.py
pythonの実行がpythonではなく、python3の場合はそのように書き換えてください。
Windowsの場合
Windowsの場合、起動スクリプトに追記ではなく、タスクスケジューラで起動時に実行するように設定します。
タスクスケジューラの編集画面で、以下のようにタスクを設定してください。
以下の例では、Pythonコードを「C:\Startup_Script\route53-update.py」に配置しています。
以上で設定はすべて完了です。
今後は設定したドメイン名を使用してEC2へのアクセスを名前解決できるようになりました。
おわりに
いかがでしょうか。こちらの作業でEIPの固定費をかけずに済むのでオススメです。EIPはたしか月360円ほどだったと思うのですが、これを節約できるのは個人利用者には大きいと思います。
上記は慣れればすぐ設定できるような内容なので本記事のコードをコピペして使ってもらえたら幸いです。