CloudNet@ Team Study/EKS Workshop 4th Cohort

GitOps App and Infrastructure Design

"Everything about infra" 2026. 4. 27. 04:30
포스팅은 CloudNet@팀 서종호(Gasida)님이 진행하시는
AWS EKS Workshop Study 내용을 참고하여 작성합니다.

 

이번 챕터에서는 워크숍에서 제공해준 GitOps 인프라 중

실습 1번 항목인 앱 및 인프라 설계에 대해서 다뤄볼 예정입니다.

 

 

샘플 테넌트 로드맵은 아래와 같습니다.

이번 워크숍에서는 임차인들을 위한 두 가지 애플리케이션에 대해서 다뤄볼 예정입니다.

  • 프로듀서 : API 호출을 수신하고, 메시지를 생성하여 SQS 큐로 전송하는 역할을 담당합니다.
  • 컨슈머 : SQS 큐에서 메시지를 가져와 특정 DynamoDB 테이블에 저장하는 역할을 담당합니다.

애플리케이션들이 Amazon SQS 및 Amazon DynamoDB와 같은

외부 서비스와 어떻게 상호 작용하는지를 보여줍니다.

 

01. 앱 및 인프라 설계

현대 조직에서 팀은 일반적으로 애플리케이션 개발팀과 인프라/운영팀, 두 가지로 나뉩니다.

각 팀의 소유권과 책임은 명확히 구분되어 있으며, 대부분의 애플리케이션은 IAM, SQS 큐, DynamoDB 테이블

같은 특정 인프라 구성 요소를 필요로 합니다.

 

이 때문에 개발자가 인프라팀에 리소스 생성을 요청하는 상황이 반복적으로 발생하겠죠 ?

하지만 조직 규모가 커질수록 요청이 쌓이며, 인프라팀은 업무가 병목 현상에 직면하게 됩니다.

현재 관행을 개선할 여유도 없어지고, 테넌트가 늘어날수록 이 문제는 기하급수적으로 악화돼요.

 

개발 주도형 인프라 (Developer-Driven Infrastructure)

중앙 집중식 모델과 대조적으로, 개발자 주도형 인프라는 개발자가 사전 정의된 보안 및 거버넌스 프레임워크

내에서 인프라 구성 요소를 직접 프로비저닝하고 관리할 수 있도록 지원하는 패러다임을 지향합니다.

 

이 모델은 자동화 및 IaC(Infrastructure as Code) 도구를 활용하여 개발자에게 셀프 서비스 기능을 제공하고, 각 애플리케이션의 특정 요구 사항에 따라 인프라를 신속하게 프로비저닝할 수 있도록 합니다.

이번 실습에서는 Terraform 모듈 → Tofu 컨트롤러 → Helm Chart → HelmRelease의 흐름으로

이 패러다임을 직접 구현해 볼 예정 입니다!

 

02. EKS 클러스터 및 추가기능 확인

현재 어떤 리소스들이 띄워져 있는지 확인 해볼까요 ?

kubectl get namespace

 

아래와 같이 한눈에 정리해보았습니다.

[인프라/시스템]
kube-system / kube-node-lease / kube-public / default / aws-system

[GitOps 엔진]
flux-system

[테넌트 자동화]
argo-events → argo-workflows → onboarding-service

[테넌트 앱]
pool-1 (Basic 티어)

[노드 관리]
karpenter

[비용 추적]
kubecost

 

1) GitOps Controller : flux-system

  • Gitea GitOps Repository를 Watch하고 Reconcile 실행하는 핵심 컨트롤러 입니다.
  • Flux v2가 떠있는 곳입니다.

2) 테넌트 온보딩/오프보딩 자동화

argo-workflows       ← 워크플로우 실행 엔진
argo-events          ← 워크플로우를 트리거하는 이벤트 처리
onboarding-service   ← 온보딩 API/서비스가 떠 있는 곳

외부 요청(테넌트 추가) → argo-events (이벤트 감지) → argo-workflows (Onboarding 워크플로우 실행)

→ onboarding-service (실제 처리 로직) → Gitea에 테넌트 설정 파일 Push → flux-system이 감지

→ pool-1 실행. 이 흐름으로 자동화 처리 합니다.

 

3) SaaS 테넌트 실제 배포 공간 : pool-1

  • Basic 티어 테넌트들이 공유하는 Pool 네임스페이스
  • Producer/Consumer 앱이 실제로 떠 있는 곳
  • 테넌트가 추가될수록 pool-2, pool-3... 이런 식으로 늘어날 수 있음

'kubectl get all -n pool-1' 명령으로 확인해보았을 때 리소스는 아래와 같습니다.

pool-1 namespace
├─ Producer Deployment (replica: 3)   ← 메시지 생성
│    ├─ pod: bzzbn
│    ├─ pod: g85kf
│    └─ pod: v8mnr
│
└─ Consumer Deployment (replica: 3)   ← 메시지 소비
     ├─ pod: 8tgc8
     ├─ pod: 9grdh
     └─ pod: gkl7g

 

4) 노드 프로비저닝 : karpenter

  • Pool namespace에 앱이 배포될 때 노드가 부족하면 Karpenter가 자동으로 노드 추가

5) 비용 모니터링 : kubecost

  • 테넌트별 비용을 추적하는 도구
  • SaaS에서 테넌트마다 얼마나 리소스를 쓰는지 파악하는 게 중요하니까 함께 구성된 것입니다.

 

Flux 리소스 확인

Flux는 이 솔루션의 핵심 엔진으로, Git 및 ECR의 변경 사항을 감시하여 클러스터 상태를 선언된 상태와

일치시키는 역할을 담당합니다. 다음 명령으로 전체 Flux 리소스를 확인해볼까요 ?

[ec2-user@ip-10-0-1-79 environment]$ flux get all
NAME                    REVISION                SUSPENDED       READY   MESSAGE                                             
ocirepository/capacitor v0.4.8@sha256:1efcb443  False           True    stored artifact for digest 'v0.4.8@sha256:1efcb443'

NAME                            REVISION                        SUSPENDED       READY   MESSAGE                                                      
gitrepository/flux-system       refs/heads/main@sha1:83debf83   False           True    stored artifact for revision 'refs/heads/main@sha1:83debf83'
gitrepository/terraform-v0-0-1  v0.0.1@sha1:2d19a84a            False           True    stored artifact for revision 'v0.0.1@sha1:2d19a84a'         

