LoginSignup
25
19

More than 5 years have passed since last update.

Cloud Frontから特定のS3バケットにある画像にアクセスできるようにする(cache distributionパターン)

Last updated at Posted at 2019-04-21

やりたかったこと

s3にuploadした画像を cache distributionパターンで管理しアクセスできるようにしたい。
Infrastructure as Code100%を目指しているので、リソースの作成はterraformで!
※ 独自ドメインでアクセスできるようにしたいのでroute53の設定もしますが、SSL証明書は発行してある前提です。Cloud Frontはus-eastで発行しないと作成できないので要注意です!(罠)

構成

Untitled Diagram.png

作成手順

上の構成図の下から順に作っていこうと思います👍
全てのterraformコードを載せています。

S3の作成

s3.tf
resource "aws_s3_bucket" "image-bucket" {
  bucket = "image-bucket"
  acl    = "private"
  region = "ap-northeast-1"
}

まず上記のコードのみapplyしてみましょう。
そしてコンソールからimage-bucketにimageをuploadし、 https://s3-ap-northeast-1.amazonaws.com/image-bucket/image.png にアクセス。
privateバケットなのでアクセスできないはずですね。
image.png

Origin Access Identityの作成

上記の通りS3に直接アクセスすることはできませんが、Cloud Frontからはアクセスできるようにするため、Origin Access Identityを作成します。あとでS3のPolicyに紐づけることで、Cloud Frontからのアクセスを許可できます。

cloudfront.tf
resource "aws_cloudfront_origin_access_identity" "origin_access_identity" {
  comment = "origin access identity for s3"
}

S3のPolicyを作成

principalsのidentifiersで先ほど作成したOrigin Access Identityを指定し、Cloud Front → S3 bucket の一部アクションを許可をします。

iam.tf
data "aws_iam_policy_document" "cf_to_s3_policy" {
  statement {
    actions = ["s3:GetObject", "s3:ListBucket"]

    resources = [
      "${aws_s3_bucket.image-bucket.arn}",
      "${aws_s3_bucket.image-bucket.arn}/*",
    ]

    principals {
      type        = "AWS"
      identifiers = ["${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"]
    }
  }
}

そしてこのpolicyをs3に繋げてあげます。

iam.tf
resource "aws_s3_bucket_policy" "cf-to-s3" {
  bucket = "${aws_s3_bucket.image-bucket.id}"
  policy = "${data.aws_iam_policy_document.cf_to_s3_policy.json}"
}

Cloud Frontの作成

よしなに指定する箇所

  • origin/domain_name
    • S3バケットのドメイン名
  • s3_origin_config/origin_access_identity
    • Origin Access Identityのパス
  • aliases
    • 名前解決させたい独自のドメイン名
  • viewer_certificate/acm_certificate_arn
    • 独自ドメインを発行したacmのarn(us-eastである必要があります)

他パラメータの補足

  • default_cache_behavior
    • cacheサーバーの細かい設定
  • price_class
    • cacheサーバーとして利用する地域のクラスを選択
  • restrictions
    • ユーザーリクエストの地域制限を設定、white listとblack listを登録できる
cloudfront.tf
resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = "${aws_s3_bucket.image-bucket.bucket_regional_domain_name}"
    origin_id   = "${aws_s3_bucket.image-bucket.id}"

    s3_origin_config {
      origin_access_identity = "${aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path}"
    }
  }

  enabled         = true
  is_ipv6_enabled = false
  comment         = "comment"

  logging_config {
    include_cookies = false
    bucket          = "${aws_s3_bucket.image-bucket.bucket_domain_name}"
    prefix          = "prefix"
  }

  aliases = ["sample.com"]

  default_cache_behavior {
    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "${aws_s3_bucket.image-bucket.id}"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "allow-all"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  price_class = "PriceClass_200"

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  tags = {
    Environment = "dev"
  }

  viewer_certificate {
    acm_certificate_arn = "arn:aws:acm:us-east-1:xxx:certificate/xxx"
    ssl_support_method  = "vip"
  }
}

Cloud Frontの設定は、us-eastしか受け付けない問題から始まり、restrictionsをサーバーの話かと思いwhite listに日本(JP)を入れずに設定してしまったりと(自分もアクセスできなくなるw)ちょっと詰まりました・・・。

さて、Cloud Front→S3まではできたのでapplyしてみましょう。
(Cloud Frontの作成は30minほどかかります😓)

Cloud Frontが無事に作成されたら、domain nameを確認しアクセスしてみましょう。リクエストが成功し、S3にuploadした画像をみることができました🎉
image.png

route53のRecordの作成

最後に独自ドメインからもアクセスできるようにします。

よしなに指定する箇所

  • zone_id
    • HostedZoneのid
  • name
    • アクセスできるようにするドメイン名
  • records
    • cnameの値=先ほど作成したCloud Front Distributionのドメイン名(xxx.cloudfront.net)
route53.tf
resource "aws_route53_record" "cname" {
  zone_id = "xxx"
  name    = "sample.com"
  type    = "CNAME"
  ttl     = "300"
  records = ["${aws_cloudfront_distribution.s3_distribution.domain_name}"]
}

これでapplyしてみましょう!
sample.com/image.png にアクセスして画像が表示されました🎉
image.png

25
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
19