Skip to content

Commit bd7fa8e

Browse files
committed
feat: automated deployment for argocd in single cluster mode
1 parent 9e94ae6 commit bd7fa8e

File tree

5 files changed

+205
-0
lines changed

5 files changed

+205
-0
lines changed

argocd/deploy-argocd/.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Local .terraform directories
2+
**/.terraform/*
3+
4+
# .tfstate files
5+
*.tfstate
6+
*.tfstate.*
7+
8+
# Crash logs
9+
crash.log
10+
crash.*.log
11+
12+
# Sensitive variable files (where you store your Keycloak credentials)
13+
*.tfvars
14+
*.tfvars.json
15+
override.tf
16+
override.tf.json
17+
_override.tf
18+
_override.tf.json
19+
20+
# Local environment files
21+
.envrc
22+
.env
23+
24+
# MacOS files
25+
.DS_Store
26+
27+
# Helm local cache/logs
28+
.helm/

argocd/deploy-argocd/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Modular ArgoCD Deployment with Keycloak OIDC & RBAC
2+
3+
This Terraform module deploys **ArgoCD** into a Kubernetes cluster using the official Helm chart. It is designed to be modular, supporting deployment to different clusters (Control Plane vs. Workload) with toggleable features for **Keycloak (OIDC) integration** and **RBAC (Role-Based Access Control)**.
4+
5+
---
6+
7+
## Directory Structure
8+
9+
```text
10+
.
11+
├── modules/
12+
│ └── argocd/ # Core Logic (Don't touch unless modifying the blueprint)
13+
└── environments/
14+
└── control-plane/ # Deployment configuration for your specific cluster
15+
├── main.tf
16+
├── variables.tf # Define your cluster context and secrets here
17+
├── terraform.tfvars # (Optional) Store non-sensitive values here
18+
└── providers.tf # Configures connection to the specific K8s cluster

argocd/deploy-argocd/main.tf

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# =============================================================================
2+
# SECTION 1: KEYCLOAK CONFIGURATION
3+
# Configure the existing Keycloak to accept ArgoCD logins
4+
# =============================================================================
5+
6+
# 1. Create the OIDC Client
7+
resource "keycloak_openid_client" "argocd" {
8+
realm_id = var.target_realm
9+
client_id = "argocd-client"
10+
name = "ArgoCD"
11+
enabled = true
12+
access_type = "CONFIDENTIAL"
13+
standard_flow_enabled = true
14+
direct_access_grants_enabled = true
15+
16+
# This must match your ArgoCD URL exactly
17+
valid_redirect_uris = [
18+
"${var.argocd_url}/auth/callback",
19+
"${var.argocd_url}/*" # Temporary wildcard to troubleshoot
20+
]
21+
}
22+
23+
resource "keycloak_openid_client_default_scopes" "client_default_scopes" {
24+
realm_id = var.target_realm
25+
client_id = keycloak_openid_client.argocd.id
26+
27+
default_scopes = [
28+
"openid",
29+
"profile",
30+
"email",
31+
"roles"
32+
]
33+
}
34+
35+
# 2. Create the Client Secret
36+
# (The provider generates this automatically, we just access it later)
37+
38+
# 3. Create Group Mapper
39+
# This ensures Keycloak sends the "groups" claim so ArgoCD can do RBAC
40+
resource "keycloak_openid_group_membership_protocol_mapper" "groups" {
41+
realm_id = var.target_realm
42+
client_id = keycloak_openid_client.argocd.id
43+
name = "group-mapper"
44+
claim_name = "groups"
45+
full_path = false
46+
}
47+
48+
# =============================================================================
49+
# SECTION 2: ARGOCD DEPLOYMENT (HELMS)
50+
# Deploy ArgoCD to GKE and inject the secrets from Section 1
51+
# =============================================================================
52+
53+
resource "helm_release" "argocd-test" {
54+
name = "argocd"
55+
repository = "https://argoproj.github.io/argo-helm"
56+
chart = "argo-cd"
57+
namespace = "argocd-test"
58+
create_namespace = true
59+
version = "5.51.0"
60+
skip_crds = true
61+
62+
# Using values (YAML) instead of set avoids comma parsing errors entirely
63+
values = [
64+
yamlencode({
65+
configs = {
66+
cm = {
67+
url = var.argocd_url
68+
"oidc.config" = yamlencode({
69+
name = "Keycloak"
70+
issuer = "${var.keycloak_url}/realms/${var.target_realm}"
71+
clientID = keycloak_openid_client.argocd.client_id
72+
clientSecret = keycloak_openid_client.argocd.client_secret
73+
requestedScopes = ["openid", "profile", "email"]
74+
75+
rootCA = ""
76+
})
77+
}
78+
rbac = {
79+
"policy.csv" = "g, /ArgoCDAdmins, role:admin"
80+
}
81+
}
82+
server = {
83+
service = {
84+
type = "LoadBalancer"
85+
}
86+
}
87+
})
88+
]
89+
}
90+
91+
# =============================================================================
92+
# OUTPUTS
93+
# =============================================================================
94+
95+
output "argocd_admin_secret" {
96+
value = keycloak_openid_client.argocd.client_secret
97+
sensitive = true
98+
}

argocd/deploy-argocd/provider.tf

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
terraform {
2+
required_providers {
3+
keycloak = {
4+
source = "mrparkers/keycloak"
5+
version = ">= 4.0.0"
6+
}
7+
helm = {
8+
source = "hashicorp/helm"
9+
version = ">= 2.0.0"
10+
}
11+
}
12+
}
13+
14+
# 1. Connect to your EXISTING Keycloak
15+
provider "keycloak" {
16+
client_id = "admin-cli"
17+
url = var.keycloak_url # e.g. https://auth.example.com
18+
username = var.keycloak_user
19+
password = var.keycloak_password
20+
}
21+
22+
# 2. Connect to GKE using your local terminal credentials
23+
provider "helm" {
24+
kubernetes = {
25+
config_path = "~/.kube/config"
26+
config_context = var.kube_context # Optional: specify if you have multiple contexts
27+
}
28+
}

argocd/deploy-argocd/variables.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# --- Keycloak Settings ---
2+
variable "keycloak_url" {
3+
description = "The URL of your existing Keycloak (e.g., https://auth.example.com)"
4+
type = string
5+
}
6+
7+
variable "keycloak_user" {
8+
description = "Keycloak Admin Username"
9+
type = string
10+
}
11+
12+
variable "keycloak_password" {
13+
description = "Keycloak Admin Password"
14+
type = string
15+
sensitive = true
16+
}
17+
18+
variable "target_realm" {
19+
description = "The Keycloak Realm where ArgoCD will be registered"
20+
default = "argocd" # Change if using a specific realm
21+
}
22+
23+
# --- ArgoCD Settings ---
24+
variable "argocd_url" {
25+
description = "The final URL where you will access ArgoCD (e.g., https://argocd.example.com)"
26+
type = string
27+
}
28+
29+
variable "kube_context" {
30+
description = "The context name in your kubeconfig (run 'kubectl config current-context')"
31+
type = string
32+
default = "" # If empty, uses current context
33+
}

0 commit comments

Comments
 (0)