Skip to content

Repository files navigation

Terraform EKS Infrastructure

AWS EKS 클러스터와 주변 인프라를 프로비저닝하는 Terraform 프로젝트입니다.
VPC(사설 서브넷), IAM Role, Security Group, EKS Cluster/Managed NodeGroup, IRSA(IAM Roles for Service Accounts),
(선택) AWS IoT Things/Certificate/Policy 구성을 포함합니다.

목차


아키텍처

Root Module
│
├── module.iam        → EKS 클러스터·노드용 IAM 역할 생성
├── module.vpc        → 멀티-AZ 사설 서브넷, NAT 게이트웨이, 라우트 테이블 생성
├── module.security   → EKS용 보안 그룹 생성
├── module.eks        → EKS 클러스터 및 관리형 노드 그룹 생성
├── module.irsa       → OIDC 공급자, ALB Controller·ESO Kafka용 IRSA 역할 생성
└── module.iot (주석) → AWS IoT Things·인증서·정책 생성 (선택)

의존성 흐름:

iam ─┐
vpc ─┼─► eks ─► irsa
sec ─┘

사전 준비

도구 최소 버전 비고
Terraform >= 1.5.0
AWS CLI >= 2.x aws eks update-kubeconfig 사용
kubectl 클러스터 버전과 일치
jq - apply.sh 사용 시 필요

AWS 자격증명이 설정되어 있어야 합니다:

aws configure
# 또는
export AWS_PROFILE=<profile-name>

빠른 시작

# 1) terraform.tfvars 파일 생성
cp terraform.tfvars.example terraform.tfvars

# 2) 초기화
terraform init

# 3) 플랜 확인
terraform plan

# 4) 적용
terraform apply

# 또는 apply.sh 스크립트 사용 (검증·플랜·적용·kubeconfig 업데이트 자동화)
bash apply.sh

설정 (루트 모듈 변수)

terraform.tfvars 파일에 아래 변수를 설정합니다. (.gitignore에 포함되어 커밋되지 않습니다)

권장: 변수는 "필수/기본값/민감정보 여부"를 팀 표준으로 통일해서 관리하세요.

변수명 타입 필수 기본값 설명
aws_region string - AWS 리전 (예: ap-northeast-2)
vpc_id string - 기존 VPC ID
rtb_id string - 기존 라우트 테이블 ID
cluster_name string - EKS 클러스터 이름
nodegroup_name string - EKS 관리형 노드 그룹 이름
desired_capacity number - 원하는 노드 수
min_capacity number - 최소 노드 수
max_capacity number - 최대 노드 수
instance_types list(string) - EC2 인스턴스 타입 목록
azs list(string) - 가용 영역 목록
public_subnet_ids list(string) - 공용 서브넷 ID 목록 (NAT 게이트웨이 배치용)
private_subnet_cidrs list(string) - 생성할 사설 서브넷 CIDR 목록 (azs와 순서 일치)
server_tls_secret_prefix string - Kafka 브로커 서버 TLS 시크릿의 Secrets Manager 이름 접두사
client_tls_secret_prefix string - Kafka 퍼블리셔 클라이언트 TLS 시크릿의 Secrets Manager 이름 접두사
factory_id string IoT 사용 시 - IoT 팩토리 ID
line_id string IoT 사용 시 - IoT 라인 ID
equipment_thing_names set(string) IoT 사용 시 - IoT 장비 Thing 이름 목록

terraform.tfvars 예시:

aws_region     = "ap-northeast-2"
vpc_id         = "vpc-0123456789abcdef0"
rtb_id         = "rtb-0123456789abcdef0"
cluster_name   = "my-eks-cluster"
nodegroup_name = "my-node-group"

desired_capacity = 2
min_capacity     = 1
max_capacity     = 4
instance_types   = ["t3.medium"]

azs                  = ["ap-northeast-2a", "ap-northeast-2c"]
public_subnet_ids    = ["subnet-aaa111", "subnet-bbb222"]
private_subnet_cidrs = ["10.0.10.0/24", "10.0.11.0/24"]

server_tls_secret_prefix = "kafka/broker/tls"
client_tls_secret_prefix = "kafka/client/tls"

모듈 상세

Module: iammodules/iam/

EKS 클러스터 제어 플레인과 워커 노드에 필요한 IAM 역할을 생성합니다.

입력 변수

