Skip to content

Commit

Permalink
Merge pull request #610 from woowacourse-teams/feat/609-aws-infrastru…
Browse files Browse the repository at this point in the history
…cture-as-code

AWS 인프라스트럭쳐(cloudfront, s3) 정의 terraform 코드 추가
  • Loading branch information
solo5star authored Nov 28, 2023
2 parents 334b7d8 + e7a30e0 commit 82452e4
Show file tree
Hide file tree
Showing 7 changed files with 284 additions and 0 deletions.
34 changes: 34 additions & 0 deletions infrastructure/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc
25 changes: 25 additions & 0 deletions infrastructure/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions infrastructure/acm.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "aws_acm_certificate" "default" {
provider = aws.virginia
domain_name = var.domain_name
validation_method = "DNS"
key_algorithm = "EC_prime256v1"

lifecycle {
create_before_destroy = true
}
}

resource "aws_acm_certificate_validation" "default" {
provider = aws.virginia
certificate_arn = aws_acm_certificate.default.arn
}
110 changes: 110 additions & 0 deletions infrastructure/cloudfront.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
resource "aws_cloudfront_origin_access_control" "default" {
name = "${var.project_name} CloudFront OAC"
description = "${var.project_name} CloudFront S3 OAC"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}

resource "aws_cloudfront_distribution" "default" {
enabled = true
comment = var.project_name
aliases = [var.domain_name]

is_ipv6_enabled = true
default_root_object = "index.html"

http_version = "http2and3"

origin {
origin_id = "App"
domain_name = aws_s3_bucket.default.bucket_regional_domain_name
origin_path = "/app"
origin_access_control_id = aws_cloudfront_origin_access_control.default.id
}

origin {
origin_id = "Images"
domain_name = aws_s3_bucket.default.bucket_regional_domain_name
origin_access_control_id = aws_cloudfront_origin_access_control.default.id
}

origin {
origin_id = "API"
domain_name = var.api_domain_name

custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}

custom_error_response {
error_code = 403
response_code = 200
response_page_path = "/index.html"
}

custom_error_response {
error_code = 404
response_code = 200
response_page_path = "/index.html"
}

default_cache_behavior {
target_origin_id = "App"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
compress = true
cache_policy_id = data.aws_cloudfront_cache_policy.caching_optimized.id
viewer_protocol_policy = "redirect-to-https"
}

ordered_cache_behavior {
target_origin_id = "API"
path_pattern = "/api/*"
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD", "OPTIONS"]
compress = false
cache_policy_id = data.aws_cloudfront_cache_policy.caching_disabled.id
viewer_protocol_policy = "redirect-to-https"
origin_request_policy_id = data.aws_cloudfront_origin_request_policy.all_viewer_except_host_header.id
}

ordered_cache_behavior {
target_origin_id = "Images"
path_pattern = "/images/*"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
compress = true
cache_policy_id = data.aws_cloudfront_cache_policy.caching_optimized.id
viewer_protocol_policy = "redirect-to-https"
}

viewer_certificate {
cloudfront_default_certificate = true
acm_certificate_arn = aws_acm_certificate_validation.default.certificate_arn
minimum_protocol_version = "TLSv1.2_2021"
ssl_support_method = "sni-only"
}

restrictions {
geo_restriction {
restriction_type = "none"
}
}
}

data "aws_cloudfront_cache_policy" "caching_optimized" {
name = "Managed-CachingOptimized"
}

data "aws_cloudfront_cache_policy" "caching_disabled" {
name = "Managed-CachingDisabled"
}

data "aws_cloudfront_origin_request_policy" "all_viewer_except_host_header" {
name = "Managed-AllViewerExceptHostHeader"
}
31 changes: 31 additions & 0 deletions infrastructure/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "ap-northeast-2"

default_tags {
tags = {
Project = var.project_name
Environment = "Production"
}
}
}

provider "aws" {
alias = "virginia"
region = "us-east-1"

default_tags {
tags = {
Project = var.project_name
Environment = "Production"
}
}
}
50 changes: 50 additions & 0 deletions infrastructure/s3.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
resource "aws_s3_bucket" "default" {
bucket = var.bucket_name
}

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

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

resource "aws_s3_bucket_policy" "default" {
bucket = aws_s3_bucket.default.id
depends_on = [aws_s3_bucket_public_access_block.default]
policy = data.aws_iam_policy_document.default.json
}

resource "aws_s3_object" "images" {
bucket = aws_s3_bucket.default.id
key = "images/"
}

resource "aws_s3_object" "app" {
bucket = aws_s3_bucket.default.id
key = "app/"
}

data "aws_iam_policy_document" "default" {
statement {
sid = "Allow all HTTP from cloudfront"
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}
actions = [
"s3:GetObject"
]
resources = [
"${aws_s3_bucket.default.arn}/*"
]
effect = "Allow"
condition {
test = "StringEquals"
variable = "AWS:SourceArn"
values = [aws_cloudfront_distribution.default.arn]
}
}
}
19 changes: 19 additions & 0 deletions infrastructure/vars.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
variable "project_name" {
type = string
description = "The unique name of the project (IMPORTANT: this value will be used for tagging) (e.g. yozm-cafe)"
}

variable "bucket_name" {
type = string
description = "The name of the target bucket where static files will be deployed. (e.g. yozm-cafe)"
}

variable "domain_name" {
type = string
description = "The domain name that will be connected to CloudFront. (e.g. yozm.cafe)"
}

variable "api_domain_name" {
type = string
description = "The domain name that will be used for API request. (e.g. api.yozm.cafe)"
}

0 comments on commit 82452e4

Please sign in to comment.