[Terraform] S3 버킷 앞단에 CloudFront를 붙이는 아키텍처 구현

HYEOB KIM·2022년 6월 8일
1

Terraform

목록 보기
5/11

디렉토리 구조

유의사항
반드시 특정 폴더를 만들고 폴더 안에 index.html을 넣어야 한다는 것입니다. 테라폼 파일과 같은 경로에 위치시키고 index.html 을 업로드하면 페이지에 접근 시 정상적으로 접근되지 않고 index.html 파일이 다운로드 됩니다.

아키텍처

S3 버킷을 생성하고, index.html 파일을 업로드한 후, CloudFront를 앞단에 붙여서 CloudFront를 통해 접근하도록 합니다.

코드

provider.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.17.1"
    }
  }
}

provider "aws" {
  profile = var.profile
  region  = "ap-northeast-2"
}

s3.tf

resource "aws_s3_bucket" "test" {
  bucket = "tf-test-hyeob-bucket"

  tags = {
    Name        = "tf-test-hyeob"
    Environment = "Dev"
  }
}

resource "aws_s3_bucket_acl" "test" {
  bucket = aws_s3_bucket.test.id
  # `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `log-delivery-write` 중 하나 선택. 
  # 기본값은 `private`.
  # `grant`와 대비되는 속성
  acl = "public-read"
}

# 파일 업로드
resource "aws_s3_object" "object" {
  bucket = aws_s3_bucket.test.id
  key    = "index.html"
  source = "uploads/index.html"
  content_type    = "text/html"
  etag = filemd5("uploads/index.html")
}

# 버킷 정책
data "aws_iam_policy_document" "s3_policy" {
  # statement {
  #   sid = "bucketPolicyTest"
  #   principals {
  #     type        = "*"
  #     identifiers = ["*"]
  #   }

  #   actions = [
  #     "s3:GetObject"
  #   ]

  #   resources = [
  #     aws_s3_bucket.test.arn,
  #     "${aws_s3_bucket.test.arn}/*",
  #   ]
  # }

  statement {
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.test.arn}/*"]

    principals {
      type        = "AWS"
      identifiers = [aws_cloudfront_origin_access_identity.example.iam_arn]
    }
  }
}
resource "aws_s3_bucket_policy" "example" {
  bucket = aws_s3_bucket.test.id
  policy = data.aws_iam_policy_document.s3_policy.json
}

# resource "aws_s3_bucket_website_configuration" "website-config" {
#   bucket = aws_s3_bucket.test.id
#   index_document {
#     suffix = "index.html"
#   }
# }

cloudfront.tf

resource "aws_cloudfront_origin_access_identity" "test" {
  comment = "This is a test distribution"
}

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = aws_s3_bucket.test.bucket_domain_name
    origin_id   = aws_s3_bucket.test.id

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.test.cloudfront_access_identity_path
    }
  }

  enabled             = true
  is_ipv6_enabled     = true
  comment             = "Some comment"
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = aws_s3_bucket.test.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_All"

  # 지리적 제한: 특정 국가에서만 접근하도록 화이트리스트 작성
  restrictions {
    geo_restriction {
      restriction_type = "none"
      # locations        = ["US", "CA", "GB", "DE"]
    }
  }

  tags = {
    Environment = "production"
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

테스트

객체의 URL로 접근하면 액세스가 거부됩니다.

CloudFront 도메인을 통해 접근하면 index.html 페이지가 나타납니다.

profile
Devops Engineer

0개의 댓글