Amazon CloudFront を cfcurl.pl から使う

Share/Save

Amazon CloudFront を cfcurl.pl から使う

Amazon EC2 は安くて性能もよい素晴らしいサービスだが、EC2 で画像の多いウェブアプリを作ると画面が表示されるまでにやや時間がかかる。国内に置いたサーバの方に、ユーザエクスペリエンスでは分がある。Amazon CloudFront という CDN(Contents Delivery Network) サービスを使えば、この遅さを解消できるのではないかと期待して試してみた。

手順は次のとおり。

  1. アカウントの設定で Amazon CloudFront を有効にする。EC2 や S3 を使っていても、CloudFront がそのまま使えるわけではない。明示的に有効にする(Sign Up)必要がある。
  2. CloudFront で配信する object(ファイル)を S3 のバケットに用意する。
  3. distribution を作成して domain name を得る。
  4. domain name を用いてHTTPでアクセスする。

ツールのインストール

△perl のモジュールをインストールする

# perl -MCPAN -e shell
Terminal does not support AddHistory.
 
cpan shell -- CPAN exploration and modules installation (v1.7602)
ReadLine support available (try 'install Bundle::CPAN')
cpan> install Digest::HMAC_SHA1
cpan> install FindBin
cpan> install MIME::Base64
cpan> install Getopt::Long
cpan> install File::Temp
cpan> install File::Basename
cpan> install Fcntl
cpan> quit
Terminal does not support GetHistory.
Lockfile removed.

△curl をインストールする

# yum install curl

△Amazon CloudFront Authentication Tool for Curl (cfcurl.pl) をインストールする

# wget <a href="http://d1nqj4pxyrfw2.cloudfront.net/cfcurl.pl" title="http://d1nqj4pxyrfw2.cloudfront.net/cfcurl.pl">http://d1nqj4pxyrfw2.cloudfront.net/cfcurl.pl</a> 

△Amazon用のcurlの設定ファイルを作成する

# cat ~/.aws-secrets
%awsSecretAccessKeys = (
    myaccount => {
        id => '<Your primary AWS Access Key ID>',
        key => '<Your primary Secret Access Key>',
    },
);
# chmod 600 ~/.aws-secrets

distribution を作成する

△object (ファイル) を S3 bucket に用意する

CloudFront での公開向けに新しい bucket を作成して、S3 Fox でディレクトリ毎ドラッグ&ドロップして楽をした。bucket のサブディレクトリのみ公開という設定ができないようなので、AMI などを保存している bucket と共用することはできないと思われる。

△distribution を作成して domain name を割り当ててもらう

distribution とは、S3 bucket に格納した object(ファイル)を CloudFront に認識させるためのもの。S3 と CloudFront をつなげるのが distribution。ドメイン名を指定することはできない。

distribution の作成リクエストを作成する。

# cat create_request.xml
<?xml version="1.0" encoding="UTF-8"?>
  <DistributionConfig xmlns="http://cloudfront.amazonzws.com/doc/2008-06-30/">
  <Origin>yourbucketname.s3.amazonaws.com</Origin>
  <CallerReference>20081209150200</CallerReference>
  <Comment></Comment>
  <Enabled>true</Enabled>
</DistributionConfig>

yourbucketname の部分には自分のバケットの名前を入れる。

distribution の作成リクエストを送信する。

# ./cfcurl.pl --keyname gh -- -X POST -i -H "Content-Type:text/xml; charset=UTF-8" --upload-file create_request.xml <a href="https://cloudfront.amazonaws.com/2008-06-30/distribution" title="https://cloudfront.amazonaws.com/2008-06-30/distribution">https://cloudfront.amazonaws.com/2008-06-30/distribution</a> 
 
HTTP/1.1 100 Continue
 
HTTP/1.1 201 Created
ETag: E1A2X6NUDMD4NF
Location: https://cloudfront.amazonaws.com/2008-06-30/distribution/[distribution ID]
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Tue, 09 Dec 2008 06:07:52 GMT
Server: CloudFront
 