변수명 타입 필수 설명
cluster_name string IAM 역할 이름에 사용되는 EKS 클러스터 이름

출력값

출력명 설명
eks_cluster_role_arn 클러스터 제어 플레인 IAM 역할 ARN
eks_cluster_role_name 클러스터 제어 플레인 IAM 역할 이름
eks_node_role_arn 워커 노드 IAM 역할 ARN
eks_node_role_name 워커 노드 IAM 역할 이름

연결되는 관리형 정책:

  • 클러스터: AmazonEKSClusterPolicy
  • 노드: AmazonEKSWorkerNodePolicy, AmazonEKS_CNI_Policy, AmazonEC2ContainerRegistryReadOnly, CloudWatchAgentServerPolicy

Module: vpcmodules/vpc/

기존 VPC 내에 멀티-AZ 사설 서브넷, NAT 게이트웨이, 라우트 테이블을 생성합니다.

입력 변수

변수명 타입 필수 설명
vpc_id string 기존 VPC ID
azs list(string) 가용 영역 목록
public_subnet_ids list(string) 기존 공용 서브넷 ID 목록 (NAT 게이트웨이 배치용, azs와 순서 일치)
private_subnet_cidrs list(string) 사설 서브넷 CIDR 목록 (azs와 순서 일치)

출력값

출력명 설명
vpc_id VPC ID
private_subnet_ids 생성된 사설 서브넷 ID 목록
nat_gateway_ids 생성된 NAT 게이트웨이 ID 목록
private_route_table_ids 생성된 사설 라우트 테이블 ID 목록

Module: securitymodules/security/

EKS 클러스터용 보안 그룹을 생성합니다. 내부 통신(self) 허용, 전체 아웃바운드 허용.

입력 변수

변수명 타입 필수 설명
cluster_name string 보안 그룹 이름에 사용되는 클러스터 이름
vpc_id string 보안 그룹을 생성할 VPC ID

출력값

출력명 설명
eks_security_group_id 생성된 EKS 보안 그룹 ID

Module: eksmodules/eks/

EKS 클러스터 제어 플레인과 관리형 노드 그룹을 생성합니다.

입력 변수

변수명 타입 기본값 설명
cluster_name string - EKS 클러스터 이름
cluster_version string null Kubernetes 버전 (null이면 최신)
cluster_role_arn string - 클러스터 제어 플레인 IAM 역할 ARN
node_role_arn string - 워커 노드 IAM 역할 ARN
private_subnet_ids list(string) - 클러스터 및 노드 배치용 사설 서브넷 ID 목록
eks_security_group_id string - EKS 보안 그룹 ID
endpoint_private_access bool true 클러스터 프라이빗 엔드포인트 활성화 여부
endpoint_public_access bool true 클러스터 퍼블릭 엔드포인트 활성화 여부
public_access_cidrs list(string) ["0.0.0.0/0"] 퍼블릭 엔드포인트 접근 허용 CIDR 목록
nodegroup_name string - 노드 그룹 이름
desired_capacity number - 원하는 노드 수
min_capacity number - 최소 노드 수
max_capacity number - 최대 노드 수
instance_types list(string) - EC2 인스턴스 타입 목록
capacity_type string ON_DEMAND ON_DEMAND 또는 SPOT

출력값

출력명 설명
cluster_name 클러스터 이름
cluster_arn 클러스터 ARN
cluster_endpoint 클러스터 API 서버 엔드포인트
cluster_certificate_authority_data 클러스터 CA 인증서 (Base64)
cluster_oidc_issuer_url OIDC 발급자 URL (IRSA 구성에 사용)
node_group_name 노드 그룹 이름
node_group_arn 노드 그룹 ARN

Module: irsamodules/irsa/

EKS OIDC 공급자를 생성하고, ALB Controller와 External Secrets Operator(Kafka)를 위한 IRSA 역할 및 정책을 설정합니다.

입력 변수

변수명 타입 기본값 설명
cluster_name string - EKS 클러스터 이름
oidc_issuer_url string - EKS OIDC 발급자 URL (module.eks.cluster_oidc_issuer_url)
aws_region string - AWS 리전
aws_account_id string - AWS 계정 ID
server_tls_secret_prefix string - Kafka 브로커 TLS 시크릿 접두사
client_tls_secret_prefix string - Kafka 클라이언트 TLS 시크릿 접두사
alb_controller_namespace string kube-system ALB Controller가 배포될 K8s 네임스페이스
alb_controller_service_account_name string aws-load-balancer-controller ALB Controller 서비스 어카운트 이름
eso_namespace string external-secrets ESO가 배포될 K8s 네임스페이스
eso_kafka_service_account_name string eso-kafka-sa ESO Kafka 서비스 어카운트 이름

