관련글
2021.03.11 - [IT/AWS] - [3T] AWS 3 tier Architecture 구성하기 - Windows Terraform Infra(1)
2021.03.15 - [IT/AWS] - [3T] AWS 3 tier Architecture 구성하기 - Linux Apache & Tomcat 설치 (3-1)
2021.03.16 - [IT/AWS] - [3T] AWS 3 tier Architecture 구성하기 - Linux Nginx 설치 & Tomcat 연동 (3-2)
2021.03.17 - [IT/AWS] - [3T] AWS 3 tier Architecture 구성하기 - MySQL 설치 & Replication (4)
2021.03.17 - [IT/AWS] - [3T] AWS 3 tier Architecture 구성하기 - Linux Tomcat & MySQL 연동 (5)
해당 파트에서는 2개의 Load balancer(ALB, NLB)와 Security Group, EC2를 생성한다.
Bastion -> web/was/db -> ALB/NLB 순서이다.
네이밍룰은 이전과 동일하다.
Terraform Bastion - Security Group & EC2
security group은 EC2 생성 전에 만들어주는 것이 좋다.
그러나 EC2 생성 후에도 sg를 추가할 수 있다.
sg는 적용할 인스턴스 별로 파일을 나누는 게 좀 더 보기 좋다. in/out bound가 많아지면 너무 길어서 보기 힘들기 때문
Security Group
resource "aws_security_group" "terra-sg-pub-bastion"{
name = "terra-sg-pub-bastion"
description = "terra-sg-pub-bastion"
vpc_id = aws_vpc.terra-vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terra-sg-pub-bastion"
}
}
Target | Source | Port |
terra-sg-pub-bastion | 0.0.0.0/0 | 22 |
* Target: 도착지, 생성할 SG 위치
* Source: 출발지, cidr_blocks 또는 Security Group
* Port: Source에서 들어오는 Port Number
- Bastion에 사용할 sg이다.
- ingress는 Bastion에 접속 가능한 port를 의미한다.
외부에서 public에 접근하므로 any open으로 열고, xshell을 이용한 ssh 접속이므로 22번 port를 열었다.
- egress는 Bastion에서 접속 할 그룹을 설정했다.
나가는 경우에는 큰 제한을 두지 않았다.
EC2
resource "aws_instance" "terra-ec2-pub-a-bastion"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2a"
subnet_id = aws_subnet.terra-sub-pub-a.id
key_name = "test"
vpc_security_group_ids = [
aws_security_group.terra-sg-pub-bastion.id
]
tags = {
Name = "terra-ec2-pub-a-bastion"
}
}
* ami: 인스턴스의 os 선택
* instance_type: 생성할 cpu, memory를 고려한 type 설정
* availability_zone: az 설정
* key_name: instance에 접근하기 위해 필요한 key 설정
* vpc_security_group_ids: ec2의 sg 설정
terraform plan > terraform apply
상세 설정을 보면 이와 같이 테라폼으로 설정한 ec2의 내용을 확인 할 수 있다.
Bastion은 Public 영역에서 Private 영역 접근에 필요할 때, 터널링 역할을 해주는 서버이다.
Terraform Web Was DB - Security Group & EC2
private 영역에서 a와 c존에 각각 두 대씩 instance를 만들어준다.
Security Group
3 tier에서 가장 신경써야 할 것중 하나인 Security Group이다. 3 tier 뿐만 아니라, 이러한 환경을 구성할 때는 항상 Security Group을 잘 생각해야 한다.
- Web SG
resource "aws_security_group" "terra-sg-pri-web"{
name = "terra-sg-pri-web"
description = "terra-sg-pri-web"
vpc_id = aws_vpc.terra-vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.terra-sg-pub-bastion.id]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terra-sg-pri-web"
}
}
Target | Source | Port |
terra-sg-pri-web | terra-sg-pub-bastion | 22 |
terra-sg-pri-web | 0.0.0.0/0 | 80 |
Web의 경우, 외부 http, https에서 접속하는 Front 단이다.
22번 port의 경우, Bastion을 통해서 내부로 접속하기 때문에 ingress에서 bastion만 open하면 된다.
80번 port는 Nginx 또는 Apache와 같은 웹서버가 접속하기 위한 port이다. 외부 어디에서든 접속이 가능해야하는 http를 위해 Any Open으로 열어줬다.
- Was SG
# was
resource "aws_security_group" "terra-sg-pri-was"{
name = "terra-sg-pri-was"
description = "terra-sg-pri-was"
vpc_id = aws_vpc.terra-vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.terra-sg-pub-bastion.id]
}
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["10.0.10.0/24", "10.0.20.0/24"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terra-sg-pri-was"
}
}
Target | Source | Port |
terra-sg-pri-was | terra-sg-pub-bastion | 22 |
terra-sg-pri-was | 10.0.10.0/24, 10.0.20.0/24 | 8080 |
22번 port는 마찬가지로 bastion을 위해 열어줬다.
8080의 경우 Web의 Subent 대역을 Source로 하였다. NLB는 SG가 없고, NLB의 SG까지 WEB SG에서 받아줘야 한다.
** 왜 Security Group으로는 열리지 않을까? 아직 의문이다.
- DB SG
# db
resource "aws_security_group" "terra-sg-pri-db"{
name = "terra-sg-pri-db"
description = "terra-sg-pri-db"
vpc_id = aws_vpc.terra-vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.terra-sg-pub-bastion.id]
}
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terra-sg-pri-db"
}
}
Target | Source | Port |
terra-sg-pri-db | terra-sg-pub-bastion | 22 |
terra-sg-pri-db | 0.0.0.0/0 | 3306 |
이후 있을 Master-Slave로 인해 3306 port를 any open으로 열어둔다.
Bastion에서 접속하기 위해 22번 port도 열어준다.
EC2
# web, db 이중화 구성
# a 대역에 ec2 생성
resource "aws_instance" "terra-ec2-pri-a-web1"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2a"
subnet_id = aws_subnet.terra-sub-pri-a-web.id
key_name = "test"
vpc_security_group_ids = [
aws_security_group.terra-sg-pri-web.id
]
tags = {
Name = "terra-ec2-pri-a-web1"
}
}
# c 대역에 ec2 생성
resource "aws_instance" "terra-ec2-pri-c-web2"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2c"
subnet_id = aws_subnet.terra-sub-pri-c-web.id
key_name = "test"
vpc_security_group_ids = [
aws_security_group.terra-sg-pri-web.id
]
tags = {
Name = "terra-ec2-pri-c-web2"
}
}
#db
resource "aws_instance" "terra-ec2-pri-a-db1"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2a"
subnet_id = aws_subnet.terra-sub-pri-a-db.id
key_name = "test"
vpc_security_group_ids = [
aws_security_group.terra-sg-pri-db.id
]
tags = {
Name = "terra-ec2-pri-a-db1"
}
}
resource "aws_instance" "terra-ec2-pri-c-db2"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2c"
subnet_id = aws_subnet.terra-sub-pri-c-db.id
key_name = "test"
vpc_security_group_ids = [
aws_security_group.terra-sg-pri-db.id
]
tags = {
Name = "terra-ec2-pir-c-db2"
}
}
# was 역시 이중화 구성이지만 ebs를 추가적으로 붙여준다.
# was
resource "aws_instance" "terra-ec2-pri-a-was1"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2a"
subnet_id = aws_subnet.terra-sub-pri-a-was.id
key_name = "test"
# ebs 추가적으로 구성
ebs_block_device{
device_name ="/dev/sdb"
volume_size = "8"
}
vpc_security_group_ids = [
aws_security_group.terra-sg-pri-was.id
]
tags = {
Name = "terra-ec2-pri-a-was1"
}
}
resource "aws_instance" "terra-ec2-pri-c-was2"{
ami = "ami-006e2f9fa7597680a"
instance_type = "t2.micro"
availability_zone = "ap-northeast-2c"
subnet_id = aws_subnet.terra-sub-pri-c-was.id
key_name = "test"
ebs_block_device{
device_name ="/dev/sdb"
volume_size = "8"
}
vpc_security_group_ids = [
aws_security_group.terra-sg-pri-was.id
]
tags = {
Name = "terra-ec2-pri-c-was2"
}
}
- web과 db의 경우에는 기존 bastion과 크게 다르지 않게 구성
- 여기서 추가적으로 필요한 옵션들을 넣어주면 된다.
- was는 tomcat 설치를 ebs에서 compile로 진행하기위해 ebs block을 추가적으로 붙여줬다.
Terraform Web ALB, Was NLB
web, was 이중화를 위해 LB가 필요하다.
alb란? Application Load Balancer
HTTP 및 HTTPS 트래픽 로드밸런싱 최적화 된 L7 로드밸런서
- web: 주소를 통해서 들어오므로 프론트단에 접속하기 때문에 http를 로드밸런싱하는 alb를 달아준다.
# alb 생성
resource "aws_lb" "terra-alb-web"{
name = "terra-alb-web"
internal = false # 외부
load_balancer_type = "application"
security_groups = [aws_security_group.terra-sg-alb-web.id] # alb는 sg 필요
subnets = [aws_subnet.terra-sub-pub-a.id, aws_subnet.terra-sub-pub-c.id] # public subnet에서 web 통신
tags = {
Name = "terra-alb-web"
}
}
# 타겟그룹 생성
resource "aws_lb_target_group" "terra-atg-web"{
name = "terra-atg-web"
port = "80"
protocol = "HTTP"
vpc_id = aws_vpc.terra-vpc.id
target_type = "instance"
tags = {
Name = "terra-atg-web"
}
}
# 리스너 생성
resource "aws_lb_listener" "terra-alt-web"{
load_balancer_arn = aws_lb.terra-alb-web.arn
port = "80"
protocol = "HTTP"
default_action{
type = "forward"
target_group_arn = aws_lb_target_group.terra-atg-web.arn
}
}
# 2개의 web attachement
resource "aws_lb_target_group_attachment" "terra-att-web1"{
target_group_arn = aws_lb_target_group.terra-atg-web.arn
target_id = aws_instance.terra-ec2-pri-a-web1.id
port = 80
}
resource "aws_lb_target_group_attachment" "terra-att-web2"{
target_group_arn = aws_lb_target_group.terra-atg-web.arn
target_id = aws_instance.terra-ec2-pri-c-web2.id
port = 80
}
# alb sg
resource "aws_security_group" "terra-sg-alb-web" {
name = "terra-sg-alb-web"
description = "terra-sg-alb-web"
vpc_id = aws_vpc.terra-vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terra-sg-alb-web"
}
}
- alb는 sg가 필요하다. 또한, 외부에서 접근이 가능하므로 internal은 false가 된다.
nlb란? Network Load Balancer
TCP, UDP 등 서버 구축 시 최적의 성능을 보여주는 L4 로드밸런서
- was: ip port로 web에서 was로 접근하므로 tcp 통신을 로드밸런싱하는 nlb를 달아준다.
# nlb 생성
resource "aws_lb" "terra-nlb-was"{
name = "terra-nlb-was"
internal = true # 내부 접근
load_balancer_type = "network"
subnets = [aws_subnet.terra-sub-pri-a-web.id, aws_subnet.terra-sub-pri-c-web.id] # web subnet에서 was를 바라봄
tags = {
Name = "terra-nlb-was"
}
}
# 타겟그룹
# was에서 진행 될 tomcat의 경우, 8080 port로 통신된다.
resource "aws_lb_target_group" "terra-ntg-was"{
name = "terra-ntg-was"
port = "8080"
protocol = "TCP"
vpc_id = aws_vpc.terra-vpc.id
target_type = "instance"
tags = {
Name = "terra-ntg-was"
}
}
resource "aws_lb_listener" "terra-nlt-was"{
load_balancer_arn = aws_lb.terra-nlb-was.arn
port = "8080"
protocol = "TCP"
default_action{
type = "forward"
target_group_arn = aws_lb_target_group.terra-ntg-was.arn
}
}
resource "aws_lb_target_group_attachment" "terra-ntt-was1"{
target_group_arn = aws_lb_target_group.terra-ntg-was.arn
target_id = aws_instance.terra-ec2-pri-a-was1.id
port = 8080
}
resource "aws_lb_target_group_attachment" "terra-ntt-was2"{
target_group_arn = aws_lb_target_group.terra-ntg-was.arn
target_id = aws_instance.terra-ec2-pri-c-was2.id
port = 8080
}
lb가 놓일 subnet의 위치는 크게 상관이 없지만, 타겟그룹은 중요하다.
terraform plan > terraform apply를 진행하면 서비스가 생성된다.
ec2에서 대상 그룹을 선택하게 되면 lb 대상 그룹을 생성한 것을 확인 할 수 있다.
확인하고 싶은 target group을 선택한 후, Targets를 누르면 현재 instance의 상태를 확인할 수 있다.
이렇게 unhealthy가 뜨게 되는데, 이유는 사용할 port를 지정해 주었지만 현재 아무런 것도 깔려 있지 않기 때문에 unhealthy 상태를 출력한다.
2021.02.05 - [IT/실수하지말자] - Network Load Balancer Unhealthy
해당 페이지에서 좀 더 자세하게 unhealthy의 이유를 확인할 수 있다.
이렇게 모든 aws 서비스 생성을 테라폼을 통해 올렸다.
이후 3 tier 내부 구성은 (3)에서 이어진다.
'IT > AWS' 카테고리의 다른 글
[Terraform] Destroy (0) | 2021.03.16 |
---|---|
[3T] AWS 3 tier Architecture 구성하기 - Linux Apache & Tomcat 설치 (3-1) (0) | 2021.03.15 |
[3T] AWS 3 tier Architecture 구성하기 - Windows Terraform Infra (1) (0) | 2021.03.11 |
AWS Directory Service 생성 및 Windows FSx 연결 (0) | 2021.03.09 |
Serverless with AWS Lambda (3) - 삽질 (0) | 2021.03.09 |