<?xml version="1.0"?>
<Distribution xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Id>[distribution ID]</Id> 
  <Status>InProgress</Status>
  <LastModifiedTime>2008-12-09T06:07:52.160Z</LastModifiedTime>
  <DomainName>yourdomainname.cloudfront.net</DomainName> 
  <DistributionConfig>
    <Origin>yourbucketname.s3.amazonaws.com</Origin>
    <CallerReference>20081209150200</CallerReference>
    <Comment></Comment>
    <Enabled>true</Enabled>
  </DistributionConfig>
</Distribution>
☆実際は改行されていない。

ドメイン名として yourdomainname.cloudfront.net が割り当てられた。yourdomainname の部分は、実際にはランダムに見える数字とアルファベットの羅列になる。

△デプロイ状態を確認する

# ./cfcurl.pl --keyname gh -- https://cloudfront.amazonaws.com/2008-06-30/distribution/[distribution ID]
 
<?xml version="1.0"?>
<Distribution xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Id>[distribution ID]</Id>
  <Status>Deployed</Status&gt 
  ;<LastModifiedTime>2008-12-09T06:07:52.160Z</LastModifiedTime>
  <DomainName>yourdomainname.cloudfront.net</DomainName>
  <DistributionConfig>
    <Origin>yourbucketname.s3.amazonaws.com</Origin>
    <CallerReference>20081209150200</CallerReference>
    <Enabled>true</Enabled>
  </DistributionConfig>
</Distribution>
☆実際は改行されていない。

Deployed になった。

割り当てられたドメイン名を使ってHTTPでアクセスする

http://yourdomainname.cloudfront.net/test.gif などでアクセスできることを確認する。ディレクトリを作成してある場合は http://yourdomainname.cloudfront.net/dir/test.gif となる。

CNAME を使って独自ドメインでアクセスする

yourdomainname.cloudfront.net のまま使っても良いのだが、きれいではない。そこで、独自ドメイン cdn.yourdomain.com に割り当てることにする。

まず、DNS で CNAME を設定する。ここでは、cdn.yourdomainname.com を yourdomainname.cloudfront.net に割り当てる。DNS で設定しただけで cdn.yourdomainname.com でアクセスすると "Sorry, invalid request" とエラーが返るので注意。

CloudFront に CNAME を設定する。まずは distribution configuration を取得する。

# ./cfcurl.pl --keyname gh -- -X GET -i https://cloudfront.amazonaws.com/2008-06-30/distribution/[distribution ID]/config
 
HTTP/1.1 200 OK
ETag: E3UVV2001DSTPM 
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Wed, 10 Dec 2008 01:45:59 GMT
Server: CloudFront
 
<?xml version="1.0"?>
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Origin>yourbucketname.s3.amazonaws.com</Origin>
  <CallerReference>20081209150200</CallerReference>
  <Enabled>true</Enabled>
</DistributionConfig>
☆実際は改行されていない。

取得した XML に CNAME の設定を追加する。ここでは cdn.yourdomainname.com というドメインを設定した。

# cat add_cname_request.xml
<?xml version="1.0"?>
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Origin>yourbucketname.s3.amazonaws.com</Origin>
  <CallerReference>20081209150200</CallerReference>
  <CNAME>cdn.yourdomainname.com</CNAME>
  <Enabled>true</Enabled>
</DistributionConfig>

リクエストを送信する。

# ./cfcurl.pl --keyname gh -- -X PUT <span style="color:red">-H 'If-Match: E3UVV2001DSTPM'</span> -H 'Content-Type: text/xml; charset=UTF-8' --upload-file add_cname_request.xml -i <a href="https://cloudfront.amazonaws.com/2008-06-30/distribution/E34IPDB0XMHUZ8/config" title="https://cloudfront.amazonaws.com/2008-06-30/distribution/E34IPDB0XMHUZ8/config">https://cloudfront.amazonaws.com/2008-06-30/distribution/E34IPDB0XMHUZ8/...</a> 
 
HTTP/1.1 100 Continue
 
HTTP/1.1 200 OK
ETag: E1R8F57QTNMIK7
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Wed, 10 Dec 2008 01:54:39 GMT
Server: CloudFront
 
