Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- jenkins
- go
- dockerfile
- 파이썬
- Azure
- GIT
- 클라우드
- 사용자 계정 관리
- 함수
- it기사
- nexus
- aws사용자모임
- 리눅스
- 명령어
- 표준 라이브러리
- AI챗봇
- 프로세스 관리
- 3티어 아키텍처
- maven
- AWS
- AI
- terraform
- docker
- open ai
- python
- git hub
- Linux
- 애저
- 변수
- awskrug
Archives
- Today
- Total
We are Architect
4. AWS: 테라폼으로 구축하는 3티어 아키텍처 구현(3) 본문
* 퍼블릭 서브넷 구간 구성: alb(외부)
- 클라이언트의 진입 역할 및 프록시 역할을 한다. 그래서 트래픽 부하분산 및 ip노출을 방지할 수 있다.
- 요청을 URL 경로 기반 라우팅 할수있다는 것이 ALB 사용의 큰 이유이다.
- 다른 가용영역으로 자동분산하여 가용성이 좋다.
# Public-ALB 리스너
resource "aws_lb_listener" "Public-ALB-listner" {
load_balancer_arn = aws_lb.Public-ALB.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.Web-Srv-tg.arn
}
}
# Public-ALB
resource "aws_lb" "Public-ALB" {
name = "Public-ALB"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb-sg.id]
subnets = [ aws_subnet.Public-SN1.id, aws_subnet.Public-SN2.id ]
tags = {
Name = "Public-ALB"
}
}
# Public-ALB 타겟그룹
resource "aws_lb_target_group" "Web-Srv-tg" {
name = "Web-Srv-tg"
port = 80
protocol = "HTTP"
target_type = "instance"
vpc_id = aws_vpc.vpc.id
health_check {
path = "/index.html" # 해당 파일경로로 통신이 되는지 확인.
interval = 30 # 30초 마다 확인.
timeout = 5 # 5초이내 응답.
healthy_threshold = 2 # 2번 연속 응답시 건강 확인.
unhealthy_threshold = 2 # 2번 연속 불응답시 불건강 확인.
}
}
# Public-ALB + 타겟그룹1
resource "aws_lb_target_group_attachment" "web-server-1-attachment" {
target_group_arn = aws_lb_target_group.Web-Srv-tg.arn
target_id = aws_instance.Web-Srv-1.id
port = 80
}
# Public-ALB + 타겟그룹2
resource "aws_lb_target_group_attachment" "web-server-2-attachment" {
target_group_arn = aws_lb_target_group.Web-Srv-tg.arn
target_id = aws_instance.Web-Srv-2.id
port = 80
}
* 프레젠테이션 계층 구성: 웹 서버, NLB(내부)
- 프레젠테이션 계층은 GUI, 인터페이스를 사용자에게 제공하는 계층으로 Web서버를 통해서 사용자와 교류를 한다.
- 외부에서 ALB 도메인으로 요청을 보내면 ALB의 경로설정 값에 따라 Web서버로 보내게 된다.(현재는 경로설정 X)
# 웹 서버1 인스턴스 구성
resource "aws_instance" "Web-Srv-1" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
key_name = "AWS 키값"
subnet_id = aws_subnet.Private-SN1.id
security_groups = [
aws_security_group.Web-srv-sg.id
]
user_data = <<-EOF
#!/bin/bash
(
echo "qwe123"
echo "qwe123"
) | passwd --stdin root
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "Web Server 1 is Ready" > /var/www/html/index.html
EOF
tags = {
Name = "Web-Srv-1"
}
}
# 웹 서버2 인스턴스 구성
resource "aws_instance" "Web-Srv-2" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
key_name = "AWS 키값"
subnet_id = aws_subnet.Private-SN2.id
security_groups = [
aws_security_group.Web-srv-sg.id
]
user_data = <<-EOF
#!/bin/bash
(
echo "qwe123"
echo "qwe123"
) | passwd --stdin root
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "Web Server 2 is Ready" > /var/www/html/index.html
EOF
tags = {
Name = "Web-Srv-2"
}
}
- NLB를 통해서 Web서버에서 WAS서버로 요청
# Private-NLB 리스너
resource "aws_lb_listener" "Private-NLB-listner" {
load_balancer_arn = aws_lb.Private-NLB.arn
port = "8080"
protocol = "TCP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.WAS-Srv-tg.arn
}
}
# Private-NLB
resource "aws_lb" "Private-NLB" {
name = "Private-NLB"
internal = true
load_balancer_type = "network"
security_groups = [aws_security_group.Private-nlb-sg.id]
subnets = [ aws_subnet.Private-SN3.id, aws_subnet.Private-SN4.id ]
tags = {
Name = "Private-NLB"
}
}
# Private-NLB 타겟그룹
resource "aws_lb_target_group" "WAS-Srv-tg" {
name = "WAS-Srv-tg"
port = 8080
protocol = "TCP"
target_type = "instance"
vpc_id = aws_vpc.vpc.id
health_check {
protocol = "HTTP"
healthy_threshold = 3
unhealthy_threshold = 3
timeout = 5
interval = 10
}
tags = {
Name = "WAS-Srv-tg"
}
}
# Private-NLB + 타겟그룹1
resource "aws_lb_target_group_attachment" "WAS-server-1-attachment" {
target_group_arn = aws_lb_target_group.WAS-Srv-tg.arn
target_id = aws_instance.WAS-Srv-1.id
port = 8080
}
# Private-NLB + 타겟그룹2
resource "aws_lb_target_group_attachment" "WAS-server-2-attachment" {
target_group_arn = aws_lb_target_group.WAS-Srv-tg.arn
target_id = aws_instance.WAS-Srv-2.id
port = 8080
}
* 애플리케이션 계층 구성: WAS 서버
- 프레젠테이션 계층과 데이터 계층으로부터 요청을 주고받는 계층.
- NLB를 통해서 온 요청이 WAS서버로 전달 되게 되고 해당 WAS서버에서는 원래는 받은 요청에 따른 데이터 값을 DB 서버에게 넘겨주고 받는 역할을 해야 한다.
- NLB의 도메인 및 포트로 요청 보내서 WAS서버는 요청을 받는다.
# WAS 서버1 인스턴스 구성
resource "aws_instance" "WAS-Srv-1" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
key_name = "AWS 키값"
subnet_id = aws_subnet.Private-SN3.id
security_groups = [
aws_security_group.WAS-srv-sg.id
]
user_data = <<-EOF
#!/bin/bash
(
echo "qwe123"
echo "qwe123"
) | passwd --stdin root
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "This is the WAS server" > /var/www/html/index.html
# 80번리스너 줄 위에 8080번리스너 추가.
sed -i '/^Listen 80$/i Listen 8080' /etc/httpd/conf/httpd.conf
systemctl restart httpd
EOF
tags = {
Name = "WAS-Srv-1"
}
}
# WAS 서버2 인스턴스 구성
resource "aws_instance" "WAS-Srv-2" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
key_name = "AWS 키값"
subnet_id = aws_subnet.Private-SN4.id
security_groups = [
aws_security_group.WAS-srv-sg.id
]
user_data = <<-EOF
#!/bin/bash
(
echo "qwe123"
echo "qwe123"
) | passwd --stdin root
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "This is the WAS server" > /var/www/html/index.html
# 80번리스너 줄 위에 8080번리스너 추가.
sed -i '/^Listen 80$/i Listen 8080' /etc/httpd/conf/httpd.conf
systemctl restart httpd
EOF
tags = {
Name = "WAS-Srv-2"
}
}
* 데이터 계층 구성: db서버
- 데이터베이스를 관리하는 계층으로 실제 데이터를 저장하고 검색하는 역할로써 DB정보를 제공해 준다.
- 현재 DB서버에는 MYSQL 8.0 버전이 설치되어 있고 WAS서버에서 DB서버로 통신 요청이 가능한지 테스트하였다.
- 특히 WAS서버에서 DB서버끼리 통신 시에는 데이터베이스용 포트만 보안그룹에서 허용해서 통신하는 것이 좋다.
# DB 서버1 인스턴스 구축
resource "aws_instance" "DB-Srv-1" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
key_name = "AWS 키값"
subnet_id = aws_subnet.Private-SN5.id
security_groups = [
aws_security_group.DB-srv-sg.id
]
user_data = <<-EOF
#!/bin/bash
# Update and install MySQL 8.0
yum update -y
yum install -y https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
# (!)인증키없이 설치 - 보안상 매우 위험!!!
yum install -y mysql-server --nogpgcheck
# Start MySQL service
systemctl start mysqld
systemctl enable mysqld
# Retrieve temporary MySQL password
TEMP_PASSWORD=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
echo "Temporary MySQL password: $TEMP_PASSWORD" >> /var/log/mysql_setup.log
# MySQL initial setup
mysql --connect-expired-password -uroot -p"$TEMP_PASSWORD" <<MYSQL_SCRIPT
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Qwer123!';
CREATE USER 'admin'@'%' IDENTIFIED BY 'Qwer123!';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%';
FLUSH PRIVILEGES;
MYSQL_SCRIPT
echo "MySQL installation and configuration complete" >> /var/log/mysql_setup.log
EOF
tags = {
Name = "DB-Srv-1"
}
}
# DB 서버2 인스턴스 구축
resource "aws_instance" "DB-Srv-2" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
key_name = "AWS 키값"
subnet_id = aws_subnet.Private-SN6.id
security_groups = [
aws_security_group.DB-srv-sg.id
]
user_data = <<-EOF
#!/bin/bash
(
echo "qwe123"
echo "qwe123"
) | passwd --stdin root
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
yum update -y
# MySQL 8.0 설치
amazon-linux-extras enable mysql8.0
yum install -y mysql-server
systemctl start mysqld
systemctl enable mysqld
# MySQL 초기 설정
TEMP_PASSWORD=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
echo "Temporary MySQL password: $TEMP_PASSWORD" >> /var/log/mysql_setup.log
# 보안 설정: 비밀번호 설정 및 사용자 추가
mysql --connect-expired-password -uroot -p"$TEMP_PASSWORD" <<MYSQL_SCRIPT
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password123!';
CREATE USER 'admin'@'%' IDENTIFIED BY 'password123!';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%';
FLUSH PRIVILEGES;
MYSQL_SCRIPT
EOF
tags = {
Name = "DB-Srv-2"
}
}
* bastion 호스트 서버 구성(의존성 및 보안 때문에 마지막에 구성)
- 유일하게 외부에서 내부 서버들로 접속하여서 서버를 관리하기 위한 서버.
- SSH접속만 허가하였으며 AWS의 키페어 없이는 절대 다른 서버들과 통신을 할 수가 없다.
- 되도록이면 보안그룹의 고정 IP를 정하여 보안을 강화해야 한다.
# Bastion Host EC2 인스턴스
resource "aws_instance" "bastion" {
ami = "ami-0de20b1c8590e09c5"
instance_type = "t2.micro"
subnet_id = aws_subnet.Public-SN1.id
key_name = "AWS 키값"
associate_public_ip_address = true # 퍼블릭 IP 할당
security_groups = [aws_security_group.bastion-srv-sg.id]
user_data = <<-EOF
#!/bin/bash
yum update -y
echo "Bastion Host is ready." > /var/www/html/index.html
EOF
tags = {
Name = "Bastion Host"
}
}
* 유의 해야할 사항
- 사실 각 서버의 들어가서 실적인 기능 구현을 해야 하며 더욱 보완해야 할 사항 등이 매우 많다.
- 뿐만 아니라 테라폼 main.tf 파일에서 모든 작업이 이루어져서 모듈화까지 진행해야한다.
- 그러나 이번 글에서는 아주 큰 틀만 살펴보기 위한 간단한 실습이었으며 차후에는 보완 및 수정할 것이다.
'Cloud > AWS' 카테고리의 다른 글
6. AWS: 서버리스 아키텍처 란? (0) | 2024.12.03 |
---|---|
5. AWS Lambda (0) | 2024.12.03 |
3. AWS: 테라폼으로 구축하는 3티어 아키텍처 구현(2) (0) | 2024.11.19 |
2. AWS: 테라폼으로 구축하는 3티어 아키텍처 구현(1) (0) | 2024.11.16 |
1. AWS: 3티어 아키텍처 란? (0) | 2024.11.16 |