Private DB Subnet을 구축하고 SG의 인바운드 규칙을 통해 private app 통신 허용
하나의 AZ에 Primary DB가 존재하고 다른 AZ에 Read replica가 존재하는 형태
############ DB Subnet GRP ##############
resource "aws_db_subnet_group" "goorm_private_db_subnet_grp" {
name = "goorm_private_db_subnet_grp"
subnet_ids = [
aws_subnet.goorm_private_db_subnet_a.id,
aws_subnet.goorm_private_db_subnet_c.id
]
}
# Private DB Subnet resources
resource "aws_subnet" "goorm_private_db_subnet_a" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.40.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "goorm_private_db_subnet_a"
}
}
resource "aws_subnet" "goorm_private_db_subnet_c" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.50.0/24"
availability_zone = "ap-northeast-2c"
tags = {
Name = "goorm_private_db_subnet_c"
}
}
위와 같이 별도의 DB를 위한 서브넷을 구축하고 이를 Subnet GRP으로 묶어준다
############ Database SG ##############
resource "aws_security_group" "goorm-private-db-sg" {
name = "goorm-private-db-sg"
description = "database security group"
vpc_id = aws_vpc.goorm_vpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [aws_security_group.app_server_sg.id]
}
# Can communicate only when manually set egress (outbound)
egress {
from_port = 0
to_port = 0
# -1 means all protocol
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "goorm-private-db-sg"
}
}
private app 으로부터의 요청만 허용하는 RDS 클러스터를 위한 SG를 생성한다.
############# RDS Cluster ###############
resource "aws_rds_cluster" "goorm-aurora-mysql-db" {
cluster_identifier = "goorm-database"
engine_mode = "provisioned"
db_subnet_group_name = aws_db_subnet_group.goorm_private_db_subnet_grp.name
vpc_security_group_ids = [aws_security_group.goorm-private-db-sg.id]
engine = "aurora-mysql"
engine_version = "5.7.mysql_aurora.2.11.1"
availability_zones = [
"ap-northeast-2a",
"ap-northeast-2c"
]
database_name = "goormPrivatedb"
master_username = "root"
master_password = "root1234"
# skip_final_snapshot = false is cannot controlled by terraform destroy
skip_final_snapshot = true
}
# rds instance writer instance endpoint output for mysql, 3-tier architecture config
output "rds_writer_endpoint" {
value = aws_rds_cluster.goorm-aurora-mysql-db.endpoint
}
이전에 생성한 private db subnet grp을 RDS 클러스터에 지정하고 SG 또한 지정해준다. database_name
는 특수문자가 들어갈 수 없으며 master_password
같은 경우에도 8자 이상이 되어야만 RDS가 정상적으로 생성된다.
############# RDS Instance ##############
resource "aws_rds_cluster_instance" "aurora-mysql-db-instance" {
# 2 instances (reader, writer)
count = 2
identifier = "goorm-database-${count.index}"
cluster_identifier = aws_rds_cluster.goorm-aurora-mysql-db.id
instance_class = "db.r5.large"
engine = aws_rds_cluster.goorm-aurora-mysql-db.engine
engine_version = aws_rds_cluster.goorm-aurora-mysql-db.engine_version
}
이후 해당 cluster에 대한 인스턴스 생성을 위한 리소스를 생성한다.
이때 ${count.index}
로 1씩 더하며 db instance 식별자 이름을 생성한다.
[ec2-user@ip-172-16-0-164 ~]$ curl goorm-app-alb-1526695078.ap-northeast-2.elb.amazonaws.com
<h1>Hello, World! You are now in private app<h1/>
[ec2-user@ip-172-16-0-164 ~]$ curl --connect-timeout 5 3.38.92.91
curl: (28) Failed to connect to 3.38.92.91 port 80 after 5000 ms: Timeout was reached
sudo dnf install mariadb105
AWS ami 배포판에는 mariaDB 클라이언트가 지원되므로 해당 CLI를 설치하고
reader endpoint를 이용해 APP EC2 인스턴스에서 접근하면
[root@ip-172-16-0-251 ec2-user]$ sudo mysql -h goorm-database.cluster-ro-cakam30tcvwy.ap-northeast-2.rds.amazonaws.com -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 175
Server version: 5.7.12 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| goormPrivatedb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.001 sec)
MySQL [(none)]>
위와 같이 정상적으로 DB에 접근되는 것을 볼 수 있다.
따라서 3-Tier 아키텍처가 IaC를 통해 정상적으로 구현되었음을 검증하였다.