본문 바로가기
Devops/CICD

ACK + Jenkins로 AWS 자동화작업

by 광진구뚝배기 2025. 6. 29.

Terraform 대신 ACK를 도입한 이유는 이전 글 "내가 ACK를 선택한 이유" 에 자세히 정리해두었다.
이번 글에서는 ACK와 Jenkins를 기반으로 GitOps 방식의 자동화 파이프라인을 구축하고

이를 통해 ACM, Route53, ALB, CloudFront, S3, Lambda, RDS, ECR 등 주요 AWS 리소스를 자동으로 생성·배포한 구조를 공유하려고 한다.

 

CSR 기반 단순 서비스 자동화 현황

내가 입사했을 당시, 일부 CSR 기반 기본 인프라 자동화가 이미 구축되어 있었다.
정적 파일을 S3에 올리고 CloudFront를 통해 서비스하는 단순한 구조에 한해, 아래 작업들이 자동으로 처리되고 있었다.

 

- ACM 인증서 생성

- Route53 DNS validation 레코드 생성

- CloudFront, S3 생성 및 원본경로 연결

 

하지만 실제 운영되는 서비스들은 대부분 CSR만으로는 부족했고 조금 더 복잡한 구성이 필요했다.

 

SSR / Backend 인프라 구조와 수작업 현황

 

Frontend 서비스는 CSR과 SSR 렌더링 서버가 혼합된 구조로 운영되고 있었다.
SSR 인프라는 기존 CSR 구조에 ALB, RDS, Kubernetes Pod 연결 등이 추가된 형태였다.

Backend 서비스는 ALB, RDS, ElastiCache(Redis) 등 다양한 AWS 자원을 활용하고 있었다.

 

이런 SSR 및 Backend 서비스들은 대부분 개발자가 레드마인 티켓을 통해 인프라를 요청하면,
내가 다음 작업들을 하나하나 수작업으로 처리해야 했다.

 

- ACM 인증서 검증 자동화 및 CloudFront 생성은 되어 있었으나, 오리진에 ALB 등록과 배포 경로 설정은 수동으로 진행

- 보안 그룹 생성 및 연결

- ALB 생성 및 구성

- Route53 alias 등록 (CloudFront연결은 자동화되어 있었으나, Backend용 ALB 연결은 직접 작업 필요)

- RDS 및 Redis 생성

 

자동화된 부분은 거의 없었으며, Jenkins 파이프라인으로 ECR 생성과 코드 배포만 자동화되어 있었다.

 

자동화가 꼭 필요했던 이유

수작업 부담
인프라 담당자가 나 혼자라서, 매번 인프라를 직접 만들고 관리하는 데 개발 리소스가 부족했다.

관리 복잡도
서비스별 구성과 기록이 흩어져 있어 관리가 어려웠고, 사용하지 않는 리소스가 쌓여 자원 관리가 제대로 되지 않았다.

CSR 자동화 확장성 한계
CSR만을 위한 전용 로직이라 범용성이 떨어져, 다른 서비스 유형에 적용하기 어려웠다.

 

이런 이유들 때문에, CSR, SSR, Backend 등 모든 서비스 유형을 아우를 수 있는 범용 자동화 파이프라인을 새로 구축하기로 결심했다.

 

구조 재설계 방향

기존 CSR 파이프라인은 너무 특화되어 있었고, 사용된 Custom Controller들도 기능별로 나누어져 따로따로 운영되고 있었다.

예를 들면,

 

- ACM 생성 시 Route53 validation 레코드 생성하는 컨트롤러

- ACM 발급 완료 후 CloudFront에 인증서 ARN 업데이트하는 컨트롤러

- CloudFront 생성 완료 후 Route53 alias 등록하는 컨트롤러

 

기능별로 쪼개져 있어서 디버깅, 배포, CRD 관리가 분산됐고, SSR/Backend 서비스에 필요한 추가 기능을 넣기도 불편했다.

 

통합 Custom Controller 기반 API 구조 재설계

 

kubebuilder를 활용해 단일 Custom Controller 프로젝트를 새로 만들고, 여러 서비스 유형에 대응할 수 있도록 복수 API(Group/Kind)를 포함하는 구조로 재설계했다.

 

단일 Custom Controller 프로젝트

certificate, distribution, loadbalancer, lambda 등 여러 AWS 리소스별 Reconciler를 하나의 프로젝트 내에 정의하여 관리

Jenkins 파이프라인

config 레포에서 인프라용 Kubernetes YAML을 생성하고, 이를 ACK 컨트롤러를 통해 Kubernetes 클러스터에 배포

ACK 컨트롤러

배포된 Resource를 감지하여 AWS 리소스를 자동으로 생성하고 관리

컨트롤러 내부 처리

ACK에서 아직 지원하지 않는 기능들을 직접 추가 개발하여 보완

로그 레벨을 구분하고, log.WithValues() 기반의 구조화된 로그를 사용하여 운영 편의성 향상

 

결과


이 구조로 완전히 재설계한 이후부터는 CSR, SSR, Backend 모든 서비스가 단일 Git 리소스 정의만으로 인프라 구성이 가능해졌다.
개발자는 config-repo에 YAML만 작성하면 Jenkins + ACK + Custom Controller가 전체 배포를 자동으로 처리해 내가 별도로 작업할 일이 거의 없어졌다.
또한 Git에서 리소스 사용 여부를 관리해서 자원 낭비도 훨씬 줄어들었다.

 

 

개발자는 이렇게 정의했다 - 실제 YAML 예시

 

실제 구현에 대한 자세한 내용은 별도 포스팅에서 다루기로 하고,
아래는 개발자가 config-repo에 작성하는 인프라 정의 YAML의 예시다.

 

# Jenkinsfile

#!groovy
/* groovylint-disable-next-line CompileStatic, NoDef, UnusedVariable, VariableName, VariableTypeRequired */
@Library('common-library') _

pipelineCodeConfig(
    defaultConfig: [
        createResource: true, // 생략 시 기본값은 false
        requestAWSResourcesPath: 'aws-resources', // 생략 시 기본 경로는 'request-aws-resources'
    ],
)

 

 

#  request-aws-resources.dev.yaml 

acm:
  certificate:
    domainName: "domain-sample.com"
    tags:
      - key: service-code
        value: "450"
      - key: service-name
        value: "450test"

route53:
  recordSet:
    name: "domain-sample.com"

elbv2:
  targetGroup:
    tags:
      - key: service-code
        value: "450"
      - key: service-name
        value: "450test"

  rule:
    domainName: "domain-sample.com"
    tags:
      - key: service-code
        value: "450"
      - key: service-name
        value: "450test"

cloudfront:
  distribution:
    distributionConfig:
      comment: "domain-sample.com"
    tags:
      - key: service-code
        value: "450"
      - key: service-name
        value: "450test"

s3:
  bucket:
    tags:
      - key: service-code
        value: "450"
      - key: service-name
        value: "450test"

 

 

 

댓글