본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 6장: 셀프서비스 인프라
2026년 3월 27일·인프라·

6장: 셀프서비스 인프라

셀프서비스의 핵심 원칙, GitOps 기반 인프라 요청, Crossplane을 활용한 Kubernetes 네이티브 인프라 추상화, 그리고 승인 워크플로우를 다룹니다.

14분790자7개 섹션
platform-engineeringdevopsinfrastructure
공유
platform-engineering6 / 10
12345678910
이전5장: Golden Path 설계와 구현다음7장: 플랫폼 API 설계

학습 목표

  • 셀프서비스 인프라의 핵심 원칙과 가드레일 개념을 이해합니다.
  • GitOps 기반 인프라 요청 워크플로우를 설계할 수 있습니다.
  • **Crossplane(크로스플레인)**을 활용한 Kubernetes 네이티브 인프라 추상화를 구현할 수 있습니다.
  • 리소스 유형별 승인 워크플로우를 설계할 수 있습니다.

셀프서비스의 원칙

셀프서비스 인프라의 목표는 개발자가 티켓 없이, 대기 없이 필요한 인프라를 직접 프로비저닝할 수 있도록 하는 것입니다. 단, 이 자율성에는 **가드레일(Guardrail)**이 함께해야 합니다.

자율성과 가드레일의 균형

가드레일의 핵심 원칙:

원칙설명예시
사전 정의된 선택지무한한 자유가 아닌, 검증된 옵션 제공DB 인스턴스: small, medium, large
기본값 최적화대부분의 경우 기본값이 적절하도록 설계스토리지 암호화 기본 활성화
비용 투명성리소스 생성 전 예상 비용 표시"이 DB의 월 예상 비용: 약 150 USD"
정책 자동 적용수동 검토 없이 정책 준수 보장퍼블릭 접근 차단, 태그 자동 부여
Info

셀프서비스는 "아무것이나 할 수 있다"가 아니라 "필요한 것을 빠르게 할 수 있다"를 의미합니다. 잘 설계된 가드레일은 개발자를 제한하는 것이 아니라, 실수로부터 보호하는 것입니다.


GitOps 기반 인프라 요청

**GitOps(깃옵스)**는 Git 저장소를 인프라의 단일 진실 소스(Single Source of Truth)로 사용하는 방식입니다. 인프라 변경을 Pull Request로 관리하면 이력 추적, 리뷰, 롤백이 자연스럽게 가능합니다.

인프라 요청 워크플로우

인프라 저장소 구조

infra-gitops 저장소 구조
text
infra-gitops/
  teams/
    checkout-team/
      dev/
        databases.yaml
        queues.yaml
        caches.yaml
      staging/
        databases.yaml
        queues.yaml
      production/
        databases.yaml
        queues.yaml
        caches.yaml
    auth-team/
      dev/
        databases.yaml
      staging/
        databases.yaml
      production/
        databases.yaml
  policies/
    cost-limits.rego
    security-baseline.rego
    naming-conventions.rego
  modules/
    rds-postgresql/
    elasticache-redis/
    sqs-queue/
    s3-bucket/

리소스 요청 파일 예시

teams/checkout-team/dev/databases.yaml
yaml
apiVersion: infra.mycompany.com/v1
kind: DatabaseRequest
metadata:
  name: checkout-db
  namespace: checkout-team
  labels:
    team: checkout-team
    environment: dev
    service: checkout-service
spec:
  engine: postgresql
  version: "16"
  size: small          # small: db.t4g.micro, medium: db.t4g.medium, large: db.t4g.large
  storage: 20          # GB
  backup:
    enabled: true
    retention: 7       # days
  monitoring:
    enabled: true
    alerts:
      - type: cpu
        threshold: 80
      - type: storage
        threshold: 85

Crossplane으로 Kubernetes 네이티브 인프라 관리

**Crossplane(크로스플레인)**은 Kubernetes를 범용 제어 평면(Control Plane)으로 확장하여, 클라우드 리소스를 Kubernetes 리소스처럼 관리할 수 있게 해주는 CNCF 프로젝트입니다.

왜 Crossplane인가

관점TerraformCrossplane
실행 방식CLI / CI에서 실행Kubernetes 컨트롤러
상태 관리tfstate 파일Kubernetes etcd
드리프트 감지수동 (terraform plan)자동 (지속적 조정)
셀프서비스API 래핑 필요kubectl / Backstage 연동
학습 곡선HCL 학습 필요YAML (Kubernetes 친숙)
조합 추상화모듈Composition(컴포지션)

Crossplane의 가장 큰 장점은 **Composition(컴포지션)**을 통한 인프라 추상화입니다. 복잡한 클라우드 리소스 조합을 단순한 Kubernetes 리소스로 추상화할 수 있습니다.

Crossplane 설치

Crossplane 설치
bash
# Helm으로 Crossplane 설치
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
 
helm install crossplane crossplane-stable/crossplane \
  --namespace crossplane-system \
  --create-namespace
 
