Terraform를 사용한 Amazon EKS에서 ArgoCD와 GitOps: 완전 구현 가이드

발행: (2025년 12월 12일 오후 01:35 GMT+9)
5 min read
원문: Dev.to

Source: Dev.to

GitOps 개요

GitOps는 선언형 인프라와 애플리케이션에 대한 단일 진실 소스로 Git을 사용하는 현대적인 지속적 배포 접근 방식입니다. 핵심 원칙은 다음과 같습니다:

  • 선언형 구성 – 모든 것이 Git에 선언형으로 기술됩니다.
  • 버전 관리 – 모든 변경 사항이 추적되고 감사 가능합니다.
  • 자동 배포 – Git의 변경이 자동 배포를 트리거합니다.
  • 지속적 모니터링 – 시스템이 원하는 상태와 실제 상태가 일치하도록 지속적으로 확인합니다.

왜 ArgoCD인가?

ArgoCD는 Kubernetes용 선언형 GitOps 지속적 전달 도구로 다음을 제공합니다:

  • 애플리케이션 관리 – 여러 애플리케이션을 중앙에서 관리합니다.
  • 멀티‑클러스터 지원 – 여러 Kubernetes 클러스터에 배포할 수 있습니다.
  • 풍부한 UI – 배포를 모니터링하기 위한 직관적인 웹 인터페이스를 제공합니다.
  • RBAC 통합 – 세밀한 접근 제어가 가능합니다.
  • 롤백 기능 – 이전 버전으로 쉽게 롤백할 수 있습니다.

아키텍처 개요

우리 구현은 다음과 같은 견고하고 확장 가능한 아키텍처를 생성합니다:

┌──────────────────────────────────────────────────────────────┐
│                        AWS Cloud                             │
│  ┌──────────────────────────────────────────────────────────┐│
│  │                    VPC                                   ││
│  │  ┌─────────────────┐    ┌──────────────────────────────┐ ││
│  │  │  Public Subnets │    │      Private Subnets         │ ││
│  │  │                 │    │  ┌─────────────────────────┐ │ ││
│  │  │  ┌───────────┐  │    │  │      EKS Cluster        │ │ ││
│  │  │  │    NAT    │  │    │  │  ┌─────────────────────┐│ │ ││
│  │  │  │  Gateway  │  │    │  │  │   NGINX Ingress     ││ │ ││
│  │  │  └───────────┘  │    │  │  │    Controller       ││ │ ││
│  │  │                 │    │  │  └─────────────────────┘│ │ ││
│  │  └─────────────────┘    │  │  ┌─────────────────────┐│ │ ││
│  │                         │  │  │     ArgoCD          ││ │ ││
│  │                         │  │  │     Server          ││ │ ││
│  │                         │  │  └─────────────────────┘│ │ ││
│  │                         │  │  ┌─────────────────────┐│ │ ││
│  │                         │  │  │   Application       ││ │ ││
│  │                         │  │  │   Workloads         ││ │ ││
│  │                         │  │  └─────────────────────┘│ │ ││
│  │                         │  └─────────────────────────┘ │ ││
│  │                         └──────────────────────────────┘ ││
│  └──────────────────────────────────────────────────────────┘│
│                                                              │
│  ┌──────────────────────────────────────────────────────────┐│
│  │                   Route53                                ││
│  │  argocd.chinmayto.com → NGINX Ingress NLB                ││
│  │  app.chinmayto.com → NGINX Ingress NLB                  ││
│  └──────────────────────────────────────────────────────────┘│
└──────────────────────────────────────────────────────────────┘

사전 요구 사항

시작하기 전에 다음을 확인하세요:

  • 적절한 권한이 설정된 AWS CLI
  • Terraform 설치 (버전 ≥ 1.0)
  • kubectl 설치
  • Route53에 등록된 도메인 이름
  • Helm 설치 (버전 ≥ 3.0)

구현 단계

단계 1: VPC 및 EKS 클러스터 생성

AWS 커뮤니티 Terraform 모듈을 사용해 기본 인프라를 생성합니다.

변수 (infrastructure/variables.tf)

variable "aws_region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "cluster_name" {
  description = "Name of the EKS cluster"
  type        = string
  default     = "CT-EKS-Cluster"
}

variable "cluster_version" {
  description = "Kubernetes version for the EKS cluster"
  type        = string
  default     = "1.33"
}

variable "vpc_cidr" {
  description = "CIDR block for VPC"
  type        = string
  default     = "10.0.0.0/16"
}

variable "public_subnet_cidrs" {
  description = "CIDR blocks for public subnets"
  type        = list(string)
  default     = ["10.0.1.0/24", "10.0.2.0/24"]
}

variable "private_subnet_cidrs" {
  description = "CIDR blocks for private subnets"
  type        = list(string)
  default     = ["10.0.10.0/24", "10.0.20.0/24"]
}

메인 Terraform 구성 (infrastructure/main.tf)

# Data source for availability zones
data "aws_availability_zones" "available" {
  state = "available"
}

# VPC Module Configuration
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = "${var.cluster_name}-VPC"
  cidr = var.vpc_cidr

  azs               = slice(data.aws_availability_zones.available.names, 0, 2)
  private_subnets   = var.private_subnet_cidrs
  public_subnets    = var.public_subnet_cidrs

  enable_nat_gateway = true
  enable_vpn_gateway = false
  single_nat_gateway = true

  enable_dns_hostnames = true
  enable_dns_support   = true

  public_subnet_tags = {
    "kubernetes.io/role/elb" = "1"
  }

  private_subnet_tags = {
    "kubernetes.io/role/internal-elb" = "1"
  }

  tags = {
    Name      = "${var.cluster_name}-VPC"
    Terraform = "true"
  }
}

# EKS Cluster Module Configuration
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.0"

  cluster_name    = var.cluster_name
  cluster_version = var.cluster_version

  vpc_id                                   = module.vpc.vpc_id
  subnet_ids                               = module.vpc.private_subnets
  cluster_endpoint_public_access          = true
  enable_cluster_creator_admin_permissions = true

  # EKS Managed Node Groups
  eks_managed_node_groups = {
    EKS_Node_Group = {
      min_size     = 1
      max_size     = 3
      desired_size = 2

      instance_types = ["t3.medium"]
      capacity_type  = "ON_DEMAND"

      subnet_ids = module.vpc.private_subnets
    }
  }

  # EKS Add‑ons
  cluster_addons = {
    coredns = {
      most_recent = true
    }
    kube-proxy = {
      most_recent = true
    }
    vpc-cni = {
      most_recent = true
    }
    eks-pod-identity-agent = {
      most_recent = true
    }
  }

  tags = {
    Name      = var.cluster_name
    Terraform = "true"
  }
}

# Null Resource to update the kubeconfig file
resource "null_resource" "update_kubeconfig" {
  provisioner "local-exec" {
    command = "aws eks --region ${var.aws_region} update-kubeconfig --name ${var.cluster_name}"
  }

  depends_on = [module.eks]
}
Back to Blog

관련 글

더 보기 »