【所要時間10分】Terraformを使って、S3でWebサイトを公開する!

July 30, 2020

今個人で開発しているSPA(シングルページアプリケーション)で、フロント資材をS3にアップして公開する作業を行ったので、その時の手順を残したいと思います。この記事を見れば、最低限S3でWebサイトを公開できるようになるはず!

目次 1.S3バケットを作成する。
2.パブリックアクセスブロックを設定する。
3.バケットポリシーを作成する。
4.公開するHTMLをアップロードする。

S3バケットを作成する。

Webサイトを公開するためのバケットを作成していきます。

main.tf

resource "aws_s3_bucket" "mini_schna_frontend" {
  # バケット名 
  # ※本記事では解説しませんが、Route53を使ってドメイン公開したい場合、「Route53のレコード名=バケット名」にならないといけないので注意!
  bucket        = "${var.env}.mini-schna.com"

  # Webサイトを公開したいため、全てのユーザーに読み取り権限を許可します。
  #  アクセスコントロールリスト (ACL) の概要: https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/acl-overview.html
  acl           = "public-read"
 
  # バケットポリシーの設定。後ほど解説します。
  policy        = data.aws_iam_policy_document.mini_schna_bucket_policy.json

  # バケットにオブジェクトが入った状態では、Terraformからバケットを削除できない(false)。
  # ※今回は念の為。
  force_destroy = false
 
  # Webサイトの設定。
  website {
    # S3にアクセスしたときにデフォルトで表示されるファイル。
    index_document = "index.html"
    # エラーが発生した時に表示されるデフォルトのファイル。今回は準備できていないので使用しません。
    error_document = ""
    
    # 下記はリダイレクト設定。今回はリダイレクトを使用しないため無効。
    # redirect_all_requests_to = ""
    # routing_rules {}
  }

  # CORSの設定。今回はWebサイトを最低限公開するだけなので特に設定しません。
  # cors_rule {
  #   allowed_methods = []
  #   allowed_methods = []
  #   allowed_origins = []
  #   expose_headers = []
  #   max_age_seconds = 3000
  # }

  # オブジェクトのバージョン管理設定。「古いバージョンに戻したい!」等ができるようになります。
  versioning {
    enabled    = true  # バージョン管理するためtrue。
    mfa_delete = false # オブジェクトへのアクセスにMFAは使用しないためfalse。
  }

  # このバケットに対するアクセスログの扱い方に関する設定。今回はログに残さないため無効。
  # logging {}

  # オブジェクトのライフサイクル設定。今回はライフサイクル設定は使用しないため無効。
  # ※ライフサイクル設定の解説は少し長くなってしまうため、別記事にまとめようと思います。
  # lifecycle_rule {
  #   id      = "assets"
  #   enabled = true
  #   expiration {
  #     days = "7"
  #   }
  #   transition {
  #     days          = "30"
  #     storage_class = "STANDARD_IA"
  #   }
  #   noncurrent_version_expiration {
  #     days = "3"
  #   }
  #   noncurrent_version_transition {
  #     days          = "3"
  #     storage_class = "STANDARD_IA"
  #   }
  # }

  # Trancefer Accelerationの設定。大きいサイズ(テラバイト等)のデータをアップロードしたりしないため無効。
  # (使用する場合、追加料金が必要になります。)
  # acceleration_status = "Suspended"

  region        = "ap-northeast-1"
  # S3の料金を誰が支払うかの設定。今回支払うのはバケット所有者。
  request_payer = "BucketOwner"

  # オブジェクトのレプリケーションは使用しないため無効。
  # replication_configuration {}

  # オブジェクトのサーバサイド暗号化の設定。今回は公開するため無効。
  # server_side_encryption_configuration {
  #   rule {
  #     apply_server_side_encryption_by_default {
  #       # AWS管理のCMKで暗号化する。
  #       sse_algorithm = "AES256"
  #    }
  #   }
  # }

  # オブジェクトロックは利用しないため無効。
  # object_lock_configuration {
  #   object_lock_enabled = false
  #   rule {
  #     default_retention {
  #       mode  = "GOVERNANCE"
  #       years = "1"
  #     }
  #   }
  # }

  tags = {
    Env = "dev"
  }
}

パブリックアクセスブロックを設定する。

パブリックアクセスブロック設定は、ポリシーやACL設定を上書きし、パブリックアクセスを制限する機能。
今回は、後述するバケットポリシーで設定を行うため、この機能が有効になっているとWebサイトを公開することがきません。そのため、ポリシーに関する機能を無効にします。

main.tf

resource "aws_s3_bucket_public_access_block" "mini_schna_frontend" {
  bucket                  = aws_s3_bucket.mini_schna_frontend.bucket
  block_public_acls       = true   # バケットポリシーでアクセス制御するため、ACL設定はパブリックアクセスブロック設定で上書きして大丈夫。
  block_public_policy     = false  # バケットポリシーでアクセス制御したいためfasle。
  ignore_public_acls      = true   # バケットポリシーでアクセス制御するため、ACL設定はパブリックアクセスブロック設定で上書きして大丈夫。
  restrict_public_buckets = false  # バケットポリシーでアクセス制御したいためfasle。
}

バケットポリシーを作成する。

バケットポリシーでS3バケットの公開設定を行います。

main.tf

data "aws_iam_policy_document" "mini_schna_bucket_policy" {
  statement {
    sid    = ""
    effect = "Allow"

   # 全てのユーザーからのアクセスを許可するため「*」を設定。
    principals {
      identifiers = ["*"]
      type        = "*"
    }

    # ファイルの閲覧のみ許可する。
    actions = [
      "s3:GetObject"
    ]

    # 今回作成するバケットのみ許可する。
    resources = [
      "arn:aws:s3:::${var.env}.mini-schna.com",  # 「[バケット名]/*」で許可したい場合は、「バケット名」も許可する必要があります。
      "arn:aws:s3:::${var.env}.mini-schna.com/*"
    ]
  }
}

公開するHTMLをアップロードする。

下記のファイルをindex.htmlという名称で作成したS3バケットにアップロードしてください。

index.html

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>My Website Home Page</title>
</head>
<body>
  <h1>Welcome to my website</h1>
  <p>Now hosted on Amazon S3!</p>
</body>
</html>

そして、下記のいずれかのURLにアクセスするとWebページが表示されます。

s3-website ダッシュ (-) リージョン:http://[バケット名].s3-website-[リージョン].amazonaws.com
s3-website ドット (.) リージョン:http://[バケット名].s3-website.[リージョン].amazonaws.com

このようなWebページが表示されます。 terraform s3 public access 01

まとめ

以上で、S3バケットの作成が完了です。最低限の設定になりますが、これでWebサイトを公開することができます。