NAME                                    REVISION        SUSPENDED       READY   MESSAGE                                     
helmrepository/argo                     sha256:77d58f2f False           True    stored artifact: revision 'sha256:77d58f2f'
helmrepository/eks-charts               sha256:d5d7cd31 False           True    stored artifact: revision 'sha256:d5d7cd31'
helmrepository/helm-application-chart                   False           True    Helm repository is Ready                   
helmrepository/helm-tenant-chart                        False           True    Helm repository is Ready                   
helmrepository/karpenter                                False           True    Helm repository is Ready                   
helmrepository/kubecost                                 False           True    Helm repository is Ready                   
helmrepository/metrics-server           sha256:ba69c5bb False           True    stored artifact: revision 'sha256:ba69c5bb'
helmrepository/tf-controller            sha256:1fcad0f6 False           True    stored artifact: revision 'sha256:1fcad0f6'

NAME                                                    REVISION        SUSPENDED       READY   MESSAGE                                                          
helmchart/flux-system-argo-events                       2.4.3           False           True    pulled 'argo-events' chart with version '2.4.3'                 
helmchart/flux-system-argo-workflows                    0.40.11         False           True    pulled 'argo-workflows' chart with version '0.40.11'            
helmchart/flux-system-aws-load-balancer-controller      1.6.2           False           True    pulled 'aws-load-balancer-controller' chart with version '1.6.2'
helmchart/flux-system-karpenter                         1.4.0           False           True    pulled 'karpenter' chart with version '1.4.0'                   
helmchart/flux-system-kubecost                          2.1.0           False           True    pulled 'cost-analyzer' chart with version '2.1.0'               
helmchart/flux-system-metrics-server                    3.11.0          False           True    pulled 'metrics-server' chart with version '3.11.0'             
helmchart/flux-system-onboarding-service                0.0.1           False           True    pulled 'application-chart' chart with version '0.0.1'           
helmchart/flux-system-pool-1                            0.0.1           False           True    pulled 'helm-tenant-chart' chart with version '0.0.1'           
helmchart/flux-system-tf-controller                     0.16.0-rc.4     False           True    pulled 'tf-controller' chart with version '0.16.0-rc.4'         

NAME                                            LAST SCAN               SUSPENDED       READY   MESSAGE                                                
imagerepository/consumer-image-repository       2026-04-26T17:04:07Z    False           True    successful scan: found 2 tags with checksum 1936459500
imagerepository/payments-image-repository       2026-04-26T17:04:07Z    False           True    successful scan: found 2 tags with checksum 1936983789
imagerepository/producer-image-repository       2026-04-26T17:04:07Z    False           True    successful scan: found 2 tags with checksum 1937901294

NAME                                    IMAGE                                                   TAG                  READY    MESSAGE                                                                                                     
imagepolicy/consumer-image-policy       398879295738.dkr.ecr.us-west-2.amazonaws.com/consumer   prd-20260424T054936Z True     Latest image tag for 398879295738.dkr.ecr.us-west-2.amazonaws.com/consumer resolved to prd-20260424T054936Z
imagepolicy/payments-image-policy       398879295738.dkr.ecr.us-west-2.amazonaws.com/payments   prd-20260424T054919Z True     Latest image tag for 398879295738.dkr.ecr.us-west-2.amazonaws.com/payments resolved to prd-20260424T054919Z
imagepolicy/producer-image-policy       398879295738.dkr.ecr.us-west-2.amazonaws.com/producer   prd-20260424T054956Z True     Latest image tag for 398879295738.dkr.ecr.us-west-2.amazonaws.com/producer resolved to prd-20260424T054956Z

NAME                                                            LAST RUN                SUSPENDED       READY   MESSAGE               
imageupdateautomation/consumer-update-automation-pooled-envs    2026-04-26T17:02:20Z    False           True    repository up-to-date
imageupdateautomation/consumer-update-automation-tenants        2026-04-26T17:04:06Z    False           True    repository up-to-date
imageupdateautomation/payments-update-automation-pooled-envs    2026-04-26T17:02:20Z    False           True    repository up-to-date
imageupdateautomation/payments-update-automation-tenants        2026-04-26T17:04:06Z    False           True    repository up-to-date
imageupdateautomation/producer-update-automation-pooled-envs    2026-04-26T17:02:20Z    False           True    repository up-to-date
imageupdateautomation/producer-update-automation-tenants        2026-04-26T17:04:07Z    False           True    repository up-to-date

NAME                                            REVISION        SUSPENDED       READY   MESSAGE                                                                                                                     
helmrelease/argo-events                         2.4.3           False           True    Helm install succeeded for release argo-events/argo-events.v1 with chart argo-events@2.4.3                                 
helmrelease/argo-workflows                      0.40.11         False           True    Helm install succeeded for release argo-workflows/argo-workflows.v1 with chart argo-workflows@0.40.11                      
helmrelease/aws-load-balancer-controller        1.6.2           False           True    Helm install succeeded for release aws-system/aws-load-balancer-controller.v1 with chart aws-load-balancer-controller@1.6.2
helmrelease/karpenter                           1.4.0           False           True    Helm install succeeded for release karpenter/karpenter.v1 with chart karpenter@1.4.0                                       
helmrelease/kubecost                            2.1.0           False           True    Helm install succeeded for release kubecost/kubecost.v1 with chart cost-analyzer@2.1.0                                     
helmrelease/metrics-server                      3.11.0          False           True    Helm install succeeded for release kube-system/metrics-server.v1 with chart metrics-server@3.11.0                          
helmrelease/onboarding-service                  0.0.1           False           True    Helm install succeeded for release onboarding-service/onboarding-service.v1 with chart application-chart@0.0.1             
helmrelease/pool-1                              0.0.1           False           True    Helm upgrade succeeded for release pool-1/pool-1.v2 with chart helm-tenant-chart@0.0.1                                     
helmrelease/tf-controller                       0.16.0-rc.4     False           True    Helm install succeeded for release flux-system/tf-controller.v1 with chart tf-controller@0.16.0-rc.4                       

