테라폼의 모듈 구조를 사용해서 인프라 코드를 작성
먼저, 각 모듈을 저장할 깃허브 저장소를 생성하고, 네트워크, 쿠버네티스, Argo CD 모듈을 정의하고, 개발환경(env-sandbox)으로 통합
1 테라폼 모듈 저장소 생성
모듈별 깃허브 저장소
저장소 이름 | 공개 여부 | 설명 |
module-aws-network | 공개 | 네트워크를 생성하는 테라폼 모듈 |
module-aws-kubernetes | 공개 | EKS를 구축하는 테라폼 모듈 |
module-argo-cd | 공개 | Argo CD를 클러스터에 설치하는 테라폼 모듈 |
2 네트워크 모듈
쿠버네티스 및 마이크로서비스 아키텍처와 워크로드를 지원하는 AWS 네트워크 모듈을 작성
2.1 깃 클론
c:\msur> git clone https://github.com/myanjini/module-aws-network.git
Cloning into 'module-aws-network'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
2.2 네트워크 모듈 정의
C:\msur\module-aws-network\main.tf
Amazon VPC 리소스 정의
## AWS 공급자 선언
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs
provider "aws" {
region = var.aws_region # 모듈을 호출하는 곳에서 파라미터로 전달
}
## 로컬 변수 선언
## https://www.terraform.io/language/values/locals
locals {
vpc_name = "${var.env_name}-${var.vpc_name}"
cluster_name = "${var.env_name}-${var.cluster_name}"
}
## Amazon VPC 생성을 위한 코드를 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc
resource "aws_vpc" "main" {
cidr_block = var.main_vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
## 리소스 태그
## 리소스를 쉽게 식별하고 관리할 수 있으며,
## 자동화된 작업 및 특정 방식으로 관리해야 하는 리소스를 식별할 때 유용
tags = {
"Name" = local.vpc_name,
"kubernetes.io/cluster/${local.cluster_name}" = "shared",
}
}
서브넷 정의
## 공급자에 구성된 리전 내에서 AWS 계정이 액세스할 수 있는 가용 영역 목록을 조회
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones
data "aws_availability_zones" "available" {
state = "available"
}
## 퍼블릭 서브넷 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet
resource "aws_subnet" "public-subnet-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_a_cidr
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
"Name" = "${local.vpc_name}-public-subnet-a"
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_subnet" "public-subnet-b" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_b_cidr
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
"Name" = "${local.vpc_name}-public-subnet-b"
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}
}
## 프라이빗 서브넷 정의
resource "aws_subnet" "private-subnet-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_a_cidr
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
"Name" = "${local.vpc_name}-private-subnet-a"
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}
resource "aws_subnet" "private-subnet-b" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_b_cidr
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
"Name" = "${local.vpc_name}-private-subnet-b"
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}
참고: Network load balancing on Amazon EKS
https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html
EKS가 서브넷을 사용해 ELB를 생성하고 배포할 수 있도록 퍼블릭 서브넷에는 elb 태그를 지정하고, 프라이빗 서브넷에는 internal-elb 태그를 지정
퍼블릭 서브넷을 위한 인터넷 게이트웨이 및 라우팅 테이블 정의
## 인터넷 게이트웨이 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.vpc_name}-igw"
}
}
## 퍼블릭 라우팅 테이블 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table
resource "aws_route_table" "public-route" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
"Name" = "${local.vpc_name}-public-route"
}
}
## 퍼블릭 서브넷과 퍼블릭 라우팅 테이블 연결
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association
resource "aws_route_table_association" "public-a-association" {
subnet_id = aws_subnet.public-subnet-a.id
route_table_id = aws_route_table.public-route.id
}
resource "aws_route_table_association" "public-b-association" {
subnet_id = aws_subnet.public-subnet-b.id
route_table_id = aws_route_table.public-route.id
}
프라이빗 서브넷을 위한 NAT 게이트웨이 설정
## EIP를 생성해 NAT에 할당
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip
resource "aws_eip" "nat-a" {
vpc = true
tags = {
"Name" = "${local.vpc_name}-NAT-a"
}
}
resource "aws_eip" "nat-b" {
vpc = true
tags = {
"Name" = "${local.vpc_name}-NAT-b"
}
}
## NAT 게이트웨이 생성
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway
resource "aws_nat_gateway" "nat-gw-a" {
allocation_id = aws_eip.nat-a.id
subnet_id = aws_subnet.public-subnet-a.id
depends_on = [aws_internet_gateway.igw]
tags = {
"Name" = "${local.vpc_name}-NAT-gw-a"
}
}
resource "aws_nat_gateway" "nat-gw-b" {
allocation_id = aws_eip.nat-b.id
subnet_id = aws_subnet.public-subnet-b.id
depends_on = [aws_internet_gateway.igw]
tags = {
"Name" = "${local.vpc_name}-NAT-gw-b"
}
}
프라이빗 서브넷에 대한 라우팅을 정의
## 프라이빗 라우팅 테이블 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table
resource "aws_route_table" "private-route-a" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat-gw-a.id
}
tags = {
"Name" = "${local.vpc_name}-private-route-a"
}
}
resource "aws_route_table" "private-route-b" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat-gw-b.id
}
tags = {
"Name" = "${local.vpc_name}-private-route-b"
}
}
## 프라이빗 서브넷과 프라이빗 라우팅 테이블을 연결
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association
resource "aws_route_table_association" "private-a-association" {
subnet_id = aws_subnet.private-subnet-a.id
route_table_id = aws_route_table.private-route-a.id
}
resource "aws_route_table_association" "private-b-association" {
subnet_id = aws_subnet.private-subnet-b.id
route_table_id = aws_route_table.private-route-b.id
}
2.3 입력 값 정의
https://www.terraform.io/language/values/variables
C:\msur\module-aws-network\variables.tf
variable "env_name" {
type = string
}
variable "aws_region" {
type = string
}
variable "cluster_name" {
type = string
}
variable "vpc_name" {
type = string
default = "ms-up-running"
}
variable "main_vpc_cidr" {
type = string
}
variable "public_subnet_a_cidr" {
type = string
}
variable "public_subnet_b_cidr" {
type = string
}
variable "private_subnet_a_cidr" {
type = string
}
variable "private_subnet_b_cidr" {
type = string
}
2.4 출력 값 정의
https://www.terraform.io/language/values/outputs
명령줄에서 사용할 수 있는 인프라에 대한 정보를 만들고, 다른 테라폼 구성에서 사용할 정보를 노출
C:\msur\module-aws-network\outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
}
output "subnet_ids" {
value = [
aws_subnet.public-subnet-a.id,
aws_subnet.public-subnet-b.id,
aws_subnet.private-subnet-a.id,
aws_subnet.private-subnet-b.id]
}
output "public_subnet_ids" {
value = [aws_subnet.public-subnet-a.id, aws_subnet.public-subnet-b.id]
}
output "private_subnet_ids" {
value = [aws_subnet.private-subnet-a.id, aws_subnet.private-subnet-b.id]
}
output "route53_id" {
value = aws_route53_zone.private-zone.zone_id
}
2.5 형식 지정 → 작업 디렉터리 초기화 → 구성 검사
C:\msur\module-aws-network> terraform fmt
C:\msur\module-aws-network> terraform init
C:\msur\module-aws-network> terraform validate
╷
│ Error: Reference to undeclared resource
│
│ on outputs.tf line 22, in output "route53_id":
│ 22: value = aws_route53_zone.private-zone.zone_id
│
│ A managed resource "aws_route53_zone" "private-zone" has not been declared in the root module.
2.6 수정 후 다시 검사
C:\msur\module-aws-network\outputs.tf
# 오류가 발생하는 부분 주석 처리
# output "route53_id" {
# value = aws_route53_zone.private-zone.zone_id
# }
C:\msur\module-aws-network> terraform validate
Success! The configuration is valid.
2.7 깃허브 저장소에 푸시
C:\msur\module-aws-network> git add .
c:\msur\module-aws-network> git commit -m "네트워크 모듈 생성"
C:\msur\module-aws-network> git push
2.8 샌드박스 환경에 네트워크 생성
네트워크 모듈 추가
C:\kubernetes\env-sandbox\main.tf
terraform {
backend "s3" {
bucket = "sk403-003-bucket"
key = "terraform/backend"
region = "us-west-2"
}
}
locals {
env_name = "sandbox"
aws_region = "us-west-2"
vpc_name = "sk403-003-vpc"
k8s_cluster_name = "sk403-003-ms-cluster"
}
# AWS 네트워크 구성
module "aws-network" {
source = "git::https://github.com/naanjini/module-aws-network.git"
env_name = local.env_name
aws_region = local.aws_region
vpc_name = local.vpc_name
cluster_name = local.k8s_cluster_name
main_vpc_cidr = "10.10.0.0/16"
public_subnet_a_cidr = "10.10.0.0/18"
public_subnet_b_cidr = "10.10.64.0/18"
private_subnet_a_cidr = "10.10.128.0/18"
private_subnet_b_cidr = "10.10.192.0/18"
}
# TODO EKS 클러스터 구성
# TODO GitOps 구성
형식 지정, 작업 디렉터리 초기화, 구성 검사
c:\msur\env-sandbox> terraform fmt
c:\msur\env-sandbox> terraform init
c:\msur\env-sandbox> terraform validate
인프라 구축을 위한 실행 계획 확인 (모의 테스트, dry run)
c:\msur\env-sandbox> terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.aws-network.aws_eip.nat-a will be created
:
Plan: 17 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
릴리스 태그 지정 및 깃허브 저장소에 푸시
c:\msur\env-sandbox> git add .
c:\msur\env-snadbox> git commit -m "네트워크 구성"
c:\msur\env-snadbox> git push origin
c:\msur\env-snadbox> git tag -a v1.0 -m "네트워크 구성"
c:\msur\env-snadbox> git push origin v1.0
워크플로우 실행 확인
VPC 생성 확인
c:\msur\env-sandbox> aws ec2 describe-vpcs --filters Name=cidr,Values=10.10.0.0/16
{
"Vpcs": [
{
"CidrBlock": "10.10.0.0/16",
"DhcpOptionsId": "dopt-070584ca7a8169184",
"State": "available",
"VpcId": "vpc-003e20f45f753961f",
"OwnerId": "286943186215",
"InstanceTenancy": "default",
"CidrBlockAssociationSet": [
{
"AssociationId": "vpc-cidr-assoc-07fc143983e5027bc",
"CidrBlock": "10.10.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
],
"IsDefault": false,
"Tags": [
{
"Key": "kubernetes.io/cluster/sandbox-sk403-003-ms-cluster",
"Value": "shared"
},
{
"Key": "Name",
"Value": "sandbox-sk403-003-vpc"
}
]
}
]
}
2.9 생성한 리소스 모두 삭제
c:\msur\env-sandbox> terraform destroy
:
Plan: 0 to add, 0 to change, 17 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
:
Destroy complete! Resources: 17 destroyed.
댓글