1. Provider 지정
- provider : aws를 provider로 지정
- region : aws의 “us-east-2” 리전에서 인프라 생성
provider "aws" {
region = "us-east-2"
}
2. VPC 생성
- resource : 실제로 생성할 인프라 자원을 의미. 리소스 타입은 “aws_vpc”, terraform에서 정의하는 이름은 “vpc”로 정한다. “vpc”는 aws에서 사용되는 이름이 아니고 terraform 내부에서 참조하기 위한 이름이다.
- cidr_block : vpc가 사용하는 ip 대역
- tag : vpc의 이름, 등록 날짜, 사용자 이름 지정
# vpc 생성
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "ihwoo-tftest-vpc",
Date = "2022-10-05",
User = "ihwoo"
}
}
3. Subnet 생성
- resource : 리소스 타입은 “aws_subnet”
- vpc_id : 참조할 vpc 지정
- cidr_block : subnet이 사용하는 ip 대역
- availability_zone : 가용영역 지정
- map_public_ip_on_launch : 이 subnet에서 생성되는 인스턴스가 public ip 할당되어야 하는지 여부. public은 bastion을 올려야 하기 때문에 public ip가 할당되도록 옵션을 지정
- tag : subnet의 이름, 등록 날짜, 사용자 이름 지정
#public subnet 생성
resource "aws_subnet" "public-subnet-1" {
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-2a"
tags = {
Name = "ihwoo-tftest-public-subnet-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
resource "aws_subnet" "public-subnet-2" {
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-2b"
tags = {
Name = "ihwoo-tftest-public-subnet-2",
Date = "2022-10-07",
User = "ihwoo"
}
}
# private subent web 생성
resource "aws_subnet" "private-subnet-web-1"{
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.10.0/24"
availability_zone = "us-east-2a"
tags = {
Name = "ihwoo-tftest-private-subnet-web-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
resource "aws_subnet" "private-subnet-web-2"{
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.20.0/24"
availability_zone = "us-east-2b"
tags = {
Name = "ihwoo-tftest-private-subnet-web-2",
Date = "2022-10-07",
User = "ihwoo"
}
}
# private subnet was 생성
resource "aws_subnet" "private-subnet-was-1"{
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.30.0/24"
availability_zone = "us-east-2a"
tags = {
Name = "ihwoo-tftest-private-subnet-was-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
resource "aws_subnet" "private-subnet-was-2"{
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.40.0/24"
availability_zone = "us-east-2b"
tags = {
Name = "ihwoo-tftest-private-subnet-was-2",
Date = "2022-10-07",
User = "ihwoo"
}
}
# private subnet db 생성
resource "aws_subnet" "private-subnet-db-1"{
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.50.0/24"
availability_zone = "us-east-2a"
tags = {
Name = "ihwoo-tftest-private-subnet-db-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
resource "aws_subnet" "private-subnet-db-2"{
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.60.0/24"
availability_zone = "us-east-2b"
tags = {
Name = "ihwoo-tftest-private-subnet-db-2",
Date = "2022-10-07",
User = "ihwoo"
}
}
4. Internet gateway 생성
- resource : 리소스 타입은 “aws_internet_gateway”
- vpc_id : 참조할 vpc 지정
- tags : internet gateway의 이름, 등록 날짜, 사용자 이름 지정
# internet gateway 생성
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "ihwoo-tftest-igw",
Date = "2022-10-07",
User = "ihwoo"
}
}
5. EIP 생성
- NAT 게이트웨이를 생성하려면 EIP가 필요하다.
- resource : 리소스 타입은 “aws_eip”
- vpc : eip가 vpc에 위치하는지 여부
- tags : eip의 이름, 등록 날짜, 사용자 이름 지정
# elastic ip 생성
resource "aws_eip" "eip" {
vpc = true
lifecycle {
create_before_destroy = true
}
tags = {
Name = "ihwoo-tftest-eip",
Date = "2022-10-07",
User = "ihwoo"
}
}
6. NAT gateway 생성
- resource : 리소스 타입은 “aws_nat_gateway” 지정
- allocation_id : 위에서 생성했던 eip를 nat에 할당
- subnet_id : nat가 위치 할 subnet 지정
- tags : nat gateway의 이름, 등록 날짜, 사용자 이름 지정
# nat gateway 생성
resource "aws_nat_gateway" "natgw" {
allocation_id = aws_eip.eip.id
subnet_id = aws_subnet.public-subnet-1.id
tags = {
Name = "ihwoo-tftest-natgw",
Date = "2022-10-07",
User = "ihwoo"
}
}
7. Route table 생성
- resource : 리소스 타입은 “aws_route_table”
- vpc_id : 참조할 vpc 지정
- tags : route table의 이름, 등록 날짜, 사용자 이름 지정
# public route table 생성
resource "aws_route_table" "public-route-table" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "ihwoo-tftest-public-route-table",
Date = "2022-10-07",
User = "ihwoo"
}
}
# private route table 생성
resource "aws_route_table" "private-route-table-web" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "ihwoo-tftest-private-route-table-web",
Date = "2022-10-07",
User = "ihwoo"
}
}
resource "aws_route_table" "private-route-table-was" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "ihwoo-tftest-private-route-table-was",
Date = "2022-10-07",
User = "ihwoo"
}
}
resource "aws_route_table" "private-route-table-db" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "ihwoo-tftest-private-route-table-db",
Date = "2022-10-07",
User = "ihwoo"
}
}
8. Route 설정
- resource : 리소스 타입은 “aws_route”
- route_table_id : route table 테이블 지정
- destination_cidr_block : ip 대역 지정
- gatewat_id : 라우팅 할 igw지정
- nat_gatewat_id : 라우팅 할 nat 지정
# public route rule 설정
resource "aws_route" "public-route" {
route_table_id = aws_route_table.public-route-table.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
# private route rule 설정
resource "aws_route" "private-route-web" {
route_table_id = aws_route_table.private-route-table-web.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.natgw.id
}
resource "aws_route" "public-route-was" {
route_table_id = aws_route_table.private-route-table-was.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.natgw.id
}
resource "aws_route" "public-route-db" {
route_table_id = aws_route_table.private-route-table-db.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.natgw.id
}
9. Route table에 subnet 연결
- resource : 리소스 타입은 “aws_route_table_association”
- subnet_id : 연결할 subnet 지정
- route_table_id : 연결할 route table 지정
# public route table에 public subnet 연결
resource "aws_route_table_association" "public-route-table-association-1" {
subnet_id = aws_subnet.public-subnet-1.id
route_table_id = aws_route_table.public-route-table.id
}
resource "aws_route_table_association" "public-route-table-association-2" {
subnet_id = aws_subnet.public-subnet-2.id
route_table_id = aws_route_table.public-route-table.id
}
# private route table에 private subnet 연결
resource "aws_route_table_association" "private-route-table-association-1" {
subnet_id = aws_subnet.private-subnet-web-1.id
route_table_id = aws_route_table.private-route-table-web.id
}
resource "aws_route_table_association" "private-route-table-association-2" {
subnet_id = aws_subnet.private-subnet-web-2.id
route_table_id = aws_route_table.private-route-table-web.id
}
resource "aws_route_table_association" "private-route-table-association-3" {
subnet_id = aws_subnet.private-subnet-was-1.id
route_table_id = aws_route_table.private-route-table-was.id
}
resource "aws_route_table_association" "private-route-table-association-4" {
subnet_id = aws_subnet.private-subnet-was-2.id
route_table_id = aws_route_table.private-route-table-was.id
}
resource "aws_route_table_association" "private-route-table-association-5" {
subnet_id = aws_subnet.private-subnet-db-1.id
route_table_id = aws_route_table.private-route-table-db.id
}
resource "aws_route_table_association" "private-route-table-association-6" {
subnet_id = aws_subnet.private-subnet-db-2.id
route_table_id = aws_route_table.private-route-table-db.id
}
10. Security Group 생성
- resource : 리소스 타입은 “aws_security_group”
- vpc_id : 참조할 vpc 지정
- name : security group의 이름
- tags : security group의 이름, 등록 날짜, 사용자 이름 지정
# bastion security group 생성
resource "aws_security_group" "security-group-bastion"{
vpc_id = aws_vpc.vpc.id
name = "ihwoo-tftest-security-group-bastion"
tags = {
Name = "ihwoo-tftest-security-group-bastion",
Date = "2022-10-07",
User = "ihwoo"
}
}
# alb security group 생성
resource "aws_security_group" "security-group-alb"{
vpc_id = aws_vpc.vpc.id
name = "ihwoo-tftest-security-group-alb"
tags = {
Name = "ihwoo-tftest-security-group-alb",
Date = "2022-10-07",
User = "ihwoo"
}
}
# web security group 생성
resource "aws_security_group" "security-group-web"{
vpc_id = aws_vpc.vpc.id
name = "ihwoo-tftest-security-group-web"
tags = {
Name = "ihwoo-tftest-security-group-web",
Date = "2022-10-07",
User = "ihwoo"
}
}
# was security group 생성
resource "aws_security_group" "security-group-was"{
vpc_id = aws_vpc.vpc.id
name = "ihwoo-tftest-security-group-was"
tags = {
Name = "ihwoo-tftest-security-group-was",
Date = "2022-10-07",
User = "ihwoo"
}
}
# db security group 생성
resource "aws_security_group" "security-group-db"{
vpc_id = aws_vpc.vpc.id
name = "ihwoo-tftest-security-group-db"
tags = {
Name = "ihwoo-tftest-security-group-db",
Date = "2022-10-07",
User = "ihwoo"
}
}
11. 인바운드 및 아웃바운드 규칙 추가
Security Group에서 사용할 인바운드 및 아웃바운드 규칙들을 설정해야 한다.
- resource : 리소스 타입은 “aws_security_group_rule”
- type : ingress & egress 지정
- from_port : port
- to_port : port
- protocol : 프로토콜 타입
- cidr_blocks : ip대역
- source_security_group_id : 특정 대상만 허용할 경우 사용. cidr_block과 둘 중 하나만 사용 가능
- security_group_id : 규칙을 추가할 security group
# bastion 인바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-bastion-i" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-bastion.id
}
# bastion 아웃바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-bastion-e" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-bastion.id
}
# alb 인바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-alb-i" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-alb.id
}
# alb 아웃바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-alb-e" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-alb.id
}
# web 인바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-web-i1" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.security-group-bastion.id
security_group_id = aws_security_group.security-group-web.id
}
resource "aws_security_group_rule" "security-group-rule-web-i2" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-web.id
}
# web 아웃바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-web-e" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-web.id
}
# was 인바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-was-i1" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.security-group-bastion.id
security_group_id = aws_security_group.security-group-was.id
}
resource "aws_security_group_rule" "security-group-rule-was-i2" {
type = "ingress"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["10.0.10.0/24", "10.0.20.0/24"]
security_group_id = aws_security_group.security-group-was.id
}
# was 아웃바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-was-e" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-was.id
}
# db 인바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-db-i1" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.security-group-bastion.id
security_group_id = aws_security_group.security-group-db.id
}
resource "aws_security_group_rule" "security-group-rule-db-i2" {
type = "ingress"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-db.id
}
# db 아웃바운드 규칙 추가
resource "aws_security_group_rule" "security-group-rule-db-e" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.security-group-db.id
}
12. Key pair 생성
instance에 사용할 key pair 생성
- resource : 리소스 타입은 aws_key_pair
- key_name : key pair 이름
- public_key : 사용할 public key
#key pair 생성
resource "aws_key_pair" "private-key" {
key_name = "private-key"
public_key = file("~/key/terraform-test")
}
13. Instance 생성
- resource : 리소스 타입은 aws_instance
- ami : instance의 os 지정
- instance_type : cpu, memory를 고려한 생성할 instance의 타입
- availability_zone : 가용영역 지정
- subnet_id : instance가 위치할 subnet 지정
- key_name : instance에 접근하기 위해 필요한 key 지정
- vpc_security_group_ids : instance의 security group 지정
- associate_public_ip_address : public ip 할당 여부
# bastion 인스턴스 생성
resource "aws_instance" "instance-bastion" {
ami = "ami-0f924dc71d44d23e2"
instance_type = "t2.micro"
availability_zone = "us-east-2a"
subnet_id = aws_subnet.public-subnet-1.id
vpc_security_group_ids = [aws_security_group.security-group-bastion.id]
key_name = aws_key_pair.private-key.key_name
associate_public_ip_address = true
tags = {
Name = "ihwoo-tftest-instance-bastion",
Date = "2022-10-07",
User = "ihwoo"
}
}
# web1 인스턴스 생성
resource "aws_instance" "instance-web-1" {
ami = "ami-0f924dc71d44d23e2"
instance_type = "t2.micro"
availability_zone = "us-east-2a"
subnet_id = aws_subnet.private-subnet-web-1.id
vpc_security_group_ids = [aws_security_group.security-group-web.id]
key_name = aws_key_pair.private-key.key_name
associate_public_ip_address = false
tags = {
Name = "ihwoo-tftest-instance-web-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
# web2 인스턴스 생성
resource "aws_instance" "instance-web-2" {
ami = "ami-0f924dc71d44d23e2"
instance_type = "t2.micro"
availability_zone = "us-east-2b"
subnet_id = aws_subnet.private-subnet-web-2.id
vpc_security_group_ids = [aws_security_group.security-group-web.id]
key_name = aws_key_pair.private-key.key_name
associate_public_ip_address = false
tags = {
Name = "ihwoo-tftest-instance-web-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
# was1 인스턴스 생성
resource "aws_instance" "instance-was-1" {
ami = "ami-0f924dc71d44d23e2"
instance_type = "t2.micro"
availability_zone = "us-east-2a"
subnet_id = aws_subnet.private-subnet-was-1.id
vpc_security_group_ids = [aws_security_group.security-group-was.id]
key_name = aws_key_pair.private-key.key_name
associate_public_ip_address = false
tags = {
Name = "ihwoo-tftest-instance-was-1",
Date = "2022-10-07",
User = "ihwoo"
}
}
# was2 인스턴스 생성
resource "aws_instance" "instance-was-2" {
ami = "ami-0f924dc71d44d23e2"
instance_type = "t2.micro"
availability_zone = "us-east-2b"
subnet_id = aws_subnet.private-subnet-was-2.id
vpc_security_group_ids = [aws_security_group.security-group-was.id]
key_name = aws_key_pair.private-key.key_name
associate_public_ip_address = false
tags = {
Name = "ihwoo-tftest-instance-was-2",
Date = "2022-10-07",
User = "ihwoo"
}
}
14. ELB, Target Group, Target, Listener 생성
Load Balancer의 구성 요소는 크게 3가지가 있다. 먼저 요청을 받아들여 이 요청을 처리할 적절한 Target Group으로 전달하는 Listener, 어느 대상 그룹에 전달할지 판단하는 기준이 되는 Rule, 마지막으로 요청을 처리할 EC2가 모여있는 Target Group이 있다.
- resource : 리소스 타입은 aws_lb, aws_lb_target_group, aws_lb_target_group_attachment, aws_alb_listener
- name : elb 이름 지정
- internal : 외부와 통신하는지, 내부와 통신하는지 결정
- load_balancer_type : elb의 타입 지정
- security_groups : elg 의 sg 지정
- subnets : load balancer가 위치할 subnet. alb는 private subnet에 있는 web 서버를 load balancing 하지만, 외부와 통신하기 때문에 public subnet에 위치해야 한다. nlb는 private subnet에 있는 was 서버를 load balancing 하기 위해, 그 앞에 위치한 private subnet에 있어야 한다.
# alb 생성
resource "aws_lb" "alb" {
name = "ihwoo-tftest-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.security-group-alb.id]
subnets = [aws_subnet.public-subnet-1.id, aws_subnet.public-subnet-2.id]
tags = {
Name = "ihwoo-tftest-alb",
Date = "2022-10-07",
User = "ihwoo"
}
}
# target group 생성
resource "aws_lb_target_group" "target-group-web" {
name = "ihwoo-tftest-target-group-web"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.vpc.id
health_check {
interval = 30
path = "/"
healthy_threshold = 3
unhealthy_threshold = 3
}
}
# target group에 target 설정
resource "aws_lb_target_group_attachment" "target-group-attachment-web-1" {
target_group_arn = aws_lb_target_group.target-group-web.arn
target_id = aws_instance.instance-web-1.id
port = 80
}
resource "aws_lb_target_group_attachment" "target-group-attachment-web-2" {
target_group_arn = aws_lb_target_group.target-group-web.arn
target_id = aws_instance.instance-web-2.id
port = 80
}
# alb 리스너 설정
resource "aws_lb_listener" "web-http" {
load_balancer_arn = aws_lb.alb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target-group-web.arn
}
}
resource "aws_alb_listener" "web-https" {
load_balancer_arn = aws_lb.alb.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = "${data.aws_acm_certificate.example_dot_com.arn}"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target-group-web.arn
}
}
# nlb 생성
resource "aws_lb" "nlb" {
name = "ihwoo-tftest-nlb"
internal = true
load_balancer_type = "network"
subnets = [aws_subnet.private-subnet-web-1.id, aws_subnet.private-subnet-web-2.id]
tags = {
Name = "ihwoo-tftest-nlb",
Date = "2022-10-07",
User = "ihwoo"
}
}
# target group 생성
resource "aws_lb_target_group" "target-group-was" {
name = "ihwoo-tftest-target-group-was"
port = 8080
protocol = "TCP"
vpc_id = aws_vpc.vpc.id
health_check {
interval = 30
path = "/"
healthy_threshold = 3
unhealthy_threshold = 3
}
}
# target group에 target 설정
resource "aws_lb_target_group_attachment" "target-group-attachment-was-1" {
target_group_arn = aws_lb_target_group.target-group-was.arn
target_id = aws_instance.instance-was-1.id
port = 8080
}
resource "aws_lb_target_group_attachment" "target-group-attachment-was-2" {
target_group_arn = aws_lb_target_group.target-group-was.arn
target_id = aws_instance.instance-was-2.id
port = 8080
}
# nlb 리스너 설정
resource "aws_lb_listener" "was-http" {
load_balancer_arn = aws_lb.nlb.arn
port = "8080"
protocol = "TCP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target-group-was.arn
}
}
resource "aws_lb_listener" "was-https" {
load_balancer_arn = aws_lb.nlb.arn
port = "443"
protocol = "TCP"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = "${data.aws_acm_certificate.example_dot_com.arn}"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target-group-was.arn
}
}