Skip to content

Commit

Permalink
refactor(infra): separate network tf files (#1737)
Browse files Browse the repository at this point in the history
* refactor(infra): separate network tf files

* chore: create readme

* chore: remove empty file

* chore: update readme

* chore: use subnetId directly in private network

* chore: use underscore for aws provider alias

---------

Co-authored-by: cona <[email protected]>
  • Loading branch information
k1g99 and goo314 authored Jul 15, 2024
1 parent ce855d9 commit ba651a3
Show file tree
Hide file tree
Showing 8 changed files with 367 additions and 6 deletions.
76 changes: 76 additions & 0 deletions apps/infra/production/network/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,79 @@
# Network

Project for Network

코드당 인프라의 네트워크의 설정을 담은 프로젝트로 route53, cloudfront, subnet, nat 등을 관리합니다.
public network의 경우에는 본 프로젝트에서 관리하고, private network의 경우에는 각 리소스를 사용하는 서비스(프로젝트)에서 생성 및 사용하고, 본 프로젝트에서는 route table만 관리합니다.


<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 5.52 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.52.0 |
| <a name="provider_aws.us-east-1"></a> [aws.us-east-1](#provider\_aws.us-east-1) | 5.52.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_acm_certificate.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |
| [aws_acm_certificate_validation.for_all_domains](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource |
| [aws_cloudfront_distribution.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |
| [aws_eip.for_nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
| [aws_internet_gateway.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
| [aws_nat_gateway.public_subnet1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource |
| [aws_route53_record.certificate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_route53_record.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_route53_zone.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource |
| [aws_route_table.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table_association.admin_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.admin_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.client_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.client_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.iris1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.iris2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.public_subnet1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.public_subnet2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_subnet.public_subnet1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.public_subnet2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource |
| [aws_cloudfront_cache_policy.disable](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_cache_policy) | data source |
| [aws_cloudfront_origin_request_policy.allow_all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_origin_request_policy) | data source |
| [aws_cloudfront_origin_request_policy.exclude_host_header](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_origin_request_policy) | data source |
| [aws_lb.admin_api](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/lb) | data source |
| [aws_lb.client_api](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/lb) | data source |
| [aws_subnet.private_admin_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
| [aws_subnet.private_admin_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
| [aws_subnet.private_client_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
| [aws_subnet.private_client_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
| [aws_subnet.private_iris1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
| [aws_subnet.private_iris2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_private_admin_api1_id"></a> [private\_admin\_api1\_id](#input\_private\_admin\_api1\_id) | n/a | `any` | n/a | yes |
| <a name="input_private_admin_api2_id"></a> [private\_admin\_api2\_id](#input\_private\_admin\_api2\_id) | n/a | `any` | n/a | yes |
| <a name="input_private_client_api1_id"></a> [private\_client\_api1\_id](#input\_private\_client\_api1\_id) | n/a | `any` | n/a | yes |
| <a name="input_private_client_api2_id"></a> [private\_client\_api2\_id](#input\_private\_client\_api2\_id) | n/a | `any` | n/a | yes |
| <a name="input_private_iris1_id"></a> [private\_iris1\_id](#input\_private\_iris1\_id) | n/a | `any` | n/a | yes |
| <a name="input_private_iris2_id"></a> [private\_iris2\_id](#input\_private\_iris2\_id) | n/a | `any` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
104 changes: 104 additions & 0 deletions apps/infra/production/network/cloudfront.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
data "aws_lb" "client_api" {
name = "Codedang-Client-Api-LB"
}

data "aws_lb" "admin_api" {
name = "Codedang-Admin-Api-LB"
}

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

data "aws_cloudfront_origin_request_policy" "allow_all" {
name = "Managed-AllViewer"
}

data "aws_cloudfront_origin_request_policy" "exclude_host_header" {
name = "Managed-AllViewerExceptHostHeader"
}

resource "aws_cloudfront_distribution" "codedang" {
origin {
domain_name = "amplify.codedang.com"
origin_id = "frontend" # TODO: Add unique ID of Amplify

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

origin {
domain_name = data.aws_lb.client_api.dns_name
origin_id = data.aws_lb.client_api.id

custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only" # TODO: allow HTTPS only
origin_ssl_protocols = ["TLSv1.2"]
}
}

origin {
domain_name = data.aws_lb.admin_api.dns_name
origin_id = data.aws_lb.admin_api.id

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

enabled = true
comment = "Codedang"
http_version = "http2and3"

aliases = ["codedang.com"]

default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD", "OPTIONS"]
target_origin_id = "frontend" # TODO: do not hard-code origin_id
viewer_protocol_policy = "redirect-to-https"
cache_policy_id = data.aws_cloudfront_cache_policy.disable.id
origin_request_policy_id = data.aws_cloudfront_origin_request_policy.exclude_host_header.id
}

ordered_cache_behavior {
path_pattern = "/api/*"
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD", "OPTIONS"]
target_origin_id = data.aws_lb.client_api.id
viewer_protocol_policy = "redirect-to-https"
cache_policy_id = data.aws_cloudfront_cache_policy.disable.id
origin_request_policy_id = data.aws_cloudfront_origin_request_policy.allow_all.id
}

ordered_cache_behavior {
path_pattern = "/graphql"
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD", "OPTIONS"]
target_origin_id = data.aws_lb.admin_api.id
viewer_protocol_policy = "redirect-to-https"
cache_policy_id = data.aws_cloudfront_cache_policy.disable.id
origin_request_policy_id = data.aws_cloudfront_origin_request_policy.allow_all.id
}

restrictions {
geo_restriction {
restriction_type = "none"
}
}

viewer_certificate {
acm_certificate_arn = aws_acm_certificate_validation.for_all_domains.certificate_arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
}
2 changes: 1 addition & 1 deletion apps/infra/production/network/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ terraform {
}

provider "aws" {
region = var.region
region = "ap-northeast-2"
}
42 changes: 42 additions & 0 deletions apps/infra/production/network/private_network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id

route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.public_subnet1.id
}

tags = {
Name = "Codedang-Private-RT"
}
}

resource "aws_route_table_association" "admin_api1" {
subnet_id = var.private_admin_api1_subnet_id
route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "admin_api2" {
subnet_id = var.private_admin_api2_subnet_id
route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "iris1" {
subnet_id = var.private_iris1_subnet_id
route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "iris2" {
subnet_id = var.private_iris2_subnet_id
route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "client_api1" {
subnet_id = var.private_client_api1_subnet_id
route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "client_api2" {
subnet_id = var.private_client_api2_subnet_id
route_table_id = aws_route_table.private.id
}
79 changes: 79 additions & 0 deletions apps/infra/production/network/public_network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id

tags = {
Name = "Codedang-InternetFacing"
}
}

resource "aws_eip" "for_nat" {
domain = "vpc"

lifecycle {
create_before_destroy = true
}

depends_on = [aws_internet_gateway.main]

tags = {
Name = "Codedang-NatEIP"
}
}

# TODO: public_subnet2에도 할당 필요 (-> vpc endpoint로 수정하는 방향으로 진행하기)
resource "aws_nat_gateway" "public_subnet1" {
allocation_id = aws_eip.for_nat.id
subnet_id = aws_subnet.public_subnet1.id

tags = {
Name = "Codedang-NatGateway-1"
}
}

resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}

route {
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.main.id
}

tags = {
Name = "Codedang-Public-RT"
}
}

resource "aws_subnet" "public_subnet1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.90.0/24"
availability_zone = "ap-northeast-2a"

tags = {
Name = "Codedang-Public-Nat-Subnet1"
}
}

resource "aws_subnet" "public_subnet2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.91.0/24"
availability_zone = "ap-northeast-2c"

tags = {
Name = "Codedang-Public-Nat-Subnet2"
}
}

resource "aws_route_table_association" "public_subnet1" {
subnet_id = aws_subnet.public_subnet1.id
route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "public_subnet2" {
subnet_id = aws_subnet.public_subnet2.id
route_table_id = aws_route_table.public.id
}
52 changes: 52 additions & 0 deletions apps/infra/production/network/route53.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
provider "aws" {
alias = "us_east_1"
region = "us-east-1"
}

resource "aws_route53_zone" "codedang" {
name = "codedang.com"
}

resource "aws_route53_record" "codedang" {
name = "codedang.com"
type = "A"
zone_id = aws_route53_zone.codedang.zone_id

alias {
name = aws_cloudfront_distribution.codedang.domain_name
zone_id = aws_cloudfront_distribution.codedang.hosted_zone_id
evaluate_target_health = false
}
}

resource "aws_acm_certificate" "codedang" {
domain_name = "codedang.com"
validation_method = "DNS"
provider = aws.us_east_1
}

resource "aws_route53_record" "certificate" {
for_each = {
for dvo in aws_acm_certificate.codedang.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
zone_id = aws_route53_zone.codedang.zone_id
type = dvo.resource_record_type
value = dvo.resource_record_value
}
}

allow_overwrite = true
name = each.value.name
records = [each.value.value]
ttl = 60
type = each.value.type
zone_id = each.value.zone_id
}

resource "aws_acm_certificate_validation" "for_all_domains" {
provider = aws.us_east_1
certificate_arn = aws_acm_certificate.codedang.arn
validation_record_fqdns = [
for record in aws_route53_record.certificate : record.fqdn
]
}
11 changes: 6 additions & 5 deletions apps/infra/production/network/variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
variable "region" {
type = string
description = "The region for provider"
default = "ap-northeast-2"
}
variable "private_admin_api1_subnet_id" {}
variable "private_admin_api2_subnet_id" {}
variable "private_iris1_subnet_id" {}
variable "private_iris2_subnet_id" {}
variable "private_client_api1_subnet_id" {}
variable "private_client_api2_subnet_id" {}
7 changes: 7 additions & 0 deletions apps/infra/production/network/vpc.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"

tags = {
Name = "Codedang-VPC"
}
}

0 comments on commit ba651a3

Please sign in to comment.