S3バケットにサブドメインを割り当てて外部からアクセス出来るようにする

S3バケットにサブドメインを割り当てて外部からアクセス出来るようにする方法をまとめました。
ドメインをRoute53で管理しているのが前提になります。

バケットを作成します

S3のバケット名をドメイン名と合わせる必要があります。
例)ドメイン名が images.example.comならバケット名もimages.example.comにする必要があります。

bば

「パブリックアクセスをすべてブロック」のチェックを外します。

バケットのブロックパブリック・アクセスを設定している図

上記の設定でバケットは公開状態になりましたが、バケットに作成される個々のオブジェクトは非公開状態で作成されます
デフォルトで公開状態で作成されるようにするにはバケットポリシーを使用します。
バケットポリシーを使用する事でIAMユーザや匿名ユーザに対してバケット内のオブジェクトに対するアクセス許可を付与できます。

バケットのアクセス許可画面を開く

バケットポリシーとして以下を設定します。
全てのユーザ(匿名ユーザ含む)に対してオブジェクトへの参照権限を付与しています。

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"PublicRead",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject","s3:GetObjectVersion"],
      "Resource":["arn:aws:s3:::[バケット名]/*"]
    }
  ]
}

なお、これらの設定が漏れていると、オブジェクトにアクセスした際にAccessDeniedというエラーが発生しますので、上記の設定を見直してみてください。

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>xx</RequestId>
<HostId>xxx//xxxx=</HostId>
</Error>

バケットの静的ウェブサイトのホスティング設定を有効にする

独自のドメインから接続できる様にするにはバケットの「静的ウェブサイトのホスティング設定」を有効にする必要があります。

バケットのプロパティ画面を開く
バケットの静的ウェブサイトホスティングを設定する画面を開く
バケットの静的ウェブサイトホスティングを設定する

Route53の設定を変更する

サブドメインからバケットに接続できるようにレコードを追加します。

ホストゾーンのレコードを設定する画面を開く
ルーティングポリシーを選択する

レコード名はバケット名と同じにします。

レコードの設定画面

もし、バケットの設定に誤りがある場合は以下のエラーが表示されますので、前述の設定を見直してみてください。

(InvalidChangeBatch 400: "" is not a valid hosted zone id. is not a valid encrypted identifier)

動作確認

https://image.example.com/[オブジェクト名]などでオブジェクトにアクセスできればOKです。

terraformの場合

terraformで公開状態のS3バケットを作成するコードは以下の通りです。
※versioningも入っています。

resource "aws_s3_bucket" "default" {
  bucket = "バケット名"
  acl = "public-read"

  versioning {
    enabled = true
  }

  website {
    index_document = "index.html"
  }
}

resource "aws_s3_bucket_policy" "default" {
  bucket = aws_s3_bucket.default.bucket

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Sid = "PublicRead",
        Effect = "Allow",
        Principal = "*",
        Action = ["s3:GetObject", "s3:GetObjectVersion"],
        Resource = ["${aws_s3_bucket.default.arn}/*"]
      }
    ]
  })
}

以上です!

コメントする