NAME                                    REVISION                        SUSPENDED       READY   MESSAGE                                         
kustomization/capacitor                 v0.4.8@sha256:1efcb443          False           True    Applied revision: v0.4.8@sha256:1efcb443       
kustomization/controlplane              refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83
kustomization/dataplane-pooled-envs     refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83
kustomization/dataplane-tenants         refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83
kustomization/dependencies              refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83
kustomization/flux-system               refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83
kustomization/infrastructure            refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83
kustomization/sources                   refs/heads/main@sha1:83debf83   False           True    Applied revision: refs/heads/main@sha1:83debf83

[ec2-user@ip-10-0-1-79 environment]$

위 리소스 들을 아래와 같이 한번 살펴봅시다.

 

1) Git/OCI Repository (소스 감시 대상)

gitrepository/flux-system : Gitea GitOps 저장소 (main 브랜치) 감시 중
gitrepository/terraform-v0-0-1 : Terraform 모듈 저장소 (v0.0.1 태그) 감시 중
ocirepository/capacitor : Flux UI 도구 (OCI 이미지) 감시 중

 

2) Helm Repository (차트 저장소)

helmrepository/argo : Argo Workflows/Events 차트
helmrepository/karpenter : Karpenter 차트
helmrepository/kubecost : 비용 모니터링 차트
helmrepository/tf-controller : Tofu Controller 차트
helmrepository/helm-application-chart : onboarding-service용 차트 (ECR OCI)
helmrepository/helm-tenant-chart : pool-1 테넌트용 차트 (ECR OCI)

 

3) Image Repository + Policy (이미지 자동 업데이트)

imagerepository/producer-image-repository : ECR의 producer 이미지 태그 스캔 중
imagerepository/consumer-image-repository : ECR의 consumer 이미지 태그 스캔 중
imagerepository/payments-image-repository : ECR의 payments 이미지 태그 스캔 중

그리고 이미지 뒤에 태그가 붙어있는데요, Flux가 ECR을 주기적으로 스캔해서 새 이미지 태그가 올라오면

자동으로 감지합니다. 'prd-YYYYMMDDTHHmmssZ' 형식이 태그 네이밍 규칙이에요.

Gitea Actions가 빌드 후 이 형식으로 태그를 붙여서 ECR에 올리는 것입니다 !

 

4) Image Update Automation (자동 배포 트리거)

imageupdateautomation/producer-update-automation-pooled-envs : pool 환경용
imageupdateautomation/producer-update-automation-tenants : silo 환경용

(consumer, payments도 동일한 구조)

 

흐름으로 본다면 아래와 같습니다.

Gitea Actions → ECR에 새 이미지 Push (prd-새타임스탬프)
      ↓
Flux ImageRepository가 새 태그 감지
      ↓
ImagePolicy가 최신 태그 결정
      ↓
ImageUpdateAutomation이 Gitea GitOps Repo의
values.yaml 이미지 태그를 자동으로 수정 + commit
      ↓
Flux GitRepository가 변경 감지
      ↓
HelmRelease Reconcile → 새 이미지로 롤링 업데이트

개발자가 코드만 Push하면 ECR → Gitea → EKS 배포까지 자동으로 배포됩니다.

 

6) Kustomization (GitOps 구조 계층)

kustomization/flux-system : Flux 자체 부트스트랩
kustomization/sources : Git/Helm 저장소 정의
kustomization/dependencies : 의존성 순서 관리
kustomization/infrastructure : Karpenter, LBC 등 인프라
kustomization/controlplane : onboarding-service 등 플랫폼 서비스
kustomization/dataplane-pooled-envs : pool-1 같은 공유 환경
kustomization/dataplane-tenants : silo 테넌트 환경
kustomization/capacitor : flux UI

 

Gitea 저장소 접근 설정

이번 워크숍에서는 Gitea 서버에 호스팅된 여러 저장소에 접근하여 클론해야 합니다.

먼저 이러한 저장소에 대한 접근 권한을 설정해 보겠습니다.

 

먼저 웹 인터페이스 접속을 위한 Gitea URL과 관리자 자격 증명을 가져오겠습니다.

# Get Gitea IPs from the configuration
export GITEA_PRIVATE_IP=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.gitea_url}')
export GITEA_PUBLIC_IP=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.gitea_public_url}')
export GITEA_PORT="3000"

# Get Gitea admin password from Systems Manager Parameter Store
export GITEA_ADMIN_PASSWORD=$(aws ssm get-parameter --name "/eks-saas-gitops/gitea-admin-password" --with-decryption --query 'Parameter.Value' --output text)

# Display access information for web browser login
echo "=== Gitea Web Interface Access ==="
echo "Public URL (for browser access): $GITEA_PUBLIC_IP"
echo "Username: admin"
echo "Password: $GITEA_ADMIN_PASSWORD"
echo "=================================="
echo ""
echo "Use the PUBLIC URL above to access Gitea from your web browser."

 

저장소 접근 변수 설정

ConfigMap에서 필요한 값을 추출하고 환경을 설정해봅시다.

# Extract Gitea configuration from ConfigMap
export GITEA_TOKEN=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.gitea_token}')
# Set up the repository paths used throughout the workshop
export REPO_PATH="/home/ec2-user/environment/microservice-repos"
export GITOPS_REPO_PATH="/home/ec2-user/environment/gitops-gitea-repo"
mkdir -p $REPO_PATH

 

필요한 저장소 복제

워크숍 동안 사용할 저장소를 복제해볼까요 ?

cd $REPO_PATH

# Clone the microservice repositories
git clone http://admin:${GITEA_TOKEN}@${GITEA_PRIVATE_IP}:${GITEA_PORT}/admin/producer.git
git clone http://admin:${GITEA_TOKEN}@${GITEA_PRIVATE_IP}:${GITEA_PORT}/admin/consumer.git
git clone http://admin:${GITEA_TOKEN}@${GITEA_PRIVATE_IP}:${GITEA_PORT}/admin/payments.git
tree
├── consumer
│   ├── Dockerfile
│   ├── consumer.py
│   └── requirements.txt
├── payments
│   ├── Dockerfile
│   ├── payments.py
│   └── requirements.txt
└── producer
    ├── Dockerfile
    ├── producer.py
    └── requirements.txt

# Verify the repositories were cloned successfully
echo "Microservice repositories:"
ls -la $REPO_PATH
echo ""
echo "GitOps repository:"
ls -la $GITOPS_REPO_PATH

 