<?xml version="1.0"?>
<Distribution xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Id>E34IPDB0XMHUZ8</Id>
  <Status>InProgress</Status>
  <LastModifiedTime>2008-12-10T01:54:39.556Z</LastModifiedTime>
  <DomainName>daazlu5bwln5.cloudfront.net</DomainName>
  <DistributionConfig>
    <Origin>yourbucketname.s3.amazonaws.com</Origin>
    <CallerReference>20081209150200</CallerReference>
    <CNAME>cdn.yourdomainname.com</CNAME>
    <Enabled>true</Enabled>
  </DistributionConfig>
</Distribution>
☆実際は改行されていない。

http://yourdomainname.cloudfront.net/test.gif などでアクセスできることを確認する。

distrubution を削除する

ETag を取得する。

# ./cfcurl.pl --keyname gh -- -X GET -i https://cloudfront.amazonaws.com/2008-06-30/distribution/[distribution ID]/config
 
HTTP/1.1 200 OK
ETag: E1A2X6NUDMD4NF 
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Tue, 09 Dec 2008 06:49:07 GMT
Server: CloudFront
 
<?xml version="1.0"?>
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Origin>yourbucketname.s3.amazonaws.com</Origin>
  <CallerReference>20081209150200</CallerReference>
  <Enabled>true</Enabled>
</DistributionConfig>

上記で得られた ETag と XML をどこかに保存しておく。XML の中の Enabled を false にして、PUT すると、distribution を disabled にできる。

-bash-3.2# ./cfcurl.pl --keyname gh -- -X PUT -H 'If-Match: E1A2X6NUDMD4NF' -H 'Content-Type: text/xml; charset=UTF-8' --upload-file disable_request.xml -i https://cloudfront.amazonaws.com/2008-06-30/distribution/[distribution ID]/config
 
HTTP/1.1 100 Continue
 
HTTP/1.1 200 OK
ETag: E1VR3TXI7JKY94 
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Tue, 09 Dec 2008 07:43:19 GMT
Server: CloudFront
 
<?xml version="1.0"?>
<Distribution xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Id>[distribution ID]</Id>
  <Status>InProgress</Status>
  <LastModifiedTime>2008-12-09T07:43:20.254Z</LastModifiedTime>
  <DomainName>yourdomainname.cloudfront.net</DomainName>
  <DistributionConfig>
    <Origin>yourbucketname.s3.amazonaws.com</Origin>
    <CallerReference>20081209150200</CallerReference>
    <Enabled>false</Enabled>
  </DistributionConfig>
</Distribution>
☆実際は改行されていない。

上記で得られた ETag の値を用いて distribution を削除する。

# ./cfcurl.pl --keyname gh -- -i -X DELETE -H 'If-Match: E1VR3TXI7JKY94' https://cloudfront.amazonaws.com/2008-06-30/distribution/[distribution ID]

(おまけ)distribution の一覧を取得する

# ./cfcurl.pl --keyname gh -- -i -X GET <a href="https://cloudfront.amazonaws.com/2008-06-30/distribution" title="https://cloudfront.amazonaws.com/2008-06-30/distribution">https://cloudfront.amazonaws.com/2008-06-30/distribution</a> 
 
HTTP/1.1 200 OK
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Tue, 09 Dec 2008 08:02:09 GMT
Server: CloudFront
 
<?xml version="1.0"?>
<DistributionList xmlns="http://cloudfront.amazonaws.com/doc/2008-06-30/">
  <Marker></Marker>
  <MaxItems>100</MaxItems>
  <IsTruncated>false</IsTruncated>
  <DistributionSummary>
    <Id>[distribution ID]</Id>
    <Status>Deployed</Status>
    <LastModifiedTime>2008-12-09T06:45:12.827Z</LastModifiedTime>
    <DomainName>yourdomainname.cloudfront.net</DomainName>
    <Origin>yourbucketname.s3.amazonaws.com</Origin>
    <Enabled>false</Enabled>
  </DistributionSummary>
</DistributionList>
☆実際は改行されていない。

それにしても、S3 はコマンドラインから操作しようとすると、何をするのにも苦痛を伴う。普通は S3Fox などを使うほうがいい。

  • S3Fox は無料。v0.4.5 で CloudFront の distribution も操作できるようになった。
  • Bucket Explorer は有料の Amazon S3、CloudFront の操作ソフト。CloudFront 対応はまだベータ版。しかも、ベータ版はお試し利用ができずに、ライセンスを購入する必要があるようだ。