どうも、開発・運用部の川口です。今回は「CloudFront-CustomOrigin(以下、CustomOrigin)」を触ってみました。
CloudFrontとは簡単に言うとAmazonが提供する従量課金制のCDNサービスの事です。edgeサーバーが日本にあるので大規模なアクセスや容量のある静的コンテンツの配布に非常に高い性能を発揮してくれます。サービス開始以来、ストレージとしてAmazonS3しか対応していなかったのですが2010年11月にCustomOrign(独自サーバ)に対応しました。これにより複数人でコンテンツをアップロードする必要性がある場合にもわざわざManagementConsoleやS3Organizer(FireFoxのS3アドオン)の利用方法を覚える必要が無くなり、利便性やセキュリティ面においてより使い勝手の良い構成を組むことが可能となりました。
現時点(2011/01/25)ではCustomOriginのdistributionはManagementConsoleから作成することが出来ないようです(サードパーティ製のCloudFront設定ツールはあらかた対応している模様)。ステータス確認やdistributionの利用指定は可能ですのでその時はManagementConsoleを使いましょう。
1. Toolを準備する
今回、簡単に試すために[AWS SDK for PHP]を利用していきます(他言語のSDKも既に対応している模様なのでPHP以外の言語を利用されている方は各自読み替えてください)。rubyの場合は[right_aws(RightScale社が出しているaws用RubyGems)]等を利用すると便利らしいです。
アクセスキーの準備
AWSAccessKeyIDとAWSSecretKeyを「アカウント」→「セキュリティ証明書」より取得できます。わからない方はこちらの画像を参考にしてください。
configファイルを設定する
ダウンロードしてAPIを利用するためのアクセスキーの設定を行います。
$ wget http://pear.amazonwebservices.com/get/sdk-1.2.2.zip
$ unzip sdk-1.2.2.zip
$ cd sdk-1.2.2/sdk-1.2.2
$ cp config-sample.inc.php config.inc.php
$ vi config.inc.php
==================================================
define('AWS_KEY', '<アクセスキーを入力>');
define('AWS_SECRET_KEY', '<シークレットキーを入力>');
==================================================
設定が完了したら動作確認を行います。下記のような現在のdistributionの内容を表示するプログラムを作成・実行してみましょう。
$ cat list_distribution.php
==================================================
require('sdk.class.php');
$cf = new AmazonCloudFront();
$response = $cf->list_distributions();
var_dump($response->body);
==================================================
$ php list_distribution.php
object(CFSimpleXML)#5 (4) {
["@attributes"]=>
array(1) {
["ns"]=>
string(47) "http://cloudfront.amazonaws.com/doc/2010-11-01/"
}
["Marker"]=>
object(CFSimpleXML)#3 (0) {
}
["MaxItems"]=>
string(3) "100"
["IsTruncated"]=>
string(5) "false"
}
もしこの時点でエラーが出る場合は大半が未アクティベートな事が原因です。こちらからCloudFrontアクティベートを行って再試行してみてください。
※既にdistributionを作成されている方はレスポンス内容が若干異なります。
2. 事前準備を行う
CustomOriginを準備する
まずCustomOriginに指定する独自サーバーを用意しなくてはなりません。各自で持っているサーバーで構いませんが必ずドメインの名前解決が出来るようにしておく必要があります。とりあえずサクっとEC2でサーバーを立て、確認用の画像ファイル(logo-serverworks.png)をアップロードしておきます。実際にブラウザからアクセスできることも確認しておきましょう。
(http://ec2-XXX-XXX-XXX-XX.ap-southeast-1.compute.amazonaws.com/logo-serverworks.png)
ログ保存用S3Bucketを準備する
distribution情報を保管するためのS3Bucketが必須となりますのでコンソールでもAPIでも良いので作成しておきましょう。ここには実際にedgeサーバーへ配布された際のログがgzファイルで蓄積されていきます。作成したBucket名は後で利用するので保管してください(今回は[dev-swx-logs]としました)。
独自ドメインを用意する
実際にCloudFrontへ向ける独自ドメインを用意、今回は例として[example.com]を使用します。
3. distributionを作成する
今回のキモであるdistributionを作成していきます。
$ vi create_distribution.php
==================================================
require('sdk.class.php');
$cf = new AmazonCloudFront();
$origin = "http://ec2-XXX-XXX-XXX-XX.ap-southeast-1.compute.amazonaws.com";
$caller_reference = 'CloudFront-CustomOrigin' . time();
$option = array(
'Enabled' => true,
'Comment' => 'custom origin test',
'OriginProtocolPolicy' => 'http-only',
'CNAME' => 'example.com',
'Logging' => array(
'Bucket' => 'dev-swx-logs',
'Prefix' => 'example.com'
)
);
$response = $cf->create_distribution($origin, $caller_reference, $option);
var_dump($response->body);
※[create_distribution]メソッドの引数は左から順に下記の通り
引数 | 値 | 補足 |
---|---|---|
$origin | originサーバホスト名 | CloudFront対象となるサーバのドメイン名(or S3Bucket名) |
$caller_reference | リクエストID | CloudFront上でユニークな必要がある |
$option | distributionオプション | CloudFront-APIへ送信されるXML内容。APIドキュメントを見ながら指定。 |
(オプション)
- Enable
- 初期のCloudFrontの有効フラグ
- 'true'なら当然distributionが作成された瞬間に有効化
- OriginProtocolPolicy
- [http-only][match-viewer]
- アクセスポリシーを決定(詳細を調査中)
- HTTPSを使う場合は'match-viewer'を使う必要がある
- CNAME
- distributionで利用する独自ドメインのドメイン名を指定する
- 必須ではないが指定をせずに独自ドメインをCNAME指定するとエラーになる(オマケ参照)
- 複数指定が可能('CNAME' => array('example1.com', 'example2.come'))
- Logging
- [Bucket]・・・ログを保存するS3Bucket名
- [prefix]・・・S3Bucket内にて作成されるログディレクトリ名
$ php create_distribusion
object(CFSimpleXML)#3 (7) {
["@attributes"]=>
array(1) {
["ns"]=>
string(47) "http://cloudfront.amazonaws.com/doc/2010-11-01/"
}
["Id"]=>
string(14) "E2T5YVJK9KWWM9"
string(33) "CloudFront-CustomOrigin1295793351"
["Status"]=>
string(10) "InProgress"
["LastModifiedTime"]=>
string(24) "2011-01-23T14:35:52.285Z"
["InProgressInvalidationBatches"]=>
string(1) "0"
["DomainName"]=>
string(29) "d35ygdhp9w5kro.cloudfront.net"
(以下、略)
作成されたらしばらく待つ必要があります。ステータスが'InProgress'→'Deployed'へ変化したらCloudFrontの設定は完了です(この時点でMangementConsoleからdistributionが作成されていることが確認できます)。response内の'DomainName'は必要となるのでコピーしておきましょう。
4. CloudFrontを利用する
コピーしておいた'DomainName'へアクセスして実際にCloudFrontを利用してみましょう。[d35ygdhp9w5kro.cloudfront.net/logo-serverworks.png]へブラウザでアクセスして画像が表示されているなら成功です。実際に元画像をCustomOriginから削除してからアクセスしても問題なく画像が表示される為CloudFrontのedgeサーバへキャッシュされていることが確認できる筈です。
※独自ドメインを利用する際にはこの[d35ygdhp9w5kro.cloudfront.net]へCNAMEをセットするだけです。
オマケ
edgeサーバからコンテンツを消せる
知らなかったんですがいつの間にかedgeサーバへキャッシュされたコンテンツを消すことが可能となっているようです(以前はフォルダに連番をつけたりheaderに短いTTLを仕込んだりと大変だったんですが・・・)。即座に消えるわけではありませんが以前までの'最速で3600秒'といった制約は受けません。削除間隔についてはドキュメントによると約15分以内、となっているようです。
http://docs.amazonwebservices.com/AmazonCloudFront/2010-11-01/DeveloperGuide/
CustomOriginホストにIP指定できない
そのまんまです。必ずドメイン名で指定する必要があり、CustomOriginに指定するサーバは必ずCloudFront側で名前解決できるドメインを付けていなくてはなりません。
CustomOriginのパスに'/'を含められない
プロトコル部を除いて'/'が入るとdistributionの作成に失敗します。なのでサーバーの特定ディレクトリ毎にディストリビューションを作成することは出来ません。また、特定ディレクトリ指定用のオプションもないので現時点では動的にディレクトリ指定をすることは不可能なようです(これが可能か知りたくて今回の検証を行いました)。
CNAME指定しない場合の挙動について
CNAMEは必須項目ではないのですが独自ドメインを利用した際にはここが指定されていないとCloudFrontは正常なデータのキャッシュを行ってくれません。挙動としては下記の状態となりますので注意が必要です。
ドメイン | - |
---|---|
CustomOriginサーバ | ec2-XXX-XXX-XXX-XX.ap-southeast-1.compute.amazonaws.com |
distribution | dr09fj0q00.cloudfront.net |
アクセス用独自ドメイン | cloudfront.com([dr09fj0q00.cloudfront.net]のへのCNAME) |
distribution作成時の[CNAME]に[アクセス用独自ドメイン]を未設定の場合、[dr09fj0q00.cloudfront.net]へのアクセスは問題なく動作しますが[cloudfront.com]へのアクセスをCloudFront側が行わずに下記のようなレスポンスを返します。
CustomOriginはN:Nで指定可能
'CallerReference'がユニークであれば1つAWSアカウントで複数のCustomOriginを持つことが可能、逆に複数のAWSアカウントから1つのCustomOriginサーバを指定することも可能です。
まとめ
APIの仕様やCloudFrontの挙動を理解すれば非常に簡単に設定できる事が解りました。CustomOrigin機能は多くの応用が出来そうなので今後の選択肢として有意義な検証が出来きたと思います。