Flux 저장소 구성 확인

Flux는 Gitea 저장소의 변경 사항을 감시하고 클러스터 상태와 일치시키도록 구성되어 있습니다.

Flux가 모니터링하는 gitops 저장소 위치를 확인하려면 다음 명령을 실행하세요.

Check : flux-system과 terraform-v0-0-1 두 레포지토리가 READY=TRUE 상태인지 확인.

 

Terraform 및 OpenTofu 컨트롤러

이번 Lab에서는 Terraform 모듈 구조를 이해하고, Tofu Controller를 통해 GitOps 방식으로

AWS 인프라를 자동 프로비저닝하는 흐름을 직접 실습합니다.

 

핵심 흐름은 아래와 같아요

Git에 Terraform CRD 파일 Push
        ↓
Flux가 변경 감지
        ↓
Tofu Controller가 tf-runner Pod 실행
        ↓
terraform apply → AWS 리소스 생성 (DynamoDB, SQS)

 

애플리케이션 인프라는 Terraform 모듈로 정의되어 있으며, GitOps 저장소의 다음 경로에 위치한다.

gitops-gitea-repo/terraform/modules/

 

모듈 구성은 아래와 같아요.

modules/
├── flux_cd          # EKS에 Flux를 설치하는 데 필요한 리소스
├── gitea            # Gitea 저장소에 필요한 리소스
├── gitops-saas-infra # 워크숍 전체 인프라 구성 리소스
└── tenant-apps      # 테넌트 애플리케이션 인프라 구성 요소
    ├── data.tf
    ├── main.tf
    ├── outputs.tf
    ├── README.md
    ├── variables.tf
    └── versions.tf

 

각 모듈 역할

모듈 역할
flux_cd EKS 클러스터에 Flux v2 설치에 필요한 리소스 정의
gitea 내부 Git 서버(Gitea) 구성에 필요한 리소스 정의
gitops-saas-infra 워크숍 전체 기반 인프라 구성
tenant-apps 테넌트 온보딩 시 생성되는 AWS 리소스 정의 (SQS, DynamoDB, IRSA 등)

 

Terraform Aggregated Module 패턴

이 워크숍에서는 Aggregated Module 패턴을 사용합니다. 사용자는 최상위 모듈 하나만 호출하면,

내부적으로 여러 하위 모듈과 리소스가 자동으로 구성됩니다.

users
  ↓
Terraform Aggregated Module (tenant-apps)
  ├─ Terraform Module → Resource, Resource, Resource
  └─ Terraform Module → Resource, Resource, Resource

이를 통해 복잡한 테넌트 인프라를 단일 모듈 호출로 추상화할 수 있어요.

 

tenant-apps 모듈 직접 테스트

tenant-apps 모듈에는 새 테넌트를 플랫폼에 온보딩하는 데 필요한 모든 인프라 구성 요소가 포함되어 있습니다.

SQS 큐, DynamoDB 테이블, IRSA 등 Producer/Consumer 앱이 사용하는 리소스들이 이 모듈에서 정의된다.

cd /home/ec2-user/environment/gitops-gitea-repo/

# 테스트용 Terraform 파일 생성
cat << EOF > terraform_test.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.100.0"
    }
  }
}

provider "aws" {}

module "test_tenant_apps" {
  source          = "./terraform/modules/tenant-apps"
  tenant_id       = "test"
  enable_producer = true
  enable_consumer = true
}
EOF

 

terraform init & plan 후 결과를 보면 enable_producer = true, enable_consumer = true 설정 시

11개의 리소스가 생성될 예정임을 확인할 수 있다.

 

enable_producer = false로 변경 후 비교

 

cat << EOF > terraform_test.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.100.0"
    }
  }
}

provider "aws" {}

module "test_tenant_apps" {
  source          = "./terraform/modules/tenant-apps"
  tenant_id       = "test"
  enable_producer = false
  enable_consumer = true
}
EOF

terraform plan

terraform init & plan 후 결과 : enable_producer = false로 설정하면 Producer 관련 리소스가 제외되어 생성

리소스 수가 줄어듭니다. 이처럼 변수 하나로 배포되는 리소스 범위를 제어할 수 있는 것이 모듈의 핵심 장점이에요.

 

Tofu Controller 통합

로컬에서 terraform apply를 직접 실행하는 것과 달리, 이 아키텍처에서는 EKS Pod 안에서

Terraform이 실행된다. 이를 가능하게 하는 것이 Tofu Controller입니다.

 

Tofu Controller는 Terraform CRD(Custom Resource Definition) 라는

쿠버네티스 사용자 정의 리소스를 사용하여 Terraform 모듈을 클러스터 내부에서 실행합니다.

 

Tofu Controller 동작 흐름

① Flux → Git 저장소(Terraform CRD, Terraform Module) Watch
② Flux → Terraform CRD 클러스터에 생성
③ TF Controller → flux-system namespace의 Terraform CRD 모니터링
④ TF Controller → tf-runner Pod 실행
⑤ tf-runner Pod → AWS 리소스 프로비저닝 (SQS, DynamoDB)
⑥ 실행 결과(tfstate, tfplan) → Kubernetes Secret으로 저장

 

각 단계를 다이어그램으로 상세히 설명하자면, 아래와 같습니다.

 

1) Flux가 Git 저장소를 감시 : Terraform CRD 정의 파일과 Terraform 모듈이 포함된 저장소를 지속적으로 모니터링한다.

2) Terraform CRD 생성: Git 저장소에 Terraform CRD 리소스가 추가되면 Flux가 감지하고 클러스터에 해당 CRD를 생성한다.

3) TF Controller가 CRD 모니터링: flux-system 네임스페이스에서 Terraform CRD를 Watch하다가 새 항목이 감지되면 동작을 시작한다.

4) tf-runner Pod 실행: TF Controller가 tf-runner Pod를 실행한다. 이 Pod가 Git 저장소에서 지정된 Terraform 모듈을 가져와 실행한다.

5) AWS 리소스 프로비저닝: tf-runner Pod가 terraform apply를 실행하여 Amazon SQS, Amazon DynamoDB 등을 생성한다.

