AWS S3 に静的ウェブサイトをホスティングして独自ドメインで公開するまで
- 公開日
- 更新日
- カテゴリ:AWS
- タグ:AWS,S3,terraform,Route53

静的ウェブサイトを Amazon S3 にホスティングし、独自ドメインで公開するまでの環境構築を terraform を使って行っていきます。
Contents
実行環境
今回の実行環境は以下になります
- Terraform v0.15.1
コードはモジュール化を行わずに一つの tf ファイルに書いていきます。
今回使う AWS のサービスは、S3 と Route53 です。
環境変数について
terraform で構成を定義していくにあたり、環境変数を tfvars に記述しておきますが、以下のようになっています。
- terraform.tfvars
-
aws_id = 123456789 aws_access_key = "XXXXXXXXXXXXXXXXXXXX" aws_secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" aws_region = "ap-northeast-1" domain_name = "example.com" domain_host_name = "www"
- AWS のアカウント情報と、デフォルトのリージョンとして東京リージョンを指定しています。
- ネイキッドドメインとホスト名をそれぞれ分けて定義しています。
変数の設定
これから使用する値について変数とプロバイダを設定しておきます。
- main.tf
-
# variables variable "aws_id" {} variable "aws_access_key" {} variable "aws_secret_key" {} variable "aws_region" {} variable "domain_name" {} variable "domain_host_name" {} provider "aws" { access_key = var.aws_access_key secret_key = var.aws_secret_key region = var.aws_region } locals { fqdn = { name = "${var.domain_host_name}.${var.domain_name}" } bucket = { name = local.fqdn.name } }
- AWS プロバイダを定義しています。
- Route53 や S3 で使用するための FQDN と Bucket 名の変数を作成しています。
アクセスログ用のバケット作成
S3 にホスティングする場合でも、アクセスログを取る事ができます。
(オプション) ウェブトラフィックのログ記録
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/LoggingWebsiteTraffic.html
そのためのバケットを S3 に作成します。(これが無くてもサイト公開はできるので、必要なら作成してください)
- main.tf
-
## AWS アカウントのユーザー data "aws_canonical_user_id" "current_user" {} ## S3 for app logs resource "aws_s3_bucket" "app_logs" { bucket = "${local.bucket.name}-logs" grant { id = data.aws_canonical_user_id.current_user.id permissions = ["FULL_CONTROL"] type = "CanonicalUser" } grant { permissions = ["READ_ACP", "WRITE"] type = "Group" uri = "http://acs.amazonaws.com/groups/s3/LogDelivery" } }
- 権限は ACL ポリシーで設定しています。
- 前者(1 つめの grant)は、コンソール画面から操作できるように、AWS アカウントの正規ユーザーの権限を設定しています。
- 後者(2 つめの grant)は、ログを配信するための権限です。
アプリケーション用のバケット作成
静的なウェブサイトのソースコードを配置する S3 バケットを作成します。
- main.tf
-
## S3 for Static Website Hosting resource "aws_s3_bucket" "app" { bucket = local.bucket.name acl = "public-read" policy = templatefile("bucket-policy.json", { "bucket_name" = local.bucket.name }) website { index_document = "index.html" error_document = "error.html" } logging { target_bucket = aws_s3_bucket.app_logs.id target_prefix = "log/" } }
バケット名は FQDN と同じにします。
templatefile として挿入している json は以下のようになっています。
- bucket-policy.json
-
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::${bucket_name}/*" ] } ] }
logging の部分は、前項でアクセスログ用のバケットを作成した場合に指定するので、作っていなければ指定不要です。
バケットを作成したら index.html を配置してアクセスしてみると表示されます。
独自ドメインの設定
WEB サイトの公開はできましたが、ここまでだと URL が amazonaws.com なので、独自ドメインを設定します。
ドメインとホストゾーンの作成について
ドメインですが、前提として、Route53 に登録済みのドメインを使用します。
また、ネイキッドドメインのホストゾーン登録は済ませてある前提で進めるので、例えば www.example.com で S3 にホスティングしたサイトを公開するなら、そのネイキッドドメインである example.com のホストゾーンは作成しておいてくだださい。
パブリックホストゾーンの作成
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/CreatingHostedZone.html
- ドメイン名はネイキッドドメイン(例:example.com)を入力
- タイプは「パブリックホストゾーン」を指定
これだけです。
ちなみに、ドメインのネームサーバーと、作成したホストゾーンの NS レコードに設定されているネームサーバーが同じ事を確認して、もし違うようならどちらかに揃える必要があります。
レコードの設定
terraform で Route53 にレコードを作成します。
- main.tf
-
# Route 53 ## ネイキッドドメインのホストゾーン情報 data aws_route53_zone "naked" { name = var.domain_name } ## A レコード作成(to S3 Bucket) resource "aws_route53_record" "main_a" { zone_id = data.aws_route53_zone.naked.zone_id name = local.fqdn.name type = "A" alias { evaluate_target_health = true name = "s3-website-${var.aws_region}.amazonaws.com" zone_id = aws_s3_bucket.app.hosted_zone_id } }
- A レコードを作成しています。
- ホストゾーンは、作成済みのネイキッドドメインのホストゾーン情報を取得して zone_id に指定しています。
- エイリアスの設定として、S3 のウェブサイトエンドポイントを設定します。
Amazon S3 バケットでホストされているウェブサイトへのトラフィックのルーティング
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/RoutingToS3Bucket.html
動作確認
レコードを作成したら、あとは DNS の浸透を待ってアクセスすると表示されます。
S3 にホスティングしたウェブサイトを独自ドメインで公開できました。
next:AWS CloudFront で S3 にホスティングした静的ウェブサイトを CDN 配信(&独自ドメインのHTTPS化)