

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon CloudFront を使用して Amazon S3 バケットの静的なコンテンツを VPC 経由で配信する
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront"></a>

*Amazon Web Services、Angel Emmanuel Hernandez Cebrian*

## 概要
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-summary"></a>

Amazon Web Services (AWS) でホストされている静的コンテンツを配信する場合、Amazon Simple Storage Service (S3) バケットをオリジンとして使用し、Amazon CloudFront を使用してコンテンツを配信することが推奨されます。このソリューションには主に 2 つの利点があります。エッジロケーションで静的コンテンツをキャッシュする利便性と、CloudFront ディストリビューションの[ウェブアクセス制御リスト](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl.html) (ウェブ ACL) を定義する機能です。これにより、最小限の設定と管理オーバーヘッドでコンテンツへのリクエストを保護することができます。

ただし、標準的な推奨アプローチには、アーキテクチャ上の共通の制限があります。環境によっては、仮想プライベートクラウド (VPC) に仮想ファイアウォールアプライアンスをデプロイして、静的コンテンツを含むすべてのコンテンツを検査したい場合があります。標準的なアプローチでは、トラフィックを VPC 経由でルーティングして検査することはありません。このパターンは、アーキテクチャ上の代替ソリューションとなります。S3 バケットの静的コンテンツの配信には引き続き CloudFront ディストリビューションを使用しますが、トラフィックはApplication Load Balancer を使用して VPC 経由でルーティングされます。次に、AWS Lambda 関数が S3 バケットからコンテンツを取得して返します。

## 前提条件と制限
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント。
+ S3 バケットにホストされた静的ウェブサイト内容

**制限事項**
+ このパターンのリソースは単一の AWS リージョンにある必要がありますが、異なる AWS アカウントにプロビジョニングできます。
+ 制限は、Lambda 関数が受信および送信できるリクエストとレスポンスの最大サイズにそれぞれ適用されます。詳細については、「[Lambda functions as targets](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html)」(Elastic Load Balancing ドキュメント) の「*Limits*」を参照してください。
+ このアプローチを使用するときは、パフォーマンス、スケーラビリティ、セキュリティ、費用対効果のバランスを取ることが重要です。Lambda はスケーラビリティが高いにもかかわらず、Lambda の同時呼び出しの数が最大クォータを超えると、一部のリクエストがスロットされます。詳細については、Lambda のクォータ（Lambda ドキュメント）を参照してください。Lambda を使用する場合は価格設定も考慮する必要があります。Lambda 呼び出しを最小限に抑えるには、CloudFront ディストリビューションのキャッシュを適切に定義します。詳細については、「[キャッシュと可用性の最適化](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ConfiguringCaching.html)」 (CloudFront ドキュメント)」を参照してください。

## アーキテクチャ
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-architecture"></a>

**ターゲットテクノロジースタック**
+ CloudFront
+ Amazon Virtual Private Cloud (Amazon VPC)
+ Application Load Balancer
+ Lambda
+ Amazon S3

**ターゲットアーキテクチャ**

次の図表では、CloudFront を使用して S3 バケットから VPC 経由で静的コンテンツを提供する必要がある場合の推奨アーキテクチャを示しています。

![トラフィックは VPC のApplication Load Balancerを経由して Lambda 関数に流れます。](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/e0dd6928-4fe0-47ab-954f-9de5563349d8/images/b42c7dd9-4a72-4998-bf88-195c8f90ed3e.png)


1. クライアントは CloudFront ディストリビューションの URL をリクエストして S3 バケット内の特定のウェブサイトファイルを取得します。

1. CloudFront は AWS WAF にリクエストを送信します。AWS WAF は、CloudFront ディストリビューションに適用されたウェブ ACL を使用してリクエストをフィルタリングします。リクエストが有効であると判断された場合、フローは続行されます。リクエストが無効であると判断された場合、クライアントは 403 エラーを受け取ります。

1. CloudFront は内部キャッシュをチェックします。受信したリクエストに一致する有効なキーがある場合、関連する値が応答としてクライアントに送り返されます。そうでなければ、フローは続行されます。

1. CloudFront は、指定した Application Load Balancer の URL にリクエストを転送します。

1. Application Load Balancer には、Lambda 関数に基づいてターゲットグループに関連付けられたリスナーがあります。Application Load Balancer は Lambda 関数を呼び出します。

1. Lambda 関数は S3 バケットに接続して `GetObject` 操作を実行し、コンテンツをレスポンスとして返します。

**自動化とスケール**

このアプローチを使用して静的コンテンツのデプロイを自動化するには、CI/CD パイプラインを作成して、ウェブサイトをホストする Amazon S3 バケットを更新します。

Lambda 関数は、サービスのクォータと制限の範囲内で、同時リクエストを処理するように自動的にスケーリングします。詳細については、「[Lambda 関数のスケーリング](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html)」 と「[Lambda クォータ](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html)」 (Lambda ドキュメント) を参照してください。CloudFront やApplication Load Balancer など、他の AWS のサービスと特徴量については、AWS がこれらを自動的にスケーリングします。