출력값

출력명 설명
oidc_provider_arn OIDC 공급자 ARN
oidc_provider_url OIDC 공급자 URL
alb_controller_role_arn ALB Controller IAM 역할 ARN
alb_controller_role_name ALB Controller IAM 역할 이름
eso_kafka_secrets_role_arn ESO Kafka IAM 역할 ARN
eso_kafka_secrets_role_name ESO Kafka IAM 역할 이름

Module: iot (선택) — modules/iot/

AWS IoT Things, 인증서, 정책을 생성하고 인증서 파일을 로컬에 저장합니다.
기본적으로 main.tf에서 주석 처리되어 있습니다. 활성화하려면 주석을 해제하세요.

입력 변수

변수명 타입 필수 설명
aws_region string AWS 리전
aws_account_id string AWS 계정 ID
factory_id string 팩토리 ID (MQTT 토픽 경로 및 정책에 사용)
line_id string 라인 ID (MQTT 토픽 경로 및 정책에 사용)
equipment_thing_names set(string) 등록할 장비 Thing 이름 목록

출력값

출력명 설명
iot_endpoint AWS IoT ATS 엔드포인트 주소
equipment_thing_names 등록된 Thing 이름 목록 (정렬)
equipment_topic_filter MQTT 토픽 필터 패턴
cert_files_created 생성된 인증서 파일 경로 목록

주의: 이 모듈은 개인 키(.key) 파일을 ../certs/ 디렉토리에 로컬로 생성합니다. 해당 파일은 반드시 안전하게 관리하고 절대 커밋하지 마십시오.


배포 방법

수동 배포

terraform init
terraform validate
terraform plan -out=tfplan
terraform apply tfplan

자동화 스크립트 사용

apply.sh는 다음을 자동으로 수행합니다:

  1. 도구 사전 조건 확인 (terraform, aws, jq)
  2. terraform initvalidate
  3. terraform plan (변경 사항 있을 때만 apply)
  4. EKS 클러스터 활성화 대기
  5. kubeconfig 자동 업데이트
bash apply.sh

kubeconfig 업데이트 (수동)

aws eks update-kubeconfig \
  --region <aws_region> \
  --name <cluster_name>

Troubleshooting

1. plan/apply가 권한(AccessDenied)으로 실패할 때

  • AWS_PROFILE / AssumeRole 설정 확인
  • Terraform 실행 계정에 필요한 IAM 권한 확인

2. aws eks update-kubeconfig는 성공했는데 kubectl이 401/403

  • EKS 인증은 kubeconfig만으로 끝나지 않고, 클러스터 RBAC(aws-auth ConfigMap 등) 매핑이 필요할 수 있습니다.

3. VPC/서브넷/NAT 관련 네트워크 이슈

  • private subnet에서 외부 통신이 필요하면 NAT 및 라우팅 설정 확인
  • 노드가 ECR pull을 못하면 NAT 게이트웨이 또는 VPC Endpoint 구성이 필요할 수 있습니다.

주의사항

  • terraform.tfvars 파일은 .gitignore에 포함되어 있습니다. 민감한 값이 포함될 수 있으므로 절대 커밋하지 마십시오.
  • Terraform 상태 파일(.tfstate) 은 팀 협업 시 원격 백엔드(S3 + DynamoDB) 사용을 권장합니다. 로컬 state는 충돌 및 유실 위험이 있습니다.
  • IoT 인증서 파일(../certs/*.key, ../certs/*.pem)은 개인 키를 포함합니다. 생성 후 안전한 저장소로 이전하십시오.
  • public_access_cidrs의 기본값은 ["0.0.0.0/0"]입니다. 프로덕션 환경에서는 접근 허용 CIDR을 제한하는 것을 권장합니다.
  • EKS 클러스터 삭제 전 LoadBalancer 타입 Service 등 Kubernetes 리소스를 먼저 정리해야 VPC 삭제 실패를 피할 수 있습니다.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages