* 참조 사항
- 필자는 학습을 목적으로 main.tf에 전체 인프라 구축 코드를 작성하였으며, 이에 대해 각기 설명함
- .tf 파일을 resource 별로 분할할 시, 필자와 코드가 다를 수 있음
- Terraform 기초부터 순차적으로 보길 권장 (1번 게시물의 이해가 매우 중요)
1. Architecture Create : https://isc9511.tistory.com/163
2. Bucket 생성 및 파일 업로드 : https://isc9511.tistory.com/164
3. IAM Role 생성 및 정책 Attachment : https://isc9511.tistory.com/165
* AWS Networking(이번엔 코드도 길고 Resource 종류도 많다)
1. VPC (Virtual Private Cloud) : 사용자 지정 가상 클라우드 네트워크
2. Subnet : VPC에 할당 되는 IP 주소 범위 영역
3. Internet-GateWay (IGW) : VPC와 인터넷 간 통신이 가능하게 해주는 게이트웨이
4. NAT-GateWay (NGW) : Private Subnet의 인스턴스가 VPC 외부(Public)의 서비스와 연결하는데 사용되는 NAT(네트워크 주소 변환) 게이트웨이
- 단, 외부(Public) 서비스에서 Private Subnet 영역으로 연결할 수 없도록 사용하는 등 보안을 목적으로도 사용
5. Routing Table : AWS Resource 중 트래픽 경로 지정이 필요한 경우 설정
- VPC -> IGW로 전체 트래픽이 전송되어 외부로 트래픽 전달 되도록 Routing Table 설정
- NGW <> Private Subnet간 트래픽을 주고 받을 수 있도록 설정
6. Security Group : 특정 리소스에 한정하여 In/Out 트래픽을 세부적으로 제어할 수 있도록 지원하는 설정 사항
* Code 내용
- 아래는 Three Tier Architecture 설정을 위해 2개의 AZ(가용 영역)과 Public(Web) - Private(App) - Private(DB)로 네트워크 세팅을 위해 사용된 코드
- 코드가 길지만, 순차적으로 보면 이해하는데 어렵지 않을 것
- 단, VPC 생성 시 자동으로 생성이 되는 Default Routing Table과 별도로 Routing Table을 생성하는 Case의 혼동이 있을 수 있어 별도로 정리함
########## Network Setting in AWS ##############
# Network 세팅에 해당하는 부분은 순차적으로 읽으면 구성 사항 이해 가능(Three-Tier 구조이므로 순차적으로 이해 가능)
# VPC 생성
resource "aws_vpc" "three-tier-vpc" {
cidr_block = "192.168.0.0/16"
tags = {
Name = "three-tier-vpc"
}
}
# Subnet 생성 (6EA)
resource "aws_subnet" "public-subnet-az1" {
cidr_block = "192.168.10.0/24"
vpc_id = aws_vpc.three-tier-vpc.id
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = true # 해당 서브넷 선택 인스턴스는 퍼블릭 IP 주소 할당
tags = {
Name = "public-subnet-az1"
}
}
resource "aws_subnet" "private-subnet-az1" {
cidr_block = "192.168.20.0/24"
vpc_id = aws_vpc.three-tier-vpc.id
availability_zone = "ap-northeast-2a"
tags = {
Name = "private-subnet-az1"
}
}
resource "aws_subnet" "private-db-subnet-az1" {
cidr_block = "192.168.30.0/24"
vpc_id = aws_vpc.three-tier-vpc.id
availability_zone = "ap-northeast-2a"
tags = {
Name = "private-db-subnet-az1"
}
}
resource "aws_subnet" "public-subnet-az2" {
cidr_block = "192.168.40.0/24"
vpc_id = aws_vpc.three-tier-vpc.id
availability_zone = "ap-northeast-2c"
map_public_ip_on_launch = true # 해당 서브넷 선택 인스턴스는 퍼블릭 IP 주소 할당
tags = {
Name = "public-subnet-az2"
}
}
resource "aws_subnet" "private-subnet-az2" {
cidr_block = "192.168.50.0/24"
vpc_id = aws_vpc.three-tier-vpc.id
availability_zone = "ap-northeast-2c"
tags = {
Name = "private-subnet-az2"
}
}
resource "aws_subnet" "private-db-subnet-az2" {
cidr_block = "192.168.60.0/24"
vpc_id = aws_vpc.three-tier-vpc.id
availability_zone = "ap-northeast-2c"
tags = {
Name = "private-db-subnet-az2"
}
}
# Internet Gateway(IGW) 생성
resource "aws_internet_gateway" "three-tier-igw" {
vpc_id = aws_vpc.three-tier-vpc.id
tags = {
Name = "three-tier-igw"
}
}
# NAT Gateway용 EIP 생성(2ea) - 공인 IP Release에 시간이 2~3분 가량 소요되는 점 참조
resource "aws_eip" "ngw-eip1" {
vpc = true
}
resource "aws_eip" "ngw-eip2" {
vpc = true
}
# NAT Gateway 생성(2ea)
resource "aws_nat_gateway" "ngw-az1" {
allocation_id = aws_eip.ngw-eip1.id
subnet_id = aws_subnet.public-subnet-az1.id
tags = {
Name = "ngw-public-az1"
}
}
resource "aws_nat_gateway" "ngw-az2" {
allocation_id = aws_eip.ngw-eip2.id
subnet_id = aws_subnet.public-subnet-az2.id
tags = {
Name = "ngw-public-az2"
}
}
# IGW로 전체 트래픽이 가도록 Default Routing Table CIDR 수정 및 명시적 서브넷 설정
# Default Routing table ID 획득
locals {
default_route_table_id = aws_vpc.three-tier-vpc.default_route_table_id
}
# Default Routing table의 Route 설정 추가
resource "aws_route" "default-rt-to-igw" {
route_table_id = local.default_route_table_id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.three-tier-igw.id
}
# 명시적 서브넷 설정
resource "aws_route_table_association" "public-subnet-az1" {
subnet_id = aws_subnet.public-subnet-az1.id
route_table_id = local.default_route_table_id
}
# 명시적 서브넷 설정
resource "aws_route_table_association" "public-subnet-az2" {
subnet_id = aws_subnet.public-subnet-az2.id
route_table_id = local.default_route_table_id
}
# NGW1 <> Private Subnet AZ1으로 통신 되도록 Routing Table 생성 및 설정
resource "aws_route_table" "private-rt-az1" {
vpc_id = aws_vpc.three-tier-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.ngw-az1.id
}
tags = {
Name = "private-rt-az1"
}
}
# 명시적 서브넷 설정
resource "aws_route_table_association" "private-subnet-az1" {
subnet_id = aws_subnet.private-subnet-az1.id
route_table_id = aws_route_table.private-rt-az1.id
}
# NGW2 <> Private Subnet AZ2으로 통신 되도록 Routing Table 생성 및 설정
resource "aws_route_table" "private-rt-az2" {
vpc_id = aws_vpc.three-tier-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.ngw-az2.id
}
tags = {
Name = "private-rt-az2"
}
}
# 명시적 서브넷 설정
resource "aws_route_table_association" "private-subnet-az2" {
subnet_id = aws_subnet.private-subnet-az2.id
route_table_id = aws_route_table.private-rt-az2.id
}
# Security Group 생성 (5ea)
# External ALB 보안 그룹 생성
resource "aws_security_group" "external-alb-sg" {
name = "external-alb-sg"
description = "Internet facing ALB SG"
vpc_id = aws_vpc.three-tier-vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["별도 ip 주소/32"]
}
egress { # 보안 그룹 생성 시, Outbound 허용을 직접 지정해줘야 통신 가능(관리 콘솔은 자동 생성 / 테라폼은 지정 필수)
from_port = 0
to_port = 0
protocol = "-1" # Protocol -1은 전체 프로토콜을 의미
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "external-alb-sg"
}
}
# Web Tier Instance 보안 그룹 생성
resource "aws_security_group" "web-tier-instance-sg" {
name = "web-tier-instance-sg"
description = "web instance sg"
vpc_id = aws_vpc.three-tier-vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["별도 ip 주소/32"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.external-alb-sg.id]
# 처음에 생성한 External ALB SG를 Inbound로 허용하도록 구성
}
egress { # 보안 그룹 생성 시, Outbound 허용을 직접 지정해줘야 통신 가능(관리 콘솔은 자동 생성 / 테라폼은 지정 필수)
from_port = 0
to_port = 0
protocol = "-1" # Protocol -1은 전체 프로토콜을 의미
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "web-tier-instance-sg"
}
}
# Internal ALB 보안 그룹 생성
resource "aws_security_group" "internal-alb-sg" {
name = "internal-alb-sg"
description = "Internal ALB Between Web-App"
vpc_id = aws_vpc.three-tier-vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.web-tier-instance-sg.id]
# web-tier-instance-sg에서 인바운드 되는 트래픽 허용
}
egress { # 보안 그룹 생성 시, Outbound 허용을 직접 지정해줘야 통신 가능(관리 콘솔은 자동 생성 / 테라폼은 지정 필수)
from_port = 0
to_port = 0
protocol = "-1" # Protocol -1은 전체 프로토콜을 의미
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "internal-alb-sg"
}
}
# Private Instance(App Instance) 보안 그룹 생성
resource "aws_security_group" "private-instance-sg" {
name = "private-instance-sg"
description = "App tier instance sg"
vpc_id = aws_vpc.three-tier-vpc.id
ingress {
from_port = 4000
to_port = 4000
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 4000
to_port = 4000
protocol = "tcp"
security_groups = [aws_security_group.internal-alb-sg.id]
# 내부 ALB SG와 전체 주소 허용이 된, 4000TCP 포트로 트래픽 수신 설정
# 해당 4000번 포트는 ALB LB Target Group Register Port로 설정 사항에 따라 변동 가능
}
egress { # 보안 그룹 생성 시, Outbound 허용을 직접 지정해줘야 통신 가능(관리 콘솔은 자동 생성 / 테라폼은 지정 필수)
from_port = 0
to_port = 0
protocol = "-1" # Protocol -1은 전체 프로토콜을 의미
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "private-instance-sg"
}
}
# DB 보안 그룹 생성
resource "aws_security_group" "db-sg" {
name = "db-sg"
description = "database security group"
vpc_id = aws_vpc.three-tier-vpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [aws_security_group.private-instance-sg.id]
# 처음에 생성한 External ALB SG를 Inbound로 허용하도록 구성
}
egress { # 보안 그룹 생성 시, Outbound 허용을 직접 지정해줘야 통신 가능(관리 콘솔은 자동 생성 / 테라폼은 지정 필수)
from_port = 0
to_port = 0
protocol = "-1" # Protocol -1은 전체 프로토콜을 의미
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "db-sg"
}
}
* 주의 사항
1. Default Routing Table 생성과 별도의 Routing Table 생성 코드에 차이가 존재
2. 보안 그룹 (Security Group) 생성 시, Terraform에서는 Egress (Outbound)도 반드시 별도 지정 필요
- 보통 AWS Management Console에서 생성 시, 자동으로 0.0.0.0/0 전체 허용으로 생성
- 단, Terraform Code는 이를 직접 지정해줘야함 (이런줄 모르고 통신 안되서 삽질한 이력 존재)
'AWS Cloud' 카테고리의 다른 글
[AWS - Terraform] Instance(EC2) 생성 (0) | 2023.03.29 |
---|---|
[AWS - Terraform] RDS 구축 (Cluster 및 RDS Instance) (0) | 2023.03.29 |
[AWS - Terraform] IAM Role 생성 및 정책 Attachment (0) | 2023.03.28 |
[AWS - Terraform] Bucket 생성 및 파일 업로드 (0) | 2023.03.28 |
[AWS - Terraform] Architecture create (0) | 2023.03.28 |