본문으로 건너뛰기

Terraform 사용하기

경고

Terraform을 사용한 워크샵 클러스터 생성은 현재 프리뷰 상태입니다. 발생한 문제는 GitHub 리포지토리에 제기해 주세요.

이 섹션에서는 HashiCorp Terraform을 사용하여 실습용 클러스터를 구축하는 방법을 설명합니다. 이는 Terraform infrastructure-as-code 사용에 익숙한 학습자를 위한 것입니다.

terraform CLI는 웹 IDE 환경에 사전 설치되어 있으므로 즉시 클러스터를 생성할 수 있습니다. 클러스터와 지원 인프라를 구축하는 데 사용될 주요 Terraform 구성 파일을 살펴보겠습니다.

Terraform 구성 파일 이해하기

providers.tf 파일은 인프라를 구축하는 데 필요한 Terraform provider를 구성합니다. 여기서는 aws, kubernetes, helm provider를 사용합니다:

provider "aws" {
default_tags {
tags = local.tags
}
}

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.67.0"
}
}

required_version = ">= 1.4.2"
}

main.tf 파일은 현재 사용 중인 AWS 계정과 리전을 가져오기 위한 Terraform 데이터 소스와 일부 기본 태그를 설정합니다:

locals {
tags = {
created-by = "eks-workshop-v2"
env = var.cluster_name
}
}

vpc.tf 구성은 VPC 인프라가 생성되도록 합니다:

locals {
private_subnets = [for k, v in local.azs : cidrsubnet(var.vpc_cidr, 3, k + 3)]
public_subnets = [for k, v in local.azs : cidrsubnet(var.vpc_cidr, 3, k)]
azs = slice(data.aws_availability_zones.available.names, 0, 3)
}

data "aws_availability_zones" "available" {
state = "available"
}

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0"

name = var.cluster_name
cidr = var.vpc_cidr

azs = local.azs
public_subnets = local.public_subnets
private_subnets = local.private_subnets
public_subnet_suffix = "SubnetPublic"
private_subnet_suffix = "SubnetPrivate"

enable_nat_gateway = true
create_igw = true
enable_dns_hostnames = true
single_nat_gateway = true

# Manage so we can name
manage_default_network_acl = true
default_network_acl_tags = { Name = "${var.cluster_name}-default" }
manage_default_route_table = true
default_route_table_tags = { Name = "${var.cluster_name}-default" }
manage_default_security_group = true
default_security_group_tags = { Name = "${var.cluster_name}-default" }

public_subnet_tags = merge(local.tags, {
"kubernetes.io/role/elb" = "1"
})
private_subnet_tags = merge(local.tags, {
"karpenter.sh/discovery" = var.cluster_name
"kubernetes.io/role/internal-elb" = "1"
})

tags = local.tags
}

마지막으로 eks.tf 파일은 Managed Node Group을 포함한 EKS 클러스터 구성을 지정합니다:

locals {
remote_node_cidr = var.remote_network_cidr
remote_pod_cidr = var.remote_pod_cidr
}

module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "21.0.9"

cluster_name = var.cluster_name
cluster_version = var.cluster_version
cluster_endpoint_public_access = true
enable_cluster_creator_admin_permissions = true

cluster_addons = {
vpc-cni = {
before_compute = true
most_recent = true
configuration_values = jsonencode({
env = {
ENABLE_POD_ENI = "true"
ENABLE_PREFIX_DELEGATION = "true"
POD_SECURITY_GROUP_ENFORCING_MODE = "standard"
}
nodeAgent = {
enablePolicyEventLogs = "true"
}
enableNetworkPolicy = "true"
})
}
}

vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets

create_cluster_security_group = false
create_node_security_group = false
cluster_security_group_additional_rules = {
hybrid-node = {
cidr_blocks = [local.remote_node_cidr]
description = "Allow all traffic from remote node/pod network"
from_port = 0
to_port = 0
protocol = "all"
type = "ingress"
}

hybrid-pod = {
cidr_blocks = [local.remote_pod_cidr]
description = "Allow all traffic from remote node/pod network"
from_port = 0
to_port = 0
protocol = "all"
type = "ingress"
}
}

node_security_group_additional_rules = {
hybrid_node_rule = {
cidr_blocks = [local.remote_node_cidr]
description = "Allow all traffic from remote node/pod network"
from_port = 0
to_port = 0
protocol = "all"
type = "ingress"
}

hybrid_pod_rule = {
cidr_blocks = [local.remote_pod_cidr]
description = "Allow all traffic from remote node/pod network"
from_port = 0
to_port = 0
protocol = "all"
type = "ingress"
}
}


cluster_remote_network_config = {
remote_node_networks = {
cidrs = [local.remote_node_cidr]
}
# Required if running webhooks on Hybrid nodes
remote_pod_networks = {
cidrs = [local.remote_pod_cidr]
}
}

eks_managed_node_groups = {
default = {
instance_types = ["m5.large"]
force_update_version = true
release_version = var.ami_release_version
use_name_prefix = false
iam_role_name = "${var.cluster_name}-ng-default"
iam_role_use_name_prefix = false

min_size = 3
max_size = 6
desired_size = 3

update_config = {
max_unavailable_percentage = 50
}

labels = {
workshop-default = "yes"
}
}
}

tags = merge(local.tags, {
"karpenter.sh/discovery" = var.cluster_name
})
}

Terraform으로 워크샵 환경 생성하기

이 구성을 기반으로 Terraform은 다음과 같이 워크샵 환경을 생성합니다:

  • 세 개의 가용 영역에 걸친 VPC
  • EKS 클러스터
  • IAM OIDC provider
  • default라는 이름의 managed node group
  • Prefix Delegation을 사용하도록 구성된 VPC CNI

Terraform 파일을 다운로드합니다:

~$mkdir -p ~/environment/terraform; cd ~/environment/terraform
~$curl --remote-name-all https://raw.githubusercontent.com/aws-samples/eks-workshop-v2/pull/1804/head/cluster/terraform/{main.tf,variables.tf,providers.tf,vpc.tf,eks.tf}

다음 Terraform 명령을 실행하여 워크샵 환경을 배포합니다:

~$export EKS_CLUSTER_NAME=eks-workshop
~$terraform init
~$terraform apply -var="cluster_name=$EKS_CLUSTER_NAME" -auto-approve

이 프로세스는 일반적으로 완료되는 데 20-25분이 걸립니다.

다음 단계

이제 클러스터가 준비되었으므로 실습 둘러보기 섹션으로 이동하거나 상단 내비게이션 바를 사용하여 워크샵의 모든 모듈로 건너뛸 수 있습니다. 워크샵을 완료한 후에는 아래 단계에 따라 환경을 정리하세요.

정리하기 (워크샵 완료 후 단계)

경고

다음은 EKS 클러스터 사용을 완료한 후 리소스를 정리하는 방법을 보여줍니다. 이 단계를 완료하면 AWS 계정에 대한 추가 요금이 발생하지 않습니다.

IDE 환경을 삭제하기 전에 이전 단계에서 설정한 클러스터를 정리합니다.

먼저 delete-environment를 사용하여 샘플 애플리케이션과 남아있는 실습 인프라가 제거되었는지 확인합니다:

~$delete-environment

다음으로 terraform을 사용하여 클러스터를 삭제합니다:

~$cd ~/environment/terraform
~$terraform destroy -var="cluster_name=$EKS_CLUSTER_NAME" -auto-approve

이제 IDE 정리하기를 진행할 수 있습니다.