6) 상태 저장: Terraform 실행 결과(tfstate, tfplan)를 Kubernetes Secret에 저장하여 후속 작업에서 활용할 수 있게 한다.

 

Tofu Controller Pod 확인

$ kubectl get pod -n flux-system

NAME                                    READY   STATUS    RESTARTS       AGE
capacitor-76b57ffc6f-2w92w              1/1     Running   1 (131m ago)   159m
helm-controller-6fbc6bbbc9-7pfpz        1/1     Running   0              160m
kustomize-controller-9db49689-jdlt6     1/1     Running   0              160m
notification-controller-86d4b4cd45-m72lt 1/1   Running   0              160m
source-controller-cfb87bd97-57mhs       1/1     Running   0              160m
tf-controller-cf8b957d7-dvqk7           1/1     Running   0              159m  ← Tofu Controller

tf-controller Pod가 정상 실행 중임을 확인할 수 있다.

 

Terraform CRD를 통한 GitOps 배포

이제 실제로 Terraform CRD를 Git에 올려서 GitOps 방식으로 AWS 리소스를 프로비저닝해본다.

 

1) Terraform CRD 파일 생성

cat << EOF > /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/example-tenant-terraform-crd.yaml
---
apiVersion: infra.contrib.fluxcd.io/v1alpha2
kind: Terraform
metadata:
  name: example-tenant
  namespace: flux-system
spec:
  path: ./terraform/modules/tenant-apps
  interval: 1m
  approvePlan: auto
  destroyResourcesOnDeletion: true
  sourceRef:
    kind: GitRepository
    name: terraform-v0-0-1
  vars:
    - name: tenant_id
      value: example-tenant
    - name: "enable_producer"
      value: true
    - name: "enable_consumer"
      value: true
  writeOutputsToSecret:
    name: example-tenant-infra-output
EOF

 

주요 필드를 아래 표와 같이 설명 드리겠습니다.

filed describtion
kind: Terraform Tofu Controller가 인식하는 CRD 종류
path 실행할 Terraform 모듈 경로
interval: 1m 1분마다 Reconcile 실행
approvePlan: auto plan 결과 자동 승인 후 apply
destroyResourcesOnDeletion: true CRD 삭제 시 생성된 AWS 리소스도 함께 삭제
sourceRef Terraform 코드를 가져올 Git 저장소 (terraform-v0-0-1 태그)
vars Terraform 변수 주입
writeOutputsToSecret Terraform output을 Kubernetes Secret에 저장

 

sourceRef: terraform-v0-0-1 이란?

terraform-v0-0-1은 Flux의 GitRepository 리소스로,

Gitea의 eks-saas-gitops.git 저장소의 v0.0.1 태그를 참조한다.

kubectl get GitRepository terraform-v0-0-1 -n flux-system -o yaml | grep -i spec -C10

spec:
  interval: 300s
  ref:
    tag: v0.0.1        # 브랜치가 아닌 태그 기준으로 감시
  url: http://10.35.48.243:3000/admin/eks-saas-gitops.git

Terraform 모듈은 태그(v0.0.1) 기준으로 고정되어 있어,

main 브랜치의 변경에 영향받지 않고 검증된 버전의 모듈만 사용된다.

git tag
# v0.0.1 확인

 

2) kustomization.yaml에 CRD 참조 추가

Flux가 새로 만든 CRD 파일을 인식하려면 kustomization.yaml에 참조를 추가해야 합니다.

cat << EOF > /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - basic
  - advanced
  - premium
  - example-tenant-terraform-crd.yaml
EOF

 

3) Git Push

cd /home/ec2-user/environment/gitops-gitea-repo/
git pull origin main
git status
git add .
git commit -am "Added example terraform CRD for testing"
git push origin main

 

4) Flux Reconcile 강제 실행 (선택)

폴링 주기를 기다리지 않고 즉시 반영하려면:

flux reconcile source git flux-system

 

5) tf-runner Pod 및 AWS 리소스 확인

잠시 후 tf-runner Pod가 생성되어 Terraform을 실행한다.

# tf-runner Pod 확인
kubectl get pod -n flux-system

# tf-runner 로그 실시간 확인
kubectl logs pod/example-tenant-tf-runner -n flux-system -f

# DynamoDB 테이블 생성 확인
# consumer-example-tenant- 접두사의 테이블이 생성되어 있어야 함
aws dynamodb list-tables

# SQS 큐 생성 확인
# consumer-example-tenant- 접두사의 SQS 큐가 생성되어 있어야 함
aws sqs list-queues

 

📌 Terraform CRD 삭제 (리소스 정리)

GitOps의 핵심 원칙대로, 리소스를 삭제할 때도 Git에서 CRD를 제거하기만 하면 됩니다.

destroyResourcesOnDeletion: true 설정 덕분에 CRD가 삭제되면 생성된 AWS 리소스도 자동으로 삭제된다.

 

1) CRD 파일 삭제

rm /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/example-tenant-terraform-crd.yaml

 

2) kustomization.yaml에서 참조 제거

cat << EOF > /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - basic
  - advanced
  - premium
EOF

 

3) Git Push

cd /home/ec2-user/environment/gitops-gitea-repo/
git pull origin main
git add .
git commit -m "Removed Terraform CRD and reference from kustomization.yaml"
git push origin main

 

4). Flux Reconcile 및 리소스 삭제 확인

flux reconcile source git flux-system

# tf-runner의 terraform destroy 로그 확인
kubectl logs po/example-tenant-tf-runner -n flux-system -f

# AWS 리소스 삭제 확인
aws dynamodb list-tables
aws sqs list-queues

 

* 참고 : terraform apply, plan 실행 결과 내용이 Secret에 저장됩니다.

kubectl get secret -n flux-system | grep -E 'tfplan|tfstate'
tfplan-default-example-tenant              Opaque                                1      6m2s
tfplan-default-pool-1                      Opaque                                1      11s
tfstate-default-example-tenant             Opaque                                1      6m54s
tfstate-default-pool-1                     Opaque                                1      70m

 

📌 결론

이번 Lab에서 확인한 핵심 포인트를 정리하면 아래와 같습니다:

