Post

Terraform Helm Provider 사용 방법

Terraform Helm Provider 사용 방법
Helm provider가 release lifecycle을 Terraform state에 연결합니다

helm_release를 Terraform이 소유하므로 수동 helm upgrade는 다음 plan에서 drift로 보입니다.

Terraform configuration helm_release resource와 values를 선언합니다.
provider 선택
Helm provider Helm SDK를 Terraform process 안에서 실행합니다.
chart와 values 렌더링
Helm chart chart template과 전달한 values를 조합합니다.
manifests 적용
Kubernetes API rendered manifests를 cluster에 적용합니다.
state에 lifecycle 기록
Release resources release 상태가 Terraform state에서 추적됩니다.

PNG 다운로드 원본 이미지 열기

Helm은 Kubernetes의 패키지 매니저로, 애플리케이션의 배포 및 관리를 간편하게 해주는 도구입니다. Kubernetes의 리소스를 정의하는 Manifest 파일을 템플릿화하여 재사용성유지보수성을 높이는 데 도움을 줍니다.

일반적으로 패키지 매니저를 사용하지 않고 Dev, Stage, Prod 등의 다양한 환경에서 Kubernetes Manifest 파일만을 사용해 운영할 경우, 각 환경에 맞춘 Replicas, ConfigMap, Secrets 등의 설정을 개별적으로 관리해야 합니다. 이로 인해 운영의 복잡성 증가, 구성의 일관성 유지 어려움, 수작업에 의한 오류 가능성 증가와 같은 문제점이 발생할 수 있습니다.

Terraform 환경에서 Helm을 활용하면, Kubernetes 애플리케이션의 배포 자동화가 가능하며, 인프라 및 애플리케이션을 일관되게 관리하기가 쉬워집니다. Terraform의 Helm Provider를 사용하면 Helm Chart의 설치, 업데이트, 삭제를 코드로 정의할 수 있으며, 이를 통해 운영 효율성을 높이고 CI/CD 파이프라인과의 연동도 원활해집니다.

Terraform Helm Provider를 활용해 Kubernetes 애플리케이션을 배포하는 방법에 대해 다뤄보도록 하겠습니다.

TL;DR

  • Helm Provider가 클러스터에 접근하는 방법은 config_path로 kubeconfig를 가리키거나, cluster credential을 직접 넣는 두 가지입니다.
  • helm_release 리소스에 name, repository, chart, version, namespace, values를 지정해 chart를 배포합니다. version을 생략하면 최신 버전이 잡힙니다.
  • EKS라면 aws_eks_cluster_auth data source나 exec plugin으로 동적 토큰을 발급해 연결할 수 있습니다.

1. 실습 환경

  • Terraform (v1.10.4)
  • Helm Provider(hashicorp/helm) (v2.17.0)
  • Helm (v3.16.2)
  • kubectl (v1.32.0)
  • Kubernetes Cluster (v1.32.0)

위 버전은 현재 실습 환경이며, 실제 운영 환경에서는 다른 버전을 사용하셔도 무방합니다. 다만, Terraform Helm Provider 버전에 따라 일부 설정이나 문법이 달라질 수 있습니다.


2. Terraform Helm Provider 설정

Helm Provider를 사용하기 위해서는 크게 다음 두 가지 방법이 있습니다.

  1. config_path를 사용해 kubeconfig 파일로 접근
  2. Kubernetes Cluster Credentials를 직접 설정

2.1. config_path 사용

terraform 명령어를 실행하는 환경에서 ~/.kube/config 경로의 kubeconfig 파일이 정상적으로 Kubernetes Cluster에 접근할 수 있어야 합니다.

1
2
3
4
5
provider "helm" {
  kubernetes {
    config_path = "~/.kube/config"
  }
}

2.2. Kubernetes Cluster Credentials 사용

Kubernetes Cluster Credentials를 직접 설정하여 Helm Provider를 사용할 수도 있습니다.
kubectl config view --raw 명령어를 사용하면 client-certificate-data, client-key-data, cluster-ca-certificate-data 값을 확인할 수 있습니다.

