> For the complete documentation index, see [llms.txt](https://terraform201.devart.tv/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://terraform201.devart.tv/3.-static/cloudfront-s3-1.md).

# (Optional)Custom 도메인 사용하기

{% hint style="info" %}
본 실습은 도메인을 이미 보유하고 있는 경우에만 가능하니, 도메인을 구매하지 않으신 분들은 참고만 하시면 됩니다!
{% endhint %}

도메인이 AWS Route53에 등록되어 있다면 다음과 같은 절차를 통해서 ACM(AWS Certificate Manager)를 생성하실 수 있습니다.

* CloudFront는 전세계에 배포되는 서비스이기 때문에,  ACM을 생성할 때 반드시 `us-east-1` 리전을 사용하셔야 합니다!

### AWS Certificate Manager 생성하기

[ACM을 이용한 HTTPS 설정](/2./acm-https.md)

이제 코드를 다음과 같이 수정합니다!

* CloudFront 코드 중 alias 에 사용할 도메인을 입력합니다.&#x20;
  * ex) `cdn.devops-art-factory.com`
* 위와 동일한 도메인을 aws\_route53\_record 에도 등록합니다.
* Route53 Zone ID를 입력합니다.

{% code title="terraform/s3/art-id/id\_apnortheast2/contents-devart\_with\_domain.tf" %}

```hcl
# S3 Bucket for storing contents
resource "aws_s3_bucket" "contents_devart" {
  bucket = "${var.account_namespace}-contents-${var.shard_id}"
}

resource "aws_s3_bucket_public_access_block" "contents_devart" {
  bucket = aws_s3_bucket.contents_devart.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_cors_configuration" "contents_devart" {
  bucket = aws_s3_bucket.contents_devart.id

  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["GET", "HEAD"]
    allowed_origins = ["*"]
    expose_headers  = ["ETag"]
    max_age_seconds = 3000
  }
}

resource "aws_s3_bucket_versioning" "contents_devart" {
  bucket = aws_s3_bucket.contents_devart.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_accelerate_configuration" "contents_devart" {
  bucket = aws_s3_bucket.contents_devart.id
  status = "Enabled"
}

resource "aws_s3_bucket_policy" "contents_devart" {
  bucket = aws_s3_bucket.contents_devart.id
  policy = data.aws_iam_policy_document.contents_devart.json
}

data "aws_iam_policy_document" "contents_devart" {
  statement {
    principals {
      type        = "Service"
      identifiers = ["cloudfront.amazonaws.com"]
    }

    condition {
      test     = "StringEquals"
      variable = "AWS:SourceArn"
      values = [
        aws_cloudfront_distribution.devart_cdn_distribution.arn,
      ]
    }

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

resource "aws_s3_bucket_lifecycle_configuration" "contents_devart" {
  bucket = aws_s3_bucket.contents_devart.id

  rule {
    id     = "contents_devart_rule"
    status = "Enabled"

    transition {
      days          = 30
      storage_class = "STANDARD_IA"
    }
  }
}

resource "aws_cloudfront_origin_access_control" "devart_contents" {
  name                              = "devart-contents"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

# Cloudfront Distribution
resource "aws_cloudfront_distribution" "devart_cdn_distribution" {
  origin {
    domain_name              = aws_s3_bucket.contents_devart.bucket_regional_domain_name
    origin_id                = "devart_origin"
    origin_access_control_id = aws_cloudfront_origin_access_control.devart_contents.id
  }

  enabled         = true
  is_ipv6_enabled = true
  comment         = "Cloudfront configuration for cdn"
  http_version    = "http2and3"

  # Alias of cloudfront distribution
  aliases = ["<Your domain name>"] # change this to your domain name

  # Default Cache behavior
  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "devart_origin"
    compress         = true

    forwarded_values {
      query_string = false

      cookies {
        forward = "all"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  # List of Custom Cache behavior
  # This behavior will be applied before default
  ordered_cache_behavior {

    path_pattern = "*.gif"

    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "devart_origin"
    compress         = false

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 3600

    forwarded_values {
      query_string            = true
      query_string_cache_keys = ["d"]

      cookies {
        forward = "all"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  # Certification Settings
  viewer_certificate {
    acm_certificate_arn      = "<Your acm arn>" # change this to your acm arn in us-east-1
    minimum_protocol_version = "TLSv1.1_2016"
    ssl_support_method       = "sni-only"
  }

  # You can set custom error response
  custom_error_response {
    error_caching_min_ttl = 5
    error_code            = 404
    response_code         = 404
    response_page_path    = "/404.html"
  }

  custom_error_response {
    error_caching_min_ttl = 5
    error_code            = 500
    response_code         = 500
    response_page_path    = "/500.html"
  }

  custom_error_response {
    error_caching_min_ttl = 5
    error_code            = 502
    response_code         = 502
    response_page_path    = "/500.html"
  }

  # Tags of cloudfront
  tags = {
    Name = "<domain name>" #Change this to domain name that you want to use
  }
}

# Route 53 Record for cloudfront
resource "aws_route53_record" "devart_cdn" {
  zone_id = "<your zone id>" #Change this to your zone id
  name    = "<domain name>" #Change this to domain name that you want to use
  type    = "A"

  alias {
    name                   = aws_cloudfront_distribution.devart_cdn_distribution.domain_name
    zone_id                = "Z2FDTNDATAQYW2" # This is fixed value!
    evaluate_target_health = false
  }
}


```

{% endcode %}

### 도메인 테스트

CloudFront 도메인이 아니라, 직접 지정한 도메인으로 변경합니다!&#x20;

<figure><img src="/files/LD3mjjrriPWf5qHC0TDc" alt=""><figcaption></figcaption></figure>

```
https://cdn.devops-art-factory.com/sample.html
```

<figure><img src="/files/Zvf5aGtpFm9xOWMpgx1c" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://terraform201.devart.tv/3.-static/cloudfront-s3-1.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