항목 내용
Terraform 모듈화 tenant-apps 모듈 하나로 테넌트 인프라 전체를 추상화
변수 기반 제어 enable_producer, enable_consumer 변수로 배포 범위 조절
Tofu Controller EKS Pod 안에서 terraform apply/destroy 자동 실행
GitOps 연동 Git에 CRD 추가 → 자동 생성 / CRD 삭제 → 자동 삭제
상태 관리 tfstate를 Kubernetes Secret으로 관리

 


 

03. Helm Chart

Helm 차트는 Kubernetes 애플리케이션을 정의, 설치, 관리하는 패키징 도구입니다.

 

이 워크숍에서 사용하는 Helm 차트의 구조를 이해하고, helm template 명령어로 실제 배포 없이

렌더링 결과를 미리 확인하는 방법을 실습합니다.

 

📌 Helm Chart란?

Helm 차트는 서로 관련된 Kubernetes 리소스 세트를 하나의 패키지로 묶은 것입니다.

예를 들어 Producer 앱 하나를 배포하려면 Deployment, Service, Ingress, HPA, ServiceAccount 등

여러 YAML 파일이 필요한데, Helm은 이것들을 하나의 차트로 묶어서 관리한다.

 

차트 기본 구조:

Chart.yaml          # 차트 이름, 버전, 설명 등 메타데이터
values.yaml         # 템플릿에서 사용하는 기본값 정의
charts/             # 이 차트가 의존하는 하위 차트 디렉토리
templates/          # 실제 Kubernetes 매니페스트 템플릿 파일들
├── deployment.yaml
├── service.yaml
├── ingress.yaml
├── hpa.yaml
├── serviceaccount.yaml
├── terraform.yaml
└── ...

Chart.yaml : 차트 이름, 버전, 설명 등 메타데이터

values.yaml : 템플릿 변수의 기본값. 배포 시 재정의 가능

charts/ : 이 차트가 의존하는 서브 차트 모음

templates/ : values.yaml의 값과 결합되어 최종 Kubernetes YAML을 생성하는 템플릿

 

Helm이 있을때와 없을때의 차이점은 뭘까요 ?

[Helm 없이]
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml
... (파일마다 반복)

테넌트가 100개면 → 100세트의 YAML을 수동 관리

[Helm 사용]
helm install tenant-a ./helm-tenant-chart --values tenant-a-values.yaml
helm install tenant-b ./helm-tenant-chart --values tenant-b-values.yaml

→ 동일한 차트 + 테넌트별 values만 다르게 주입

 

★ 이 워크숍에서 사용하는 Helm 차트 2가지 입니다!

 

1) 테넌트 애플리케이션용 Helm 차트 (helm-tenant-chart)

여러 서비스(Producer, Consumer)를 단일 설치로 결합하여 테넌트별 애플리케이션을 배포합니다.

테넌트가 새로 생길 때마다 이 차트를 values.yaml만 다르게 해서 배포하는 구조다.

helm-tenant-chart/
├── Chart.yaml
├── values.yaml
└── templates/
    ├── deployment.yaml    # Producer/Consumer Deployment
    ├── service.yaml       # 서비스 엔드포인트
    ├── ingress.yaml       # 외부 트래픽 라우팅
    ├── hpa.yaml           # 오토스케일링 설정
    ├── serviceaccount.yaml # IRSA용 ServiceAccount
    ├── terraform.yaml     # Tofu Controller용 Terraform CRD 템플릿
    └── ...

 

2) 애플리케이션 연결 표(application-chart)

애플리케이션과 1:1로 대응하며, 테넌트별로 구분되지 않는 공유 서비스용 차트입니다.

onboarding-service 같은 플랫폼 공통 서비스가 이 차트로 배포된다.

 

values.yaml - 차트의 핵심 설정 파일

values.yaml은 템플릿에서 사용되는 변수의 기본값을 정의합니다.

배포 시 이 파일을 재정의하면 동일한 차트로 서로 다른 구성을 배포할 수 있다.

 

최소 values.yaml example:

tenantId: "example-tenant"

apps:
  producer:
    enabled: true

  consumer:
    enabled: true

핵심 개념: values.yaml을 최소한으로 작성한다는 것은, 일부 변수만 재정의하고 나머지는 차트에 정의된 기본값을

그대로 사용한다는 의미입니다. 모든 옵션을 다시 정의할 필요 없이 필요한 값만 오버라이드할 수 있다.

차트 기본 values.yaml (전체 설정)
        +
테넌트별 values.yaml (재정의할 값만)
        ↓
최종 렌더링 결과 (두 파일이 Merge됨)

 

helm template - 배포 없이 렌더링 결과 미리 확인

helm template 명령어는 실제로 클러스터에 배포하지 않고 Kubernetes 매니페스트를 터미널에 출력해준다.

배포 전에 어떤 YAML이 생성될지 미리 검증할 수 있습니다.

 

1) 테스트용 values.yaml 생성

cat << EOF > /home/ec2-user/environment/gitops-gitea-repo/helm-charts/helm-tenant-chart/test-values.yaml
tenantId: "example-tenant"

apps:
  producer:
    enabled: true

  consumer:
    enabled: true
EOF

 

2) helm template 실행 (Producer + Consumer 모두 활성화)

cd /home/ec2-user/environment/gitops-gitea-repo

helm template example-tenant ./helm-charts/helm-tenant-chart \
  --values ./helm-charts/helm-tenant-chart/test-values.yaml

producer와 consumer 서비스 모두에 대한 Kubernetes 리소

(Deployment, Service, Ingress, HPA 등)가 터미널에 출력된다.

 

3) producer 비활성화 후 비교

cat << EOF > /home/ec2-user/environment/gitops-gitea-repo/helm-charts/helm-tenant-chart/test-values.yaml
tenantId: "example-tenant"

apps:
  producer:
    enabled: false   # ← false로 변경

  consumer:
    enabled: true
EOF

helm template example-tenant ./helm-charts/helm-tenant-chart \
  --values ./helm-charts/helm-tenant-chart/test-values.yaml

주목할 점: producer.enabled: false로 설정해도 Producer로 향하는 Service(경로)는 계속 생성된다.

 

왜 계속 생성될까요 ?

특정 테넌트의 Producer가 비활성화된 경우
        ↓
요청을 "pooled producer" (공유 Producer)로 라우팅해야 함
        ↓
그 라우팅 경로(Service)는 Deployment 없이도 필요함

즉, 이것은 Helm 차트가 계층형(Tiered) 접근 방식을 구현한 것입니다.

 