# AWS Provider 설치
kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws
spec:
  package: xpkg.upbound.io/upbound/provider-family-aws:v1.15.0
EOF

Composite Resource Definition (XRD)

**XRD(Composite Resource Definition)**는 개발자에게 노출할 추상화된 리소스의 스키마를 정의합니다.

xrd-database.yaml
yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xdatabases.infra.mycompany.com
spec:
  group: infra.mycompany.com
  names:
    kind: XDatabase
    plural: xdatabases
  claimNames:
    kind: Database
    plural: databases
  versions:
    - name: v1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                engine:
                  type: string
                  enum: ["postgresql", "mysql"]
                  description: "데이터베이스 엔진"
                size:
                  type: string
                  enum: ["small", "medium", "large"]
                  description: "인스턴스 크기"
                  default: "small"
                storageGB:
                  type: integer
                  minimum: 20
                  maximum: 500
                  default: 20
                  description: "스토리지 크기 (GB)"
              required:
                - engine

Composition

**Composition(컴포지션)**은 추상화된 리소스가 실제 클라우드 리소스로 변환되는 규칙을 정의합니다.

composition-database-aws.yaml
yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-aws
  labels:
    provider: aws
    crossplane.io/xrd: xdatabases.infra.mycompany.com
spec:
  compositeTypeRef:
    apiVersion: infra.mycompany.com/v1
    kind: XDatabase
  resources:
    - name: rds-instance
      base:
        apiVersion: rds.aws.upbound.io/v1beta2
        kind: Instance
        spec:
          forProvider:
            region: ap-northeast-2
            instanceClass: db.t4g.micro
            allocatedStorage: 20
            storageEncrypted: true
            publiclyAccessible: false
            skipFinalSnapshot: false
            autoMinorVersionUpgrade: true
            backupRetentionPeriod: 7
            tags:
              ManagedBy: crossplane
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: "spec.engine"
          toFieldPath: "spec.forProvider.engine"
        - type: FromCompositeFieldPath
          fromFieldPath: "spec.storageGB"
          toFieldPath: "spec.forProvider.allocatedStorage"
        - type: FromCompositeFieldPath
          fromFieldPath: "spec.size"
          toFieldPath: "spec.forProvider.instanceClass"
          transforms:
            - type: map
              map:
                small: db.t4g.micro
                medium: db.t4g.medium
                large: db.t4g.large
 
    - name: security-group
      base:
        apiVersion: ec2.aws.upbound.io/v1beta1
        kind: SecurityGroup
        spec:
          forProvider:
            region: ap-northeast-2
            description: "Database security group"
            ingress:
              - fromPort: 5432
                toPort: 5432
                protocol: tcp
                cidrBlocks:
                  - "10.0.0.0/8"

개발자의 사용법

개발자는 복잡한 클라우드 리소스 세부사항을 알 필요 없이, 단순한 Claim 리소스를 작성합니다.

database-claim.yaml
yaml
apiVersion: infra.mycompany.com/v1
kind: Database
metadata:
  name: checkout-db
  namespace: checkout
spec:
  engine: postgresql
  size: small
  storageGB: 50

이 단순한 YAML 파일 하나로 RDS 인스턴스, 보안 그룹, 시크릿이 자동으로 생성됩니다.

Tip

Crossplane Composition은 환경별로 다르게 구성할 수 있습니다. dev 환경에서는 최소 사양으로, production에서는 Multi-AZ, 높은 백업 보존 기간 등을 자동 적용하도록 설계하세요.


환경 프로비저닝 자동화

새 서비스를 위한 전체 환경(네임스페이스, RBAC, 네트워크 정책, 시크릿 등)을 자동으로 프로비저닝합니다.

environment-template.yaml
yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: provision-environment
  title: "서비스 환경 프로비저닝"
  description: "새 서비스를 위한 Kubernetes 환경을 생성합니다."
spec:
  owner: group:default/platform-team
  type: environment
 
  parameters:
    - title: "환경 정보"
      required:
        - serviceName
        - environment
        - team
      properties:
        serviceName:
          title: "서비스 이름"
          type: string
        environment:
          title: "환경"
          type: string
          enum: ["dev", "staging", "production"]
        team:
          title: "소유 팀"
          type: string
          ui:field: OwnerPicker
 
  steps:
    - id: create-namespace
      name: "네임스페이스 생성"
      action: kubernetes:apply
      input:
        manifest:
          apiVersion: v1
          kind: Namespace
          metadata:
            name: "${{ parameters.serviceName }}-${{ parameters.environment }}"
            labels:
              team: "${{ parameters.team }}"
              environment: "${{ parameters.environment }}"
              istio-injection: "enabled"
 
    - id: create-resource-quota
      name: "리소스 쿼타 설정"
      action: kubernetes:apply
      input:
        manifest:
          apiVersion: v1
          kind: ResourceQuota
          metadata:
            name: default-quota
            namespace: "${{ parameters.serviceName }}-${{ parameters.environment }}"
          spec:
            hard:
              requests.cpu: "4"
              requests.memory: "8Gi"
              limits.cpu: "8"
              limits.memory: "16Gi"
              pods: "20"
 
    - id: create-network-policy
      name: "네트워크 정책 설정"
      action: kubernetes:apply
      input:
        manifest:
          apiVersion: networking.k8s.io/v1
          kind: NetworkPolicy
          metadata:
            name: default-deny-ingress
            namespace: "${{ parameters.serviceName }}-${{ parameters.environment }}"
          spec:
            podSelector: {}
            policyTypes:
              - Ingress
            ingress:
              - from:
                  - namespaceSelector:
                      matchLabels:
                        environment: "${{ parameters.environment }}"

