Amazon CloudFrontがIPv6に対応予定なのでウォッチするページを作ってみた
ども、大瀧です。 先日CloudFrontでアップデートがあり、IPv6対応がアナウンスされました。実際にIPv6アドレスが有効になるのは数週間程度かかるとのことなので、その状況をウォッチするページを作ってみました。
CloudFrontの設定
まずは、CloudFrontでIPv6を有効にする設定を確認しておきます。新規で作成するWeb Distributionでは、既定でIPv6が有効になります。既存Distributionでは、[Distribution Settings]の[General]タブに[Enable IPv6]という設定があるので、このチェックをオンにしましょう。
Route 53のエイリアスレコードをCloudFrontに設定している場合は、IPv6ホスト名に対応するAAAAレコードでエイリアスを追加します。
これでOKです。
ウォッチページのアーキテクチャ
IPv6を有効にしても、日本からは本日時点でAAAAレコードは無いとエラーが返ってきます(takipone.comにはAレコードとAAAAレコードの両方にCloudFrontのエイリアスを設定済み)。
$ host takipone.com takipone.com has address 54.192.234.164 takipone.com has address 54.192.234.80 takipone.com has address 54.192.234.71 takipone.com has address 54.192.234.216 takipone.com has address 54.192.234.197 takipone.com has address 54.192.234.76 takipone.com has address 54.192.234.213 takipone.com has address 54.192.234.167 takipone.com mail is handled by 10 inbound-smtp.us-west-2.amazonaws.com. $ host -t aaaa takipone.com takipone.com has no AAAA record $
AWS側でIPv6が有効化されるとこのAAAAレコードのレスポンスが返ってくるであろう、ということでAWS Lambdaが利用できるAWSの全リージョンで1時間に1回AAAAレコードのDNS問い合わせを行い、その結果をS3にアップするLambdaを配置し、それを確認できるWebページを作りました。
Not yet
は、上記のレコードなしの場合の表示です。IPv6アドレスが返ってくるとDeployed
と表示するようになっています。アーキテクチャを図にすると以下のような感じです。
Lambdaはipv6deployedtoyouredgelocation.com
のAAAAレコードを問い合わせ、レスポンスによって文字列を場合分けし、それをS3バケットipv6deployedtoyouredgelocation.com
にJSONファイルとしてアップロードします。コードは以下の通りです。
var AWS = require('aws-sdk'); var dns = require('dns'); var domain = 'ipv6deployedtoyouredgelocation.com'; exports.handler = function(event, context, callback) { var result = {}; // query dns AAAA record dns.resolve6(domain, (err, addresses) => { var date = new Date(); if (err && err.code == 'ENODATA') { result.status = 'Not yet'; result.timestamp = date; } else if (err) { result.status = 'Error'; result.timestamp = date; } else { result.status = 'Deployed'; result.addresses = addresses; result.timestamp = date; } var s3 = new AWS.S3(); var index = { current_status: result.status, history_files: [], timestamp: date }; var region = context.invokedFunctionArn.split(':')[3] var history_filename = 'data/' + region + '/' + date.getTime() + '.json'; var params = {Bucket: domain, Key: 'data/' + region + '/index.json'}; s3.getObject(params, function(err, data) { if (err && err.statusCode == 404) { // when first execution console.log('index file creating...'); index.history_files = [history_filename]; } else if (err) { console.error(err); } else { // add log current_index = JSON.parse(data.Body.toString()); index.history_files = current_index.history_files.concat([history_filename]); } params = { Bucket: domain, Key: history_filename, Body: JSON.stringify(result), ACL:'public-read', ContentType: 'application/json' }; s3.putObject(params, function(err, result) { if(err) console.error(err); else console.log(history_filename + " uploaded."); }); params = { Bucket: domain, Key: 'data/' + region + '/index.json', Body: JSON.stringify(index), ACL:'public-read', ContentType: 'application/json' }; s3.putObject(params, function(err, result) { if(err) console.error(err); else console.log("index file uploaded."); }); console.log(index); }); }); callback(null, ""); }
アップロードされたJSONファイルを同じS3バケットに配置したHTMLファイルからAjaxで読み込み、上記のような結果を表示しています *1。
まとめ
CloudFrontのIPv6対応と、その状況を確認するWebページのご紹介でした。こちらの記事でも触れているAWSのIPv6対応が、また一歩進みましたね。
コードと英語がかなり適当なので、添削歓迎です!なお、ヒストリーが一覧できるように鋭意開発中です。IPv6が有効化されるまでになんとかしなければ。。。
脚注
- ちなみに、Webページ自体をCloudFrontでキャッシュし、ACMの証明書を用意してHTTP/2でホストするイマドキな構成です。 ↩