Terraform은 IaC(Infra as a Code)도구입니다. EKS를 학습하던 중 계속 VPC부터 새로 만드는 것이 번거로워, Terraform을 이용해서 EKS 환경을 구성, 배포해보겠습니다.
Template 구성하기
먼저 EKS와 Control Host가 올라갈 VPC를 구성합니다.
resource "aws_vpc" "practice-vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "practice-vpc"
}
}
resource "aws_subnet" "public-a" {
vpc_id = aws_vpc.practice-vpc.id
cidr_block = "10.0.0.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-2a"
}
resource "aws_subnet" "public-c" {
vpc_id = aws_vpc.practice-vpc.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-2c"
}
resource "aws_subnet" "private-a" {
vpc_id = aws_vpc.practice-vpc.id
cidr_block = "10.0.2.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-2a"
}
resource "aws_subnet" "private-c" {
vpc_id = aws_vpc.practice-vpc.id
cidr_block = "10.0.3.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-2c"
}
resource "aws_internet_gateway" "practice-igw" {
vpc_id = aws_vpc.practice-vpc.id
tags = {
Name = "practice-internet-gateway"
}
}
resource "aws_default_route_table" "public-route_table" {
default_route_table_id = aws_vpc.practice-vpc.default_route_table_id
tags = {
Name = "default"
}
}
resource "aws_route" "internet-gw-route" {
route_table_id = aws_vpc.practice-vpc.main_route_table_id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.practice-igw.id
}
resource "aws_eip" "practice-nat-eip" {
vpc = true
depends_on = [aws_internet_gateway.practice-igw]
}
resource "aws_nat_gateway" "prac-nat" {
allocation_id = aws_eip.practice-nat-eip.id
subnet_id = aws_subnet.public-a.id
depends_on = [aws_internet_gateway.practice-igw]
}
resource "aws_route_table" "practice-private-route-table" {
vpc_id = aws_vpc.practice-vpc.id
tags = {
Name = "private"
}
}
resource "aws_route" "private_route" {
route_table_id = aws_route_table.practice-private-route-table.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.prac-nat.id
}
resource "aws_route_table_association" "public_subneta_association" {
subnet_id = aws_subnet.public-a.id
route_table_id = aws_vpc.practice-vpc.main_route_table_id
}
resource "aws_route_table_association" "public_subnetb_association" {
subnet_id = aws_subnet.public-c.id
route_table_id = aws_vpc.practice-vpc.main_route_table_id
}
resource "aws_route_table_association" "private_subneta_association" {
subnet_id = aws_subnet.private-a.id
route_table_id = aws_route_table.practice-private-route-table.id
}
resource "aws_route_table_association" "private_subnetb_association" {
subnet_id = aws_subnet.private-c.id
route_table_id = aws_route_table.practice-private-route-table.id
}
그리고, EKS Module을 이용하여 EKS Cluster를 생성해줍니다.
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "18.26.6"
cluster_name = "practice-cluster"
cluster_version = "1.22"
vpc_id = aws_vpc.practice-vpc.id
subnet_ids = [
aws_subnet.public-a.id,
aws_subnet.public-c.id,
aws_subnet.private-a.id,
aws_subnet.private-c.id
]
eks_managed_node_groups = {
default_node_group = {
min_size = 2
max_size = 5
desired_size = 2
instance_types = ["t3.small"]
}
}
tags = {
Environment = "dev"
Terraform = "true"
}
cluster_endpoint_private_access = true
}
resource "aws_security_group_rule" "eks_cluster_add_access" {
security_group_id = module.eks.cluster_security_group_id
type = "ingress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["10.0.0.0/16"]
}
resource "aws_security_group_rule" "eks_node_add_access" {
security_group_id = module.eks.node_security_group_id
type = "ingress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["10.0.0.0/16"]
}
기타 코드 ex) userdata, bastion, etc.. 들은 Github에 올라와있습니다.
GitHub - YoonHyunWoo/terraform-eks: terraform code repo for ci/cd and saving state
terraform code repo for ci/cd and saving state . Contribute to YoonHyunWoo/terraform-eks development by creating an account on GitHub.
github.com
배포 자동화하기
로그인 + 버튼정도의 과정으로 인프라가 배포되길 원했던 저는 테라폼 클라우드를 사용하기로 했습니다. terraform의 workspace나 state와 같은 파일들을 테라폼 클라우드 위에서 관리하고, Terraform runner로 사용할 수 있습니다. Github Repo를 Source 삼아 아래와 같은 workflow를 구현했습니다.
- 테라폼 깃헙 리포에 커밋이 푸쉬되면 트리거 동작합니다.
- 트리거 동작 시 클라우드에 EKS + VPC가 프로비저닝됩니다.
- 삭제를 누를 시 프로비저닝 되어있는 리소스가 내려갑니다.
그런데, 생각을 곰곰히 해보니 굳이 따로 인증 절차를 거친 후 버튼을 클릭할바에는 UI도 예쁘고, 인증 절차도 잘 구현되어있는 테라폼 클라우드의 UI에서 직접 프로비저닝과 삭제를 수행하는게 더 효율적이라는 생각이 들었습니다. 그래서 지금은 그냥 테라폼 클라우드에서 실행시키는 중이에요.. ㅎㅎ