Aws-EKS-IaC

메인 인덱스 | bob-yamong | 요약 | GitHub

한 줄 소개

Aws-EKS-IaC는 private endpoint EKS, private-subnet node group, bastion 접근 경로를 함께 정의한 단일 root-module Terraform 레포입니다.

기술 스택

  • Terraform
  • AWS VPC, EKS, EC2, IAM, NAT Gateway, EIP
  • TLS provider

코드 기준으로 확인한 구성

  • main.tf에서는 required_version >= 1.0.0, AWS provider ~> 4.0, TLS provider ~> 4.0를 사용합니다.
  • variables.tf 기본값 기준 리전은 us-east-1, 프로젝트 prefix는 EKS-TEST, 클러스터 이름은 EKS-Cluster, Kubernetes 버전은 1.31입니다.
  • VPC CIDR은 192.168.0.0/16이고, public subnet은 192.168.10.0/24, 192.168.20.0/24, private subnet은 192.168.11.0/24, 192.168.21.0/24입니다.
  • subnet AZ는 ${var.region}a, ${var.region}c를 전제로 나뉘어 있습니다.
  • public subnet에는 kubernetes.io/role/elb, private subnet에는 kubernetes.io/role/internal-elb 태그가 붙어 있고, 둘 다 kubernetes.io/cluster/${var.cluster_name} = shared 태그를 사용합니다.
  • EKS control plane과 managed node group용 IAM 역할을 분리하고, AmazonEKSClusterPolicy, AmazonEKSWorkerNodePolicy, AmazonEKS_CNI_Policy, AmazonEC2ContainerRegistryReadOnly를 연결합니다.
  • EKS 클러스터는 endpoint_private_access = true, endpoint_public_access = false로 설정돼 있습니다.
  • node group은 private subnet 2개에만 배치되고, 기본 스케일은 min 1 / desired 2 / max 2, 인스턴스 타입은 t3.medium, 디스크는 20GiB입니다.
  • bastion은 public subnet public_a에 배치되며, user data에서 AWS CLI, kubectl, eksctl을 설치합니다.

코드 기준 실행 흐름

  1. main.tf에서 Terraform과 provider 버전을 고정합니다.
  2. vpc.tf에서 VPC, Internet Gateway, subnet 4개, NAT Gateway 2개, route table과 association을 만듭니다.
  3. iam.tf에서 control plane용 aws_iam_role.eks_cluster_role과 node group용 aws_iam_role.eks_node_role을 만들고 AWS 관리형 정책을 붙입니다.
  4. security-groups.tf에서 EKS SG와 bastion SG를 만들고, bastion SG에서 EKS SG로 443, 10250, TCP/UDP 53을 허용합니다.
  5. eks.tf에서 EKS 클러스터를 만들 때 public/private subnet 4개를 모두 vpc_config.subnet_ids에 넣고, public endpoint는 끄고 private endpoint만 남깁니다.
  6. 같은 파일에서 managed node group은 private subnet 2개에만 배치합니다.
  7. bastion.tf에서 Terraform이 RSA 4096 키를 만들고, aws_key_pair.eks_key_pair를 통해 같은 key name을 bastion과 node group remote access에 연결합니다.
  8. 같은 파일의 local-exec provisioner는 ${var.project_name}-key.pem 파일을 Terraform 실행 디렉터리에 저장합니다.
  9. outputs.tf는 VPC ID, 클러스터 이름, 클러스터 endpoint, EKS SG ID, aws eks update-kubeconfig ... 명령, bastion SSH 명령, bastion public IP를 출력합니다.

개선 요구 사항 정리

  • bastion_ami 기본값이 특정 AMI ID에 고정돼 있어, 리전이나 시점이 바뀌면 수동 수정이 필요합니다.
  • bastion에서 내려받는 kubectl은 EKS 1.22.6 경로로 고정돼 있는데, 클러스터 변수 기본값은 1.31이라 버전 불일치 위험이 있습니다.
  • 코드에서는 instance profile 구성이 보이지 않습니다. bastion에서 aws configure로 자격 증명을 별도로 주입해야 합니다.
  • bastion SSH가 기본적으로 0.0.0.0/0에 열려 있어, 접근 범위를 별도 제한하지 않으면 노출 범위가 넓습니다.
  • workers_sg는 선언돼 있지만, 현재 보이는 코드 기준으로 node group이나 launch template에 연결된 흔적이 없습니다.
  • Terraform apply 시 private key 파일을 로컬 작업 디렉터리에 직접 남기기 때문에 비밀키 관리가 수동입니다.
  • S3 backend나 DynamoDB locking 같은 remote state 구성이 없어 협업형 IaC로 쓰기에는 부족합니다.
  • subnet AZ를 a, c suffix로 직접 조합하고 있어, 리전을 바꿔도 같은 AZ 조합이 항상 유효하다고 가정합니다.
  • 제가 로컬에서 terraform fmt -check -recursive를 돌리면 eks.tf가 포맷 불일치로 잡힙니다.
  • 커밋이 1개뿐이라 설계가 어떻게 진화했는지보다는 최종 스냅샷을 읽는 레포에 가깝습니다.

포트폴리오 메모

제가 이 레포를 소개할 때는 “운영 가능한 EKS 플랫폼을 완성했다”보다 “private endpoint EKS 환경을 띄우는 데 필요한 인프라 연결을 Terraform으로 정리한 레포”라고 설명하는 편이 맞습니다. 네트워크, 접근 경로, EKS 기본 구성을 한 번에 읽을 수 있고, 동시에 운영 관점에서 빠진 요소도 분명하게 짚을 수 있습니다.