前提条件
- Route53でHostedZoneを登録してある
- そのZONE_IDを取得してある
- そのHostedZoneを操作する権限を持つIAMユーザを作成してある
- IAMユーザのアクセスキーとシークレットキーを取得してある
必要な権限は下記の通りです。Actionは4つ、ResourceはHostedZoneを指定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:GetHostedZone",
"route53:ListResourceRecordSets",
"route53:ChangeResourceRecordSets",
"route53:GetChange"
],
"Resource": [
"arn:aws:route53:::hostedzone/Z1XUEXAMPLEWR1"
]
}
]
}
IDとキーを保存した環境変数ファイルを作成する
DDNSを実現するには HostedZoneのZONE_ID、IAMユーザのアクセスキーとシークレットキーをスクリプト内で参照する必要があります。これらをハードコーディングしたくないので、環境変数として渡すためのファイルを作成しておきます。
.api_keys
# DDNS
ROUTE53_ZONE_ID=Z1XUEXAMPLEWR1
IAM_DDNS_KEY=AEXAMPLEEXAMPLEU3C7Q
IAM_DDNS_SECRET=YxEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEYss
Dockerコンテナを作成する
Node.jsが動けばなんでもよいのですが、Dockerで準備するのが楽なのでそのようにします。
Dockerfile
FROM node:latest
MAINTAINER flny flny@example.com
RUN npm install nice-route53 \
external-ip
CMD /bin/bash
Route53を操作するために nice-route53 を、自身のグローバルIPを知るために external-ip を それぞれnpmでインストールしています。
docker build と docker runでNode.jsが動作するコンテナを作成します。
$ docker build -t ddns <Dockerfileのあるディレクトリ>
$ docker run -itd --env-file .api_keys --name ddns ddns
スクリプトを記述する
sendDdns.js
#!/usr/bin/env node
var ExtIP = require('external-ip'),
Route53 = require('nice-route53')
;
var configMap = {
zoneId : process.env.ROUTE53_ZONE_ID,
iam_key : process.env.IAM_DDNS_KEY,
iam_sec : process.env.IAM_DDNS_SECRET,
},
getIP = new ExtIP(),
r53 = new Route53(
{accessKeyId : configMap.iam_key,
secretAccessKey : configMap.iam_sec}
),
onReceiveIp, sendRecord
;
sendRecord = function(ip) {
var aRec = {
zoneId : configMap.zoneId,
name : 'foo.example.com.',
type : 'A',
ttl : 3600,
values : [ip]
};
console.log(aRec);
r53.setRecord(aRec, function(err, res) {
if(err) throw err;
console.log(res);
});
};
onReceiveIp = function(err, ip) {
if(err) {
throw err;
}
sendRecord(ip)
}
getIP(onReceiveIp);
- getIPでグローバルIPアドレスを取得して、
- それを元にAレコードを作成し、
- r53.setRecordでAレコードをupsertする
という流れです。パッケージのおかげで楽ちんですね。
動作を確認する
# ./sendDdnsRec.js
{ zoneId: 'Z1XUEXAMPLEWR1',
name: 'foo.example.com.',
type: 'A',
ttl: 3600,
values: [ '110.233.x.x' ] }
{ changeId: 'C316EXAMPLE9ZO',
url: '/change/C316EXAMPLE9ZO',
status: 'PENDING',
submittedAt: Tue May 24 2016 15:47:34 GMT+0000 (UTC) }
コンテナ上で スクリプトを実行すると、うまくいけば status: 'PENDING' のレスポンスが返ります。'PENDING'という記述ですが Aレコードは既に登録されています。
以上