테넌트가 전용 Producer를 갖지 않더라도, 공유(Pool) Producer로 요청을

자연스럽게 넘길 수 있도록 Service 경로는 항상 유지된다.

 

Terraform과 Helm의 역할 비교

이 시점에서 앞서 다룬 Terraform 모듈과 Helm 차트의 역할을 명확히 구분해두자.

구분 Terraform module Helm chart
대상 AWS 리소스 Kubernetes 리소스
생성하는 것 DynamoDB, SQS, IAM Role Deployment, Service, Ingress, HPA
변수 제어 enable_producer = true/false apps.producer.enabled: true/false
실행 주체 Tofu Controller (tf-runner Pod) Flux HelmRelease
저장 위치 Gitea GitOps Repo (Terraform CRD) Gitea GitOps Repo (HelmRelease)

테넌트 온보딩 시 이 둘이 함께 동작한다:

Git에 테넌트 설정 Push
        ↓
Flux 감지
        ├─ HelmRelease → Helm 차트 배포 → Deployment, Service, Ingress, HPA 생성
        └─ Terraform CRD → Tofu Controller → DynamoDB, SQS 생성

 


 

04. Helm 차트와 Flux 통합하기

앞선 섹션에서 helm template으로 차트를 로컬에서 검증했다면, 이번 섹션에서는

HelmRelease CRD를 사용하여 Flux가 Helm 배포를 자동으로 관리하도록 통합합니다.

 

핵심 흐름은 아래와 같습니다.

Helm 차트 → ECR에 OCI 이미지로 패키징 & Push
        ↓
Git에 HelmRelease YAML 파일 추가
        ↓
Flux가 감지 → HelmRelease 생성
        ↓
Flux가 ECR에서 차트를 Pull → helm install 자동 실행
        ↓
example-tenant Namespace에 Producer/Consumer 배포

 

Helm 차트가 이미 ECR에 있는지 확인

HelmRelease를 만들기 전에, 먼저 Helm 차트가 이미 ECR에 패키징되어 있는지 확인한다.

# ConfigMap에서 ECR 정보 가져오기
AWS_ACCOUNT_ID=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.account_id}')
ECR_HELM_CHART_URL=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.ecr_helm_chart_url}')
ECR_REGISTRY=$(echo $ECR_HELM_CHART_URL | cut -d'/' -f1)
ECR_REPOSITORY=$(echo $ECR_HELM_CHART_URL | cut -d'/' -f2-)
AWS_REGION=$(echo $ECR_HELM_CHART_URL | cut -d'.' -f4)

# Docker를 ECR에 인증
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY

# ECR에 올라간 이미지(차트) 목록 확인
aws ecr list-images --repository-name $ECR_REPOSITORY --region $AWS_REGION

 

확인 결과:

{
    "imageIds": [
        {
            "imageDigest": "sha256:158069159914...",
            "imageTag": "0.0.1"
        }
    ]
}

0.0.1 태그로 Helm 차트가 이미 ECR에 Push되어 있음을 확인할 수 있다.

 

Helm 차트를 ECR에 Push하는 방법 (참고)

워크숍 환경에는 이미 Push되어 있으므로 이 과정은 실행하지 않아도 된다. 실제 환경에서 차트를 업데이트할 때 사용하는 절차다.

 

1) 차트 패키징

cd $GITOPS_REPO_PATH/helm-charts/helm-tenant-chart

# .tgz 파일로 패키징
helm package . --version 0.0.1-test

 

2) 환경 변수 설정

AWS_ACCOUNT_ID=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.account_id}')
ECR_HELM_CHART_URL=$(kubectl get configmap saas-infra-outputs -n flux-system -o jsonpath='{.data.ecr_helm_chart_url}')
ECR_REGISTRY=$(echo $ECR_HELM_CHART_URL | cut -d'/' -f1)
ECR_REPOSITORY=$(echo $ECR_HELM_CHART_URL | cut -d'/' -f2-)
AWS_REGION=$(echo $ECR_HELM_CHART_URL | cut -d'.' -f4)

 

3) ECR 인증 후 Push

# ECR 로그인
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY

# OCI 형식으로 ECR에 Push
helm push ./helm-tenant-chart-0.0.1-test.tgz oci://$(echo $ECR_HELM_CHART_URL | cut -d'/' -f1)/gitops-saas

 

4) 업로드 확인

aws ecr list-images --repository-name $ECR_REPOSITORY --region $AWS_REGION

포인트: Helm 차트를 일반 컨테이너 이미지처럼 ECR에 OCI 이미지로 저장한다.

이렇게 하면 Flux의 HelmRepository가 ECR을 차트 저장소로 사용할 수 있습니다.

 

HelmRelease란?

HelmRelease는 Flux에서 제공하는 CRD로, Helm 릴리즈를 선언적으로 관리할 수 있게 해준다.

 

기존 방식과 비교해볼까요?

[기존 방식 - 직접 실행]
helm install example-tenant ./helm-tenant-chart --values values.yaml
→ 사람이 직접 실행, Git과 연동 안 됨

[HelmRelease GitOps 방식]
Git에 HelmRelease YAML 파일 추가
→ Flux가 감지 → 자동으로 helm install/upgrade 실행
→ 차트 버전 변경, values 변경도 Git Push만으로 반영

 

HelmRelease 예시 (example-tenant-premium)

apiVersion: v1
kind: Namespace
metadata:
  name: example-tenant
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: example-tenant-premium
  namespace: flux-system
spec:
  releaseName: example-tenant-premium
  targetNamespace: example-tenant     # 실제 앱이 배포될 Namespace
  storageNamespace: example-tenant    # Helm 릴리즈 메타데이터 저장 위치
  interval: 1m0s                      # 1분마다 Reconcile
  chart:
    spec:
      chart: helm-tenant-chart        # 사용할 차트 이름
      version: "0.x"                  # 0.x 버전 중 최신 사용
      sourceRef:
        kind: HelmRepository
        name: helm-tenant-chart       # ECR을 가리키는 HelmRepository
  values:
    tenantId: example-tenant
    apps:
      producer:
        enabled: true   # Silo 배포 - Premium 티어는 테넌트별 전용 Deployment
      consumer:
        enabled: true   # Silo 배포 - Premium 티어는 테넌트별 전용 Deployment

 