승인 워크플로우

모든 인프라 요청이 자동 승인되어서는 안 됩니다. 리소스의 위험도와 비용에 따라 차등화된 승인 워크플로우를 적용합니다.

승인 정책

approval-policy.yaml
yaml
apiVersion: policy.mycompany.com/v1
kind: ApprovalPolicy
metadata:
  name: infrastructure-approval
spec:
  rules:
    - name: "자동 승인 (저위험)"
      conditions:
        environment: ["dev", "staging"]
        resourceType: ["namespace", "configmap", "secret"]
        estimatedMonthlyCost:
          lessThan: 50
      approval: auto
 
    - name: "팀 리드 승인 (중위험)"
      conditions:
        environment: ["production"]
        resourceType: ["database", "cache", "queue"]
        estimatedMonthlyCost:
          lessThan: 500
      approval:
        required: 1
        approvers:
          - role: team-lead
 
    - name: "플랫폼 팀 + 팀 리드 승인 (고위험)"
      conditions:
        estimatedMonthlyCost:
          greaterThanOrEqual: 500
      approval:
        required: 2
        approvers:
          - role: team-lead
          - role: platform-team
 
    - name: "CISO 승인 (보안 민감)"
      conditions:
        resourceType: ["iam-role", "vpc-peering", "public-endpoint"]
      approval:
        required: 1
        approvers:
          - role: security-team
Warning

승인 워크플로우는 보안과 속도의 균형을 맞추어야 합니다. 승인 단계가 너무 많으면 셀프서비스의 의미가 퇴색됩니다. 자동 승인의 범위를 최대한 넓히되, 고위험 작업에만 수동 승인을 적용하세요.


정리

이번 장에서는 셀프서비스 인프라의 설계와 구현을 다루었습니다.

  • 셀프서비스는 자율성과 가드레일의 균형이 핵심입니다.
  • GitOps 기반 워크플로우는 인프라 변경의 추적성, 리뷰, 롤백을 보장합니다.
  • Crossplane은 Kubernetes 네이티브 방식으로 클라우드 리소스를 추상화하며, 개발자에게 단순한 인터페이스를 제공합니다.
  • 리소스의 위험도와 비용에 따라 차등화된 승인 워크플로우를 적용합니다.

다음 장에서는 플랫폼 API 설계를 다룹니다. 플랫폼을 제품으로 바라보는 관점에서 API 계층을 설계하고, 추상화 수준을 결정하며, CLI 도구를 제공하는 방법을 살펴보겠습니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#platform-engineering#devops#infrastructure

관련 글

인프라

7장: 플랫폼 API 설계

Platform as a Product 관점에서의 API 계층 설계, 추상화 수준 결정, 내부 API 버전닝, 인증과 인가, 감사 로깅, 그리고 CLI 도구 제공까지 다룹니다.

2026년 3월 29일·14분
인프라

5장: Golden Path 설계와 구현

Golden Path의 정의와 철학, 옵셔널하되 매력적인 경로 설계, Terraform/Pulumi 기반 자동 인프라 프로비저닝, 그리고 80% 이상 자발적 채택률의 비결을 다룹니다.

2026년 3월 25일·19분
인프라

8장: 비용 가시성과 FinOps 통합

FinOps 원칙과 플랫폼 통합, Backstage 비용 대시보드, 태그 기반 비용 할당, 리소스 생성 시점의 비용 예측, 그리고 AI 기반 비용 최적화를 다룹니다.

2026년 3월 31일·16분
이전 글5장: Golden Path 설계와 구현
다음 글7장: 플랫폼 API 설계

댓글

목차

약 14분 남음
  • 학습 목표
  • 셀프서비스의 원칙
    • 자율성과 가드레일의 균형
  • GitOps 기반 인프라 요청
    • 인프라 요청 워크플로우
    • 인프라 저장소 구조
    • 리소스 요청 파일 예시
  • Crossplane으로 Kubernetes 네이티브 인프라 관리
    • 왜 Crossplane인가
    • Crossplane 설치
    • Composite Resource Definition (XRD)
    • Composition
    • 개발자의 사용법
  • 환경 프로비저닝 자동화
  • 승인 워크플로우
    • 승인 정책
  • 정리