지난 게시글에서, 빠르게 결과물을 보려고 main.tf 파일에 다 때려넣었는데
각 리소스의 역할에 맞게 파일을 구분해 유지/보수에 유리하게 구조를 변경하자.
이전 글까지 따라했다면 아래의 상태일텐데,
/project_root
│
├── terraform
│ ├── main.tf
│ ├── .terraform.lock.hcl
│ ├── terraform.tfstate
│ ├── terraform.tfstate.backup
│ ├── .terraform
│ │ ├── ...
오늘의 목표는 이렇게 바꾸는 것이다.
/project_root
│
├── terraform
│ ├── main.tf // 컨트롤 타워
│ ├── variable.tf // 민감한 정보 저장
│ ├── provider.tf // region 등 배포에 필요한 제공자 저장
│ ├── common // util resource
│ │ ├── network
│ │ │ ├── network.tf // network resource
│ │ ├── security
│ │ │ ├── security.tf // security resource
│ ├── rds
│ │ ├── rds.tf // rds resource
│ ├── .terraform.lock.hcl
│ ├── .terraform
│ │ ├── ...
AWS에서 구분한 기능에 맞게 파일을 전부 나누고, 연결시켜 줄 것이다.
in terraform/variables.tf,
# Basic Info
variable "region" {
description = "The AWS region"
default = {your_region}
}
# RDS
variable "db_instance_name" {
description = "The name of the RDS instance"
type = string
default = {your_instance_name}
}
variable "db_username" {
description = "Master username for the RDS cluster"
type = string
default = {your_username}
}
variable "db_password" {
description = "Master password for the RDS cluster"
type = string
sensitive = true
default = {your_password}
}
variable "db_name" {
description = "The name of database"
type = string
default = {your_db_name}
}
in terraform/provider.tf
provider "aws" {
region = var.region
}
in terraform/main.tf,
# # Provider
# provider "aws" {
# region = {your_region}
# }
# Provider 정의 제거
...
# DB Instance
resource "aws_db_instance" "db_instance" {
identifier = var.db_instance_name # varialbe.tf에서 불러오도록 변경
...
username = var.db_username
password = var.db_password
db_name = var.db_name
...
}
network 관련 리소스: VPC, Subnet, Internet Gateway, Route Table, Route Table Association, Subnet Group
in terraform/common/network/network.tf,
# DB Network
data "aws_availability_zones" "available" {}
resource "aws_vpc" "db_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "db-vpc"
}
}
resource "aws_subnet" "db_subnet" {
count = 2
vpc_id = aws_vpc.db_vpc.id
cidr_block = element(["10.0.1.0/24", "10.0.2.0/24"], count.index)
availability_zone = element(data.aws_availability_zones.available.names, count.index)
tags = {
Name = "db-subnet-${count.index}"
}
}
resource "aws_internet_gateway" "db_igw" {
vpc_id = aws_vpc.db_vpc.id
tags = {
Name = "db-igw"
}
}
resource "aws_route_table" "db_route_table" {
vpc_id = aws_vpc.db_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.db_igw.id
}
tags = {
Name = "db-route-table"
}
}
resource "aws_route_table_association" "db_route_table_assoc" {
count = 2
subnet_id = element(aws_subnet.db_subnet[*].id, count.index)
route_table_id = aws_route_table.db_route_table.id
}
resource "aws_db_subnet_group" "db_subnet_group" {
name = "db-subnet-group"
subnet_ids = aws_subnet.db_subnet[*].id
tags = {
Name = "db-subnet-group"
}
}
in terraform/common/network/network.tf,
...
output "db_vpc_id" {
value = aws_vpc.db_vpc.id
}
output "db_subnet_group_name" {
value = aws_db_subnet_group.db_subnet_group.name
}
in terraform/main.tf,
# DB Network
module "network" { # 기존 코드를 교체
source = "./common/network"
}
# DB Security
resource "aws_security_group" "db_sg" {
...
vpc_id = module.network.db_vpc_id # 교체
...
}
# DB Instance
resource "aws_db_instance" "db_instance" {
...
db_subnet_group_name = module.network.db_subnet_group_name # 교체
...
}
이번엔 network 때와 다르게 main.tf에 정의할 module에 db_vpc_id 라는 input이 있다.
기존 main.tf의 코드를 옮기고, rds resource에서 사용할 security group id 를 output으로 내놓는 것까진 동일하다.
in terraform/common/security/security.tf,
# DB Security
resource "aws_security_group" "db_sg" {
description = "Allow DB instance access"
vpc_id = module.network.db_vpc_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 = "db-sg"
}
}
output "db_sg_id" {
value = aws_security_group.db_sg.id
}
이제 network module의 output을 security module의 input으로 받아들일 수 있는 구조로 변경하자.
terraform/common/security 디렉토리에 variables.tf 파일을 만들자.
in terraform/common/security/variables.tf,
variable "db_vpc_id" {
description = "The ID of the VPC for DB"
type = string
}
그리고 security.tf 의 module.network.db_vpc_id 부분을 변경하자.
in terraform/common/security/security.tf,
# DB Security
resource "aws_security_group" "db_sg" {
...
vpc_id = var.db_vpc_id
...
}
security 디렉토리의 variables.tf에 "db_vpc_id"가 정의되었으므로,
해당 디렉토리를 기준으로 생성되는 모듈에서는 "db_vpc_id" 값을 반드시 필요로 한다.
마지막으로 main.tf 의 security 부분을 교체한다.
in terraform/main.tf
...
# DB Security
module "security" {
source = "./common/security"
db_vpc_id = module.network.db_vpc_id # Resource Input
}
# DB Instance
resource "aws_db_instance" "db_instance" {
...
vpc_security_group_ids = [module.security.db_sg_id]
...
}
이제 감을 잡았을 것이다. 해야할 것은 크게 4가지
한 번에 가보자.
in terraform/rds/rds.tf
# DB Instance
resource "aws_db_instance" "db_instance" {
identifier = var.db_instance_name
instance_class = "db.t3.micro"
engine = "mysql"
engine_version = "8.0.34"
username = var.db_username
password = var.db_password
db_name = var.db_name
allocated_storage = 20
db_subnet_group_name = var.db_subnet_group_name
vpc_security_group_ids = [var.db_sg_id]
skip_final_snapshot = true
publicly_accessible = true
}
in terraform/rds/variables/tf
variable "db_sg_id" {
description = "Security group id for db instance"
type = string
}
variable "db_instance_name" {
description = "The name of the RDS instance"
type = string
}
variable "db_username" {
description = "Root user name"
type = string
}
variable "db_password" {
description = "Root user password"
type = string
}
variable "db_name" {
description = "The name of database"
type = string
}
variable "db_subnet_group_name" {
description = "Subnet group name for db"
type = string
}
in terraform/main.tf
...
# DB instance
module "rds" {
source = "./rds"
db_sg_id = module.security.db_sg_id
db_instance_name = var.db_instance_name
db_username = var.db_username
db_password = var.db_password
db_name = var.db_name
db_subnet_group_name = module.network.db_subnet_group_name
}
terraform init
terraform validate
terraform apply
지난 게시글에서와 동일하게 10개의 리소스를 배포한다고 한다. 구조만 변경한 것이니 당연하다.
디렉토리는 아래처럼 바뀌었다.
/project_root
│
├── terraform
│ ├── main.tf
│ ├── variable.tf
│ ├── provider.tf
│ ├── common
│ │ ├── network
│ │ │ ├── network.tf
│ │ ├── security
│ │ │ ├── security.tf
│ │ │ ├── variables.tf
│ ├── rds
│ │ ├── rds.tf
│ │ ├── variables.tf
│ ├── .terraform.lock.hcl
│ ├── .terraform
│ │ ├── ...
앞으로 새로운 유형의 리소스를 추가할 때도 디렉토리를 추가해 조각 조각 관리하자.
역할이 구분되어있어 맥락을 파악하기 쉽다.
마지막으로 .gitignore에 일부 파일을 등록하자.
in /.gitignore
...
# Ignore infra
terraform/.terraform/*
terraform/variables.tf
terraform/*.tfstate
terraform/*.tfstate.*
terraform/*.hcl
terraform/variables.tf.bak
끝! 다음 게시글에서는 ecr, ecs 리소스를 추가하는 과정을 다루겠다.
[Spring Boot] VSCode에서 Newer patch version of Spring Boot available: 경고 제거 (0) | 2024.07.20 |
---|---|
[Spring Boot] 초기 프로젝트 403 error request 처리 실패 해결 (0) | 2024.07.20 |
[Terraform] AWS RDS - Terraform 가이드 (3) (1) | 2024.07.16 |
[Terraform] Terraform 환경 설정 - Terraform 가이드 (1) (0) | 2024.07.15 |
[Docker] Docker 자주 쓰는 명령어 정리 (0) | 2024.07.14 |