주요 필드를 아래 표와 같이 설명드리겠습니다.

filed describtion
targetNamespace 실제 Kubernetes 리소스(Deployment, Service 등)가 배포될 Namespace
storageNamespace Helm이 릴리즈 상태를 저장하는 Secret이 생성될 Namespace
interval: 1m0s Flux가 1분마다 Git과 실제 클러스터 상태를 비교하고 동기화
chart.spec.version: "0.x" 0.x 범위의 최신 차트를 자동으로 사용
(예: 0.0.2가 올라오면 자동 업그레이드)
sourceRef 차트를 가져올 저장소 - ECR을 가리키는 HelmRepository CRD 참조
values helm install --values와 동일. 테넌트별 설정값 주입

 

HelmRepository - ECR과의 연결

HelmRelease의 sourceRef가 가리키는 HelmRepository는

Flux가 Helm 차트를 가져오는 저장소 정보를 담고 있다.

kubectl get HelmRepository -n flux-system | grep -i helm-tenant-chart

출력 결과:

helm-tenant-chart    oci://123456789012.dkr.ecr.us-west-2.amazonaws.com/gitops-saas/

Helm 차트가 ECR에 OCI 형식으로 저장되어 있고, Flux의 HelmRepository가 이 ECR URL을 가리키고 있다.

HelmRelease → HelmRepository → ECR 순서로 차트를 가져오는 구조입니다.

HelmRelease
  └─ sourceRef: helm-tenant-chart (HelmRepository)
       └─ url: oci://123456789012.dkr.ecr.us-west-2.amazonaws.com/gitops-saas/
            └─ ECR에서 helm-tenant-chart:0.0.1 차트 Pull

 

HelmRelease 실제 배포 (GitOps 방식)

Step1. HelmRealse YAML 파일 생성

cat << EOF > /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/example-tenant-helmrelease.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: example-tenant
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: example-tenant-premium
  namespace: flux-system
spec:
  releaseName: example-tenant-premium
  targetNamespace: example-tenant
  storageNamespace: example-tenant
  interval: 1m0s
  chart:
    spec:
      chart: helm-tenant-chart
      version: "0.x"
      sourceRef:
        kind: HelmRepository
        name: helm-tenant-chart
  values:
    tenantId: example-tenant
    apps:
      producer:
        enabled: true   # Silo deployment -- premium tier has a dedicated deployment for each tenant
      consumer:
        enabled: true   # Silo deployment -- premium tier has a dedicated deployment for each tenant
EOF

 

Step2. kustomization.yaml에 HelmRelease 파일 추가

Flux가 새로 만든 HelmRelease 파일을 인식하려면 kustomization.yaml에 참조를 추가해야 한다.

cat << EOF >> /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/kustomization.yaml
    - example-tenant-helmrelease.yaml
EOF

 

Step3. Git Push

cd /home/ec2-user/environment/gitops-gitea-repo/
git pull origin main
git add .
git commit -m "Added HelmRelease for example-tenant"
git push origin main

 

Step4. Flux Reconcile 강제 실행

flux reconcile source git flux-system
참고: Flux가 HelmRelease와 Terraform CRD를 통합하고 리소스를 생성하는 데 다소 시간이 걸립니다.
tf-runner 로그로 진행 상황을 확인할 수 있다.
kubectl logs pod/example-tenant-tf-runner -n flux-system -f

 

📌 생성된 리소스 확인

 

1) Kubernetes 리소스 확인

# example-tenant Namespace 생성 확인
kubectl get namespaces

# Namespace 내 모든 리소스 확인
kubectl get all -n example-tenant

HelmRelease가 정상 배포되면 example-tenant Namespace에 다음 리소스들이 생성된다:

example-tenant namespace
├─ Deployment: example-tenant-premium-producer   ← Producer 앱
├─ Deployment: example-tenant-premium-consumer   ← Consumer 앱
├─ Service: producer / consumer
├─ Ingress: 외부 트래픽 라우팅
├─ HPA: 오토스케일링
└─ ServiceAccount: IRSA 연동용

 

2) AWS 리소스 확인

HelmRelease 안에 포함된 Terraform CRD 템플릿(terraform.yaml)에 의해

Tofu Controller가 AWS 리소스도 함께 프로비저닝한다.

# DynamoDB 테이블 확인
# example-tenant 접두사의 테이블이 생성되어 있어야 함
aws dynamodb list-tables

# SQS 큐 확인
# example-tenant 접두사의 큐가 생성되어 있어야 함
aws sqs list-queues

 

📌 리소스 정리

GitOps 방식에서 리소스 삭제도 Git에서 파일을 제거하는 것으로 처리된다.

 

1) HelmRelease 파일 삭제

rm /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/example-tenant-helmrelease.yaml

 

2) kustomization.yaml에서 참조 제거

sed -i '/example-tenant-helmrelease.yaml/d' \
  /home/ec2-user/environment/gitops-gitea-repo/application-plane/production/tenants/kustomization.yaml

 

3) Git Push

cd /home/ec2-user/environment/gitops-gitea-repo/
git pull origin main
git add .
git commit -m "Removed HelmRelease for example-tenant"
git push origin main

 

4) Flux Reconcile 및 삭제 확인

flux reconcile source git flux-system

# Kubernetes 리소스 삭제 확인
kubectl get namespaces
kubectl get all -n example-tenant

# AWS 리소스 삭제 확인
aws dynamodb list-tables
aws sqs list-queues

 

★ 중요 : 실제 테넌트 온보딩 시 이 두 가지가 동시에 동작합니다.

Git에 테넌트 설정 Push (HelmRelease + Terraform CRD)
        ↓
Flux Reconcile
        ├─ HelmRelease → Helm Controller → ECR에서 차트 Pull → helm install
        │    └─ example-tenant ns: Deployment, Service, Ingress, HPA 생성
        │
        └─ Terraform CRD → Tofu Controller → tf-runner Pod → terraform apply
             └─ AWS: DynamoDB 테이블, SQS 큐, IAM Role 생성

요약 하자면, 아래와 같습니다.

 


긴 글 읽어주셔서 감사합니다.

다음 Lab에서는 "SaaS 티어 전략"이라는 주제로 찾아뵙겠습니다.