위 아키텍처를 terraform을 이용해 작성해볼 것이다. 순서는 다음과 같다.
IaC 코드를 작성하는 순서
- AWS Management Console을 이용해 최종 인프라 상태를 만든다
- 잘 작동하는지 확인한다.
- 리소스를 하나씩 terraform 코드로 옮긴다.
VPC 생성
아키텍처를 본다. 한 VPC 안에 두 개의 가용영역이 존재한다. 각 가용영역에는 하나의 퍼블릭 서브넷과 하나의 프라이빗 서브넷이 있다. 그 중 퍼블릭 서브넷에 EC2 인스턴스가 존재하고 프라이빗 서브넷에 RDS가 존재한다. Loadbalancer와 auto scaling group은 나중에 처리한다.
콘솔을 활용해 다음과 같이 VPC를 구성한다. 클릭 몇 번이면 되므로 편하다. 손쉽게 구성했지만, 되게 많은 것들이 생성되었고, 서로 연결되었다. 생성된 것을 참고하여 테라폼으로 옮겨보자.
//provider.tf 파일
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "ap-northeast-2"
}
위와 같이 porvider를 aws로 사용한다.
# VPC 생성
resource "aws_vpc" "terraform-vpc" {
tags = {
Name = "테라폼 VPC"
}
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
}
# Public 서브넷 생성
resource "aws_subnet" "public1" {
availability_zone = "ap-northeast-2a"
vpc_id = aws_vpc.terraform-vpc.id
cidr_block = "10.0.0.0/20"
tags = {
"Name" = "public subnet1"
}
}
resource "aws_subnet" "public2" {
availability_zone = "ap-northeast-2b"
vpc_id = aws_vpc.terraform-vpc.id
cidr_block = "10.0.16.0/20"
tags = {
"Name" = "public subnet2"
}
}
#Private 서브넷 생성
resource "aws_subnet" "private1" {
availability_zone = "ap-northeast-2a"
vpc_id = aws_vpc.terraform-vpc.id
cidr_block = "10.0.128.0/20"
tags = {
"Name" = "private subnet1"
}
}
resource "aws_subnet" "private2" {
availability_zone = "ap-northeast-2b"
vpc_id = aws_vpc.terraform-vpc.id
cidr_block = "10.0.144.0/20"
map_public_ip_on_launch = false
tags = {
"Name" = "private subnet2"
}
}
#인터넷 게이트웨이 생성
resource "aws_internet_gateway" "terraform-igw" {
vpc_id = aws_vpc.terraform-vpc.id
tags = {
Name = "terraform-igw"
}
}
#eip 생성
resource "aws_eip" "terraform-eip" {
vpc = true
}
#NAT 게이트웨이 생성
resource "aws_nat_gateway" "nat" {
allocation_id = aws_eip.terraform-eip.id
subnet_id = aws_subnet.public2.id #NAT가 사용될 서브넷 지정, 여기서는 db 서브넷 그룹? ㄴㄴ 퍼블릭 b
connectivity_type = "public"
tags = {
Name = "terraform Nat gw"
}
depends_on = [aws_internet_gateway.terraform-igw]
}
#Public route table 생성
resource "aws_route_table" "public-routing-table-terraform" {
vpc_id = aws_vpc.terraform-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.terraform-igw.id
}
tags = {
"Name" = "public-routing-table"
}
}
#Private route table 생성
resource "aws_route_table" "private1-routing-table-terraform" {
vpc_id = aws_vpc.terraform-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.nat.id
}
tags = {
"Name" = "private1-routing-table"
}
}
resource "aws_route_table" "private2-routing-table-terraform" {
vpc_id = aws_vpc.terraform-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.nat.id
}
tags = {
"Name" = "private2-routing-table"
}
}
#Public Route table 연결
resource "aws_route_table_association" "public1-association" {
subnet_id = aws_subnet.public1.id
route_table_id = aws_route_table.public-routing-table-terraform.id
}
resource "aws_route_table_association" "public2-association" {
subnet_id = aws_subnet.public2.id
route_table_id = aws_route_table.public-routing-table-terraform.id
}
##Private Route table 연결
resource "aws_route_table_association" "private1-association" {
subnet_id = aws_subnet.private1.id
route_table_id = aws_route_table.private1-routing-table-terraform.id
}
resource "aws_route_table_association" "private2-association" {
subnet_id = aws_subnet.private2.id
route_table_id = aws_route_table.private2-routing-table-terraform.id
}
위와 같이 네트워크 인프라를 구성한다. 테라폼 문법은 어렵지 않다. terraform registry에 모두 나와있다.
기본적인 보안그룹 설정과 ec2, rds도 생성한다.
#ec2 security group 생성
resource "aws_security_group" "public" {
name = "public"
description = "Allow Web, SSH inbound traffic"
vpc_id = aws_vpc.terraform-vpc.id
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP"
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"]
ipv6_cidr_blocks = ["::/0"]
}
}
#DB security group생성
resource "aws_security_group" "private"{
name = "private"
description = "Allow DB inbound traffic"
vpc_id = aws_vpc.terraform-vpc.id
ingress {
description = "mysql_aurora"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1" # any protocol
cidr_blocks = ["0.0.0.0/0"]
}
}
#ec2 생성
resource "aws_instance" "terraform-instance"{
ami = "ami-092dfb48456a3b119"
instance_type = "t2.micro"
key_name = var.key_name
subnet_id = aws_subnet.public1.id
vpc_security_group_ids = [aws_security_group.public.id]
associate_public_ip_address = true
user_data = file("user_data.sh")
lifecycle {
create_before_destroy = true
}
tags = {
"Name" = "terraform-instance"
}
}
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p 80 &
잘되는지 보기위한 유저데이터를 ec2에 삽입하여 ec2 실행시 hello world를 출력하는 아파치서버 실행
#DB subnet group 생성
resource "aws_db_subnet_group" "db_subnet_group" {
name = "db_subnet_group"
subnet_ids = [aws_subnet.private1.id, aws_subnet.private2.id]
tags = {
"Name" = "DB subnet group"
}
}
#DB 생성
resource "aws_db_instance" "db" {
allocated_storage = 10
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "terraform_db"
username = "admin"
password = "12345678"
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
availability_zone = "ap-northeast-2b"
db_subnet_group_name = aws_db_subnet_group.db_subnet_group.id
vpc_security_group_ids = [aws_security_group.private.id]
}
자주 쓰이거나 반복적으로 쓰이는 것들은 variables.tf에서 한번에 관리할 수도 있다.
#variables.tf
variable "key_name" { default = "mac-keypair" }
비록 alb를 못달았지만, 시간이 있다면 충분히 공식문서를 보고 해낼 수 있다.
이렇게 테라폼으로 인프라를 코드로 표기하면, 나중에 리전 옮길때나 팀으로 작업하기에 엄청 편리하다.
중요한 것은 인프라를 테라폼 코드로 옮기는 것이 아니라 어떻게 작동하는지 원리를 익히는 것이라 생각한다.
'IaC' 카테고리의 다른 글
[IaC]Terraform의 tfstate파일에 관하여 (0) | 2022.04.18 |
---|---|
[IaC]Terraform에 관하여 (0) | 2022.04.15 |