1
2
3
4
5
6
7
8
9
provider "helm" {
  kubernetes {
    host     = "https://cluster_endpoint:port"

    client_certificate     = base64decode("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0...생략...")
    client_key             = base64decode("LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVk...생략...")
    cluster_ca_certificate = base64decode("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0...생략...")
  }
}

주의
위 정보를 코드에 직접 하드코딩하면 보안적으로 취약할 수 있습니다. 실제 운영 환경에서는 Terraform 변수나 data 리소스, 외부 시크릿 저장소 등을 사용해 안전하게 주입하는 방식을 권장합니다.


3. Terraform Helm Provider를 사용한 리소스 배포

실습을 위해 Bitnami에서 제공하는 Nginx 웹 서버 Helm Chart를 간단히 배포해보겠습니다.
자세한 설정값 및 옵션은 공식 문서에서 참고하실 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
resource "helm_release" "nginx" {
  name       = "my-nginx"                                 # Kubernetes 내 Release 이름
  repository = "oci://registry-1.docker.io/bitnamicharts" # 차트 레포지토리
  chart      = "nginx"                                    # 차트명
  version    = "18.3.5"                                   # 차트 버전 (원하는 버전)

  namespace        = "helm-provider-practice" # 배포할 네임스페이스
  create_namespace = true                     # 네임스페이스가 없을 경우 생성

  # values = [
  #   file("nginx-values.yaml")  # 차트 설정(Values) 파일을 넣을 수도 있음
  # ]

  # 단순 key-value 형식 설정 (set)
  set {
    name  = "service.type"
    value = "LoadBalancer"
  }

  set {
    name  = "service.port"
    value = "80"
  }

  set {
    name  = "replicaCount"
    value = "3"
  }

  # 예시) Atomic, Timeout 등 옵션 설정 가능
  atomic  = true
  timeout = 300
} 

3.1. 핵심 옵션

  • name: Kubernetes 내 Helm Release 이름
  • repository: 차트가 있는 Helm Repo URL
  • chart: 사용할 차트 이름
  • version: 차트 버전 (생략 시 최신 버전 사용)
  • namespace: 배포할 네임스페이스 (자동 생성 옵션 있음)
  • values 또는 set {}: Helm Chart의 Values.yaml 설정

3.2. Nginx Helm Chart 배포

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
❯ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # helm_release.nginx will be created
  + resource "helm_release" "nginx" {
      + atomic                     = true
      + chart                      = "nginx"
      + cleanup_on_fail            = false
      + create_namespace           = true
      ...
      ...
      + version                    = "18.3.5"
      + wait                       = true
      + wait_for_jobs              = false

      + set {
          + name  = "replicaCount"
          + value = "3"
        }
      + set {
          + name  = "service.port"
          + value = "80"
        }
      + set {
          + name  = "service.type"
          + value = "LoadBalancer"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

helm_release.nginx: Creating...
helm_release.nginx: Still creating... [10s elapsed]
helm_release.nginx: Creation complete after 15s [id=my-nginx]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

❯ kubectl get all -n helm-provider-practice
NAME                            READY   STATUS    RESTARTS   AGE
pod/my-nginx-6c44c9689c-5rv9v   1/1     Running   0          2m31s
pod/my-nginx-6c44c9689c-kwl7x   1/1     Running   0          2m31s
pod/my-nginx-6c44c9689c-nds94   1/1     Running   0          2m31s

NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
service/my-nginx   LoadBalancer   10.233.41.62   10.0.1.101    80:30805/TCP,443:30766/TCP   2m31s

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-nginx   3/3     3            3           2m31s

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/my-nginx-6c44c9689c   3         3         3       2m31s

4. 마무리

이상으로 Terraform Helm Provider를 사용해 간단히 Nginx 웹 서버를 배포하는 과정을 살펴보았습니다.
AWS EKS 환경에서 aws eks get-token 등을 통해 동적 토큰을 발행하고, Terraform의 exec 플러그인이나 data "aws_eks_cluster_auth"와 연동하여 사용하는 방법도 있으니 참고하시기 바랍니다.


5. Reference


궁금하신 점이나 추가해야 할 부분은 댓글이나 아래의 링크를 통해 문의해주세요.
Written with KKamJi

This post is licensed under CC BY 4.0 by the author.