이전에 IAM, VPC까지 했었다
IAM, VPC
이후 AWSCLI를 설정하고 여기에 Terraform을 이용하는것 까지 완료했다
AWSCLI,Terraform
이후 내용을 정리한다.
VPC 내부에 존재하는 서브넷으로 하나의 VPC에 여러개의 서브넷이 존재 가능하다.
크게 프라이빗, 퍼블릭 서브넷이 존재하며 네트워크 세분화와 리소스 배치(EC2등)를 담당한다.
// 테라폼 설정의 시작
terraform {
// 필요한 프로바이더(클라우드 서비스 제공자)를 설정
required_providers {
// AWS 프로바이더를 사용한다고 선언
aws = {
// AWS 프로바이더의 출처를 hashicorp/aws로 지정
source = "hashicorp/aws"
// AWS 프로바이더의 버전을 4.0 이상으로 지정
version = "~> 4.0"
}
}
}
// AWS를 제공자로 사용한다고 선언
provider "aws" {
// AWS에서 사용할 리전을 변수로부터 받아옴
region = var.region
}
이부분은 테라폼을 사용한다고 선언하는 부분이다
이후 VPC와 Subnet을 만든다
// AWS VPC(Virtual Private Cloud) 리소스를 생성하고 이름을 'vpc_1'로 설정
resource "aws_vpc" "vpc_1" {
// VPC의 IP 주소 범위를 설정
cidr_block = "10.0.0.0/16"
// DNS 지원을 활성화
enable_dns_support = true
// DNS 호스트 이름 지정을 활성화
enable_dns_hostnames = true
// 리소스에 대한 태그를 설정
tags = {
Name = "${var.prefix}-vpc-1"
}
}
// AWS 서브넷 리소스를 생성하고 이름을 'subnet_1'로 설정
resource "aws_subnet" "subnet_1" {
// 이 서브넷이 속할 VPC를 지정. 여기서는 'vpc_1'를 선택
vpc_id = aws_vpc.vpc_1.id
// 서브넷의 IP 주소 범위를 설정
cidr_block = "10.0.1.0/24"
// 서브넷이 위치할 가용 영역을 설정
availability_zone = "${var.region}a"
// 이 서브넷에 배포되는 인스턴스에 공용 IP를 자동으로 할당
map_public_ip_on_launch = true
// 리소스에 대한 태그를 설정
tags = {
Name = "${var.prefix}-subnet-1"
}
}
// AWS 서브넷 리소스를 생성하고 이름을 'subnet_2'로 설정
resource "aws_subnet" "subnet_2" {
// 이 서브넷이 속할 VPC를 지정. 여기서는 'vpc_1'를 선택
vpc_id = aws_vpc.vpc_1.id
// 서브넷의 IP 주소 범위를 설정
cidr_block = "10.0.2.0/24"
// 서브넷이 위치할 가용 영역을 설정
availability_zone = "${var.region}b"
// 이 서브넷에 배포되는 인스턴스에 공용 IP를 자동으로 할당
map_public_ip_on_launch = true
// 리소스에 대한 태그를 설정
tags = {
Name = "${var.prefix}-subnet-2"
}
}
위 사진을 보면 아직 외부 인터넷과 연결이 안되어있는 상태이다.
이를 연결하기 위해 게이트웨이 설정을 해줘야 한다.
// AWS 인터넷 게이트웨이 리소스를 생성하고 이름을 'igw_1'로 설정
resource "aws_internet_gateway" "igw_1" {
// 이 인터넷 게이트웨이가 연결될 VPC를 지정. 여기서는 'vpc_1'를 선택
vpc_id = aws_vpc.vpc_1.id
// 리소스에 대한 태그를 설정
tags = {
Name = "${var.prefix}-igw-1"
}
}
네트워크 연결을 위한 게이트웨이가 열렸다.
말그대로 Routing을 해주는 테이블이다. 서브넷이 현재 2개가 있는데 이에 규칙에 따라 통신을 해준다.
라우팅 테이블을 만들고(기존것 무시) 이를 게이트 웨이와 연결해 인터넷 통신을 가능하게 한다.
// AWS 라우트 테이블 리소스를 생성하고 이름을 'rt_1'로 설정
resource "aws_route_table" "rt_1" {
// 이 라우트 테이블이 속할 VPC를 지정. 여기서는 'vpc_1'를 선택
vpc_id = aws_vpc.vpc_1.id
// 라우트 규칙을 설정. 여기서는 모든 트래픽(0.0.0.0/0)을 'igw_1' 인터넷 게이트웨이로 보냄
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw_1.id
}
// 리소스에 대한 태그를 설정
tags = {
Name = "${var.prefix}-rt-1"
}
}
// 라우트 테이블 'rt_1'과 서브넷 'subnet_1'을 연결
resource "aws_route_table_association" "association_1" {
// 연결할 서브넷을 지정
subnet_id = aws_subnet.subnet_1.id
// 연결할 라우트 테이블을 지정
route_table_id = aws_route_table.rt_1.id
}
// 라우트 테이블 'rt_1'과 서브넷 'subnet_2'을 연결
resource "aws_route_table_association" "association_2" {
// 연결할 서브넷을 지정
subnet_id = aws_subnet.subnet_2.id
// 연결할 라우트 테이블을 지정
route_table_id = aws_route_table.rt_1.id
}
보안을 허용/거부 를 하는 그룹이다. 추후 EC2에 장착해서 사용하는데 이를 통해 보안을 설정 가능하다.
// AWS 보안 그룹 리소스를 생성하고 이름을 'sg_1'로 설정
resource "aws_security_group" "sg_1" {
// 보안 그룹의 이름을 설정. 이름 앞에는 변수로부터 받은 prefix를 붙임
name = "${var.prefix}-sg-1"
// 인바운드 트래픽 규칙을 설정
// 여기서는 모든 프로토콜, 모든 포트에 대해 모든 IP(0.0.0.0/0)로부터의 트래픽을 허용
ingress {
from_port = 0
to_port = 0
protocol = "all"
cidr_blocks = ["0.0.0.0/0"]
}
// 아웃바운드 트래픽 규칙을 설정
// 여기서는 모든 프로토콜, 모든 포트에 대해 모든 IP(0.0.0.0/0)로의 트래픽을 허용
egress {
from_port = 0
to_port = 0
protocol = "all"
cidr_blocks = ["0.0.0.0/0"]
}
// 이 보안 그룹이 속할 VPC를 지정. 여기서는 'vpc_1'를 선택
vpc_id = aws_vpc.vpc_1.id
// 리소스에 대한 태그를 설정
tags = {
Name = "${var.prefix}-sg-1"
}
}
인바운드 규칙은 들어올때, 아웃바운드 규칙은 나갈때이다.
실제 사용시에는 이렇게 다 열어두면 안된다.
EC2 == 컴퓨터이다
# EC2 역할에 AmazonS3FullAccess 정책을 부착
resource "aws_iam_role_policy_attachment" "s3_full_access" {
role = aws_iam_role.ec2_role_1.name
policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}
# EC2 역할에 AmazonEC2RoleforSSM 정책을 부착
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
role = aws_iam_role.ec2_role_1.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}
# IAM 인스턴스 프로파일 생성
resource "aws_iam_instance_profile" "instance_profile_1" {
name = "${var.prefix}-instance-profile-1"
role = aws_iam_role.ec2_role_1.name
}
# EC2 인스턴스 생성
resource "aws_instance" "ec2_1" {
# 사용할 AMI ID
ami = "ami-04b3f91ebd5bc4f6d"
# EC2 인스턴스 유형
instance_type = "t2.micro"
# 사용할 서브넷 ID
subnet_id = aws_subnet.subnet_1.id
# 적용할 보안 그룹 ID
vpc_security_group_ids = [aws_security_group.sg_1.id]
# 퍼블릭 IP 연결 설정
associate_public_ip_address = true
# 인스턴스에 IAM 역할 연결
iam_instance_profile = aws_iam_instance_profile.instance_profile_1.name
# 인스턴스에 태그 설정
tags = {
Name = "${var.prefix}-ec2-1"
}
}
EC2에 관계형 데이터베이스를 올린것이다. 아마존에서 구성해주는걸로 하면 좀더 최적화가 되어 편하게 사용할수 있지만 조금더 비싸다
EC2 - 직접구성해야하지만 직접 커스텀을 할 수 있고 좀더 싸다
RDS - 조금 비용이 비싸지만 자동으로 최적화가 되어있고 바로 사용 가능하다.
resource "aws_db_instance" "db_1" {
identifier = "${var.prefix}-db-1"
allocated_storage = 20
max_allocated_storage = 1000
engine = "mariadb"
engine_version = "10.6.10"
instance_class = "db.t3.micro"
publicly_accessible = true
username = "admin"
password = "lldj123414"
parameter_group_name = aws_db_parameter_group.mariadb_parameter_group_1.name
backup_retention_period = 1
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.sg_1.id]
db_subnet_group_name = aws_db_subnet_group.db_subnet_group_1.name
availability_zone = "${var.region}a"
tags = {
Name = "${var.prefix}-db-1"
}
}
resource "aws_db_instance" "db_2" {
identifier = "${var.prefix}-db-2"
engine = "mariadb"
engine_version = "10.6.10"
instance_class = "db.t3.micro"
publicly_accessible = true
parameter_group_name = aws_db_parameter_group.mariadb_parameter_group_1.name
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.sg_1.id]
availability_zone = "${var.region}c" # different zone for high availability
# replication configuration
replicate_source_db = aws_db_instance.db_1.identifier # specify the master DB instance identifier here
tags = {
Name = "${var.prefix}-db-2"
}
}
필요하다고 생각하는 부분만 나누었다.
이제 흔히 사용하는 전략으로 db_replication전략이다.
DB조회의 대부분은 조회 이다. EC2같은 컴퓨터를 여러대 늘리는건 쉽지만 DB는 무작정 늘리면 데이터 무결성이 깨진다.
따라서 Master 하나에서만 모든 쓰기 작업이 일어난다. 이런 변경 과정을 모드 로그나 스냅샷으로 남겨둔 뒤 Slave DB들이 이 로그, 스냅샷을 이용하여 데이터를 복제한다.
모든 조회 데이터는 이 Slave들에게 조회를 한다. 이를 통해 부하를 나눠서 처리가 가능하다.
그리고 장점으로 만약 Master가 장애가 나서 처리 불가능 상태가 되면 Slave중 하나를 Master로 승격시켜 장애를 극복하고 서비스를 이어나갈 수 있다.
위에서는 db_1 이 마스터이다. 그냥 만들면 된다.
아래는 username, password등 나머지 구성요소는 빼고 밑에 replicate_source_db를 설정하였다. 이를통해 replicate를 구성 가능하다.