## ツール
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-tools"></a>
+ [Amazon CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) は、世界中のデータセンターネットワークを通じて配信することで、ウェブコンテンツの配信を高速化します。これにより、レイテンシーが減少し、パフォーマンスが向上します。
+ 「[Elastic Load Balancing (ELB)](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html)」 は、受信するアプリケーションまたはネットワークのトラフィックを複数のターゲットに分散します。このパターンでは、Elastic ロードバランサーを通じてプロビジョニングされた 「[Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html)」 を使用して、トラフィックを Lambda 関数に転送します。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) は、あらゆる量のデータを保存、保護、取得できるクラウドベースのオブジェクトストレージサービスです。
+ [Amazon Virtual Private Cloud (Amazon VPC)](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) を使用すると、定義した仮想ネットワーク内で AWS リソースを起動できます。この仮想ネットワークは、お客様自身のデータセンターで運用されていた従来のネットワークに似ていますが、AWS のスケーラブルなインフラストラクチャを使用できるというメリットがあります。

## エピック
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-epics"></a>

### CloudFront を使用して Amazon S3 から VPC 経由で静的なコンテンツを提供する
<a name="use-cloudfront-to-serve-static-content-from-amazon-s3-through-a-vpc"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| VPC を作成します。 | Application Load Balancer や Lambda 関数など、このパターンでデプロイされたリソースをホストするための VPC を作成します。 手順については、「[ VPC の作成](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-VPC)」 （Amazon VPC ドキュメント）を参照してください。 | クラウドアーキテクト | 
| AWS WAF Web ACL を作成する | AWS WAF Web ACL を作成する このパターンの後半で、このウェブ ACL を CloudFront ディストリビューションに適用します。手順については、「[ウェブ ACL の作成](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-creating.html)」 (AWS WAF ドキュメント) を参照してください。 | クラウドアーキテクト | 
| Lambda 関数の作成 | S3 バケットでホストされている静的コンテンツをウェブサイトとして提供する Lambda 関数を作成します。このパターンの 「[追加情報](#serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-additional)」 セクションに記載されているコードを使用してください。ターゲット S3 バケットを識別するようにコードをカスタマイズします。 | AWS 全般 | 
| Lambda 関数をアップロードします。 | 次のコマンドを入力して、Lambda 関数コードを Lambda の.zip ファイルアーカイブにアップロードします。<pre>aws lambda update-function-code \<br />--function-name  \ <br />--zip-file fileb://lambda-alb-s3-website.zip</pre> | AWS 全般 | 
| Application Load Balancer を作成します。 | Lambda 関数を指すインターネット向けApplication Load Balancer を作成します。手順については、「[Lambda 関数のターゲットグループの作成](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#register-lambda-function)」 (Elastic ロードバランサー ドキュメント) を参照してください。高可用性構成の場合は、Application Load Balancer を作成し、それをさまざまなアベイラビリティーゾーンのプライベートサブネットにアタッチします。 | クラウドアーキテクト | 
| CloudFront ディストリビューションを作成します。 | 作成したApplication Load Balancer を指す CloudFront ディストリビューションを作成します。[See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront.html) | クラウドアーキテクト | 

## 関連リソース
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-resources"></a>

**AWS ドキュメント**
+ 「[キャッシュと可用性の最適化](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ConfiguringCaching.html)」 (CloudFront ドキュメント)」を参照してください。
+ 「[Lambda 関数がターゲットとして機能します](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html)」 (Elastic ロードバランサードキュメント)
+ 「[Lambda クォータ](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html)」 (Lambda ドキュメント)

AWS サービスウェブサイト
+ [Application Load Balancer](https://aws.amazon.com/es/elasticloadbalancing/application-load-balancer/)
+ [Lambda](https://aws.amazon.com/en/lambda/)
+ [CloudFront](https://aws.amazon.com/en/cloudfront/)
+ [Amazon S3](https://aws.amazon.com/en/s3/)
+ [AWS WAF](https://aws.amazon.com/en/waf/)
+ [Amazon VPC](https://aws.amazon.com/en/vpc/)

## 追加情報
<a name="serve-static-content-in-an-amazon-s3-bucket-through-a-vpc-by-using-amazon-cloudfront-additional"></a>

**Code**

次の例のLambda 関数が Node.js で記述されます。この Lambda 関数は、ウェブサイトリソースを含む S3 バケットに対して `GetObject` 操作を実行するウェブサーバーとして機能します。

```
/**

 * This is an AWS Lambda function created for demonstration purposes.

 * It retrieves static assets from a defined Amazon S3 bucket.

 * To make the content available through a URL, use an Application Load Balancer with a Lambda integration.
 * 
 * Set the S3_BUCKET environment variable in the Lambda function definition.
 */

var AWS = require('aws-sdk');

exports.handler = function(event, context, callback) {

    var bucket = process.env.S3_BUCKET;    
    var key = event.path.replace('/', '');
    
    if (key == '') {
        key = 'index.html';
    }

    // Fetch from S3
    var s3 = new AWS.S3();
    return s3.getObject({Bucket: bucket, Key: key},
       function(err, data) {

            if (err) {
                return err;
            }

            var isBase64Encoded = false;
            var encoding = 'utf8';
            
            if (data.ContentType.indexOf('image/') > -1) {
                isBase64Encoded = true;
                encoding = 'base64'
            }
    
            var resp = {
                statusCode: 200,
                headers: {
                    'Content-Type': data.ContentType,
                },
                body: new Buffer(data.Body).toString(encoding),
                isBase64Encoded: isBase64Encoded
            };

            callback(null, resp);
        }
    );
};
```