[Infrastructure as Code (IaC) Pulumi] Use Pulumi kubernetes (K8S) Helm Chart to deploy Argo CD

Argo CD

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.

This article is about how to use Pulumi, kubernetes (K8S) provider, Helm Chart and TypeScript SDK to deploy Argo CD within Kubernetes (K8S).

Prerequisites

Usage

Pulumi New

Create the workspace directory.

1
2
3
$ mkdir -p col-example-pulumi-typescript-argo-cd

$ cd col-example-pulumi-typescript-argo-cd

Pulumi login into local file system.

1
2
3
$ pulumi login file://.
Logged in to cloudolife as cloudolife (file://.)
or visit https://pulumi.com/docs/reference/install/ for manual instructions and release notes.

Pulumi new a project with kubernetes-typescript SDK.

1
$ pulumi new kubernetes-typescript

The above command will create some files within the current directory.

1
2
3
4
5
6
7
8
tree . -L 1
.
├── node_modules/
├── package.json
├── package.json.lock
├── Pulumi.dev.yaml
├── Pulumi.yaml
└── main.ts

Install js-yaml package to load and parse yaml file.

1
$ npm i js-yaml

Pulumi Configuration

Configure Kubernetes

By default, Pulumi will look for a kubeconfig file in the following locations, just like kubectl:

  • The environment variable: $KUBECONFIG,

  • Or in current user’s default kubeconfig directory: ~/.kube/config

If the kubeconfig file is not in either of these locations, Pulumi will not find it, and it will fail to authenticate against the cluster. Set one of these locations to a valid kubeconfig file, if you have not done so already.

Configure Values.yaml

Edit values.yaml and replace content within {{ }}.

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
# values.yaml

# argo-helm/values.yaml at master · argoproj/argo-helm
# https://github.com/argoproj/argo-helm/blob/master/charts/argo-cd/values.yaml

argo-cd-ha:
enabled: true

controller:
enableStatefulSet: true

server:
autoscaling:
enabled: true
minReplicas: 2

ingress:
# -- Enable an ingress resource for the Argo CD server
enabled: true

annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
# If you encounter a redirect loop or are getting a 307 response code
# then you need to force the nginx ingress to connect to the backend using HTTPS.
#
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

# -- Additional ingress annotations
ingressClassName: "nginx"

# -- List of ingress hosts
## Argo Ingress.
## Hostnames must be provided if Ingress is enabled.
## Secrets must be manually created in the namespace
hosts:
- {{ .Values.host }}

tls:
- secretName: {{ .Values.tls.secretName }}
hosts:
- {{ .Values.host }}

# -- Uses `server.service.servicePortHttps` instead `server.service.servicePortHttp`
https: true

config:
# Argo CD's externally facing base URL (optional). Required when configuring SSO
url: https://{{ .Values.host }}

repoServer:
autoscaling:
enabled: true
minReplicas: 2

See and modify main.ts file.

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
// main.ts

import * as pulumi from "@pulumi/pulumi";

import * as k8s from "@pulumi/kubernetes";

const yaml = require('js-yaml');
const fs = require('fs');

const nameArgoCD = "argo-cd"

const namespaceArgoCD = new k8s.core.v1.Namespace(nameArgoCD, {
metadata: {
name: nameArgoCD,
},
})

const values = yaml.safeLoad(fs.readFileSync("./values.yaml", 'utf8'))

const charNameArgoCD = "argo-cd"

// argo-cd 4.0.1 · kubernetes/argo-cd
// https://artifacthub.io/packages/helm/argo-cd/argo-cd
const charArgoCD = new k8s.helm.v3.Chart(charNameArgoCD, {
chart: charNameArgoCD,
version: "3.26.12",
fetchOpts:{
repo: "https://argoproj.github.io/argo-helm",
},
namespace: namespaceArgoCD.metadata.name,
values: values,
});

Pulumi Up

Run pulumi up to create the namespace and pods.

1
$ pulumi up

See pods about argo-cd.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ kubectl get pods -n argo-cd
NAME READY STATUS RESTARTS AGE
argo-cd-argocd-application-controller-0 1/1 Running 0 175m
argo-cd-argocd-dex-server-6f496844cd-vrh7n 1/1 Running 0 175m
argo-cd-argocd-repo-server-664cd56c78-mltrm 1/1 Running 0 175m
argo-cd-argocd-repo-server-664cd56c78-zcr6w 1/1 Running 0 175m
argo-cd-argocd-server-c8f945b59-j7b4c 1/1 Running 0 160m
argo-cd-argocd-server-c8f945b59-m6ctb 1/1 Running 0 160m
argo-cd-redis-ha-haproxy-75fb577466-6dw4g 1/1 Running 0 175m
argo-cd-redis-ha-haproxy-75fb577466-l6pwr 1/1 Running 0 175m
argo-cd-redis-ha-haproxy-75fb577466-w2brb 1/1 Running 0 175m
argo-cd-redis-ha-server-0 3/3 Running 0 175m
argo-cd-redis-ha-server-1 3/3 Running 0 174m
argo-cd-redis-ha-server-2 3/3 Running 0 173m

Get admin user init password:

1
$ kubectl -n argo-cd get secret argo-cd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

Then, open browser to visit {{ .Values.host }} to login Argo CD Web UI.

Pulumi Destroy

Destroy all resources created by Pulumi.

1
$ pulumi destroy

High Availability

This chart installs the non-HA version of ArgoCD by default. If you want to run ArgoCD in HA mode, you can use one of the example values in the next sections. Please also have a look into the upstream Operator Manual regarding High Availability to understand how scaling of ArgoCD works in detail.


Warning: You need at least 3 worker nodes as the HA mode of redis enforces Pods to run on separate nodes.


HA mode with autoscaling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# values.yaml

redis-ha:
enabled: true

controller:
enableStatefulSet: true

server:
autoscaling:
enabled: true
minReplicas: 2

repoServer:
autoscaling:
enabled: true
minReplicas: 2

HA mode without autoscaling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# values.yaml
redis-ha:
enabled: true

controller:
enableStatefulSet: true

server:
replicas: 2
env:
- name: ARGOCD_API_SERVER_REPLICAS
value: '2'

repoServer:
replicas: 2

References

[1] argo-helm/charts/argo-cd at master · argoproj/argo-helm - https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd

[2] argo-cd 3.26.12 · argoproj/argo - https://artifacthub.io/packages/helm/argo/argo-cd

[3] Argo CD | Argo - https://argoproj.github.io/cd/

[4] argoproj/argo-cd: Declarative continuous deployment for Kubernetes. - https://github.com/argoproj/argo-cd

[5] Argo CD - Declarative GitOps CD for Kubernetes - https://argo-cd.readthedocs.io/en/stable/

[6] Kubernetes Getting Started | Pulumi - https://www.pulumi.com/docs/get-started/kubernetes/

[7] Pulumi - Modern Infrastructure as Code - https://www.pulumi.com/

[8] Kubernetes - https://kubernetes.io/

[9] TypeScript: Typed JavaScript at Any Scale. - https://www.typescriptlang.org/

[10] Helm - https://helm.sh/