diff --git a/bridge/.idea/workspace.xml b/bridge/.idea/workspace.xml
new file mode 100644
index 0000000..8165e1c
--- /dev/null
+++ b/bridge/.idea/workspace.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 1
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1731596143702
+
+
+ 1731596143702
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/infra/modules/homepage/values.yaml.tftpl b/infra/modules/homepage/values.yaml.tftpl
index 8c40e6e..9b86d45 100644
--- a/infra/modules/homepage/values.yaml.tftpl
+++ b/infra/modules/homepage/values.yaml.tftpl
@@ -4,21 +4,6 @@ config:
- Github:
- abbr: GH
href: https://github.com/
- services:
- - My First Group:
- - My First Service:
- href: http://localhost/
- description: Homepage is awesome
-
- - My Second Group:
- - My Second Service:
- href: http://localhost/
- description: Homepage is the best
-
- - My Third Group:
- - My Third Service:
- href: http://localhost/
- description: Homepage is 😎
widgets:
# show the kubernetes widget, with the cluster summary and individual nodes
- kubernetes:
diff --git a/infra/modules/minio/main.tf b/infra/modules/minio/main.tf
index 4873dd8..ae332c1 100644
--- a/infra/modules/minio/main.tf
+++ b/infra/modules/minio/main.tf
@@ -58,6 +58,7 @@ resource "helm_release" "minio" {
admin = var.admin,
tls = var.mode == "distributed" ? false : var.tls
ingressClass = var.ingressClass
+ displayOnHomepage = var.displayOnHomepage
})
]
}
diff --git a/infra/modules/minio/values.yaml.tftpl b/infra/modules/minio/values.yaml.tftpl
index 0fe6965..68568d3 100644
--- a/infra/modules/minio/values.yaml.tftpl
+++ b/infra/modules/minio/values.yaml.tftpl
@@ -22,6 +22,13 @@ ingress:
ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
%{ endif }
+ %{ if displayOnHomepage }
+ gethomepage.dev/enabled: "true"
+ gethomepage.dev/name: "Minio"
+ gethomepage.dev/description: "S3-Compatible cloud storage"
+ gethomepage.dev/group: "Tools"
+ gethomepage.dev/icon: "minio.png"
+ %{ endif }
apiIngress:
enabled: true
diff --git a/infra/modules/minio/variables.tf b/infra/modules/minio/variables.tf
index e4c0dfd..5b72ab1 100644
--- a/infra/modules/minio/variables.tf
+++ b/infra/modules/minio/variables.tf
@@ -61,7 +61,11 @@ variable "ingressClass" {
}
variable "storageSize" {
- type = string
+ type = string
default = "6Gi"
}
+variable "displayOnHomepage" {
+ type = bool
+ default = false
+}
diff --git a/infra/modules/postgresql/main.tf b/infra/modules/postgresql/main.tf
index 0e2ef9f..cbc4c0f 100644
--- a/infra/modules/postgresql/main.tf
+++ b/infra/modules/postgresql/main.tf
@@ -1,4 +1,6 @@
resource "kubernetes_namespace" "postgresql" {
+ count = var.enabled ? 1 : 0
+
metadata {
name = var.namespace
}
@@ -19,11 +21,12 @@ resource "random_password" "postgresql_root_password" {
}
resource "kubernetes_secret" "postgresql_auth" {
- type = "generic"
+ count = var.enabled ? 1 : 0
+ type = "generic"
depends_on = [var.wait_on]
metadata {
name = "postgresql-auth"
- namespace = kubernetes_namespace.postgresql.metadata.0.name
+ namespace = kubernetes_namespace.postgresql[count.index].metadata.0.name
}
data = {
@@ -33,11 +36,12 @@ resource "kubernetes_secret" "postgresql_auth" {
}
resource "helm_release" "postgresql" {
+ count = var.enabled ? 1 : 0
depends_on = [var.wait_on, kubernetes_secret.postgresql_auth]
name = "postgresql"
repository = "https://charts.bitnami.com/bitnami"
chart = "postgresql"
- namespace = kubernetes_namespace.postgresql.metadata.0.name
+ namespace = kubernetes_namespace.postgresql[count.index].metadata.0.name
version = "16.0.5"
wait = true
diff --git a/infra/modules/postgresql/tenant/main.tf b/infra/modules/postgresql/tenant/main.tf
index d2cad9b..b8b3182 100644
--- a/infra/modules/postgresql/tenant/main.tf
+++ b/infra/modules/postgresql/tenant/main.tf
@@ -17,6 +17,7 @@ resource "random_password" "tenant" {
}
resource "kubernetes_job" "create-tenant" {
+ count = var.enabled ? 1 : 0
depends_on = [var.wait_on]
metadata {
@@ -108,5 +109,5 @@ output "username" {
}
output "job_name" {
- value = kubernetes_job.create-tenant.metadata[0].name
+ value = var.enabled ? kubernetes_job.create-tenant[0].metadata[0].name : null
}
diff --git a/infra/modules/postgresql/tenant/variables.tf b/infra/modules/postgresql/tenant/variables.tf
index 46c3a52..bc30f8c 100644
--- a/infra/modules/postgresql/tenant/variables.tf
+++ b/infra/modules/postgresql/tenant/variables.tf
@@ -38,3 +38,8 @@ variable "k8s_config_yaml" {
description = "Content of k8s config yaml file"
type = string
}
+
+variable "enabled" {
+ type = bool
+ default = true
+}
diff --git a/infra/modules/postgresql/variables.tf b/infra/modules/postgresql/variables.tf
index 3c3eb32..1e10dd0 100644
--- a/infra/modules/postgresql/variables.tf
+++ b/infra/modules/postgresql/variables.tf
@@ -16,3 +16,8 @@ variable "namespace" {
variable "username" {
type = string
}
+
+variable "enabled" {
+ type = bool
+ default = true
+}
diff --git a/infra/modules/zitadel/identity-provider/google/main.tf b/infra/modules/zitadel/identity-provider/google/main.tf
index fdb6abc..e116eeb 100644
--- a/infra/modules/zitadel/identity-provider/google/main.tf
+++ b/infra/modules/zitadel/identity-provider/google/main.tf
@@ -1,19 +1,44 @@
-resource "zitadel_org" "default" {
+resource "zitadel_org_idp_google" "default" {
depends_on = [var.wait_on]
- name = var.name
+ org_id = var.org_id
+ name = "Google"
+ client_id = var.client_id
+ client_secret = var.client_secret
+ scopes = var.options.scopes
+ is_linking_allowed = var.options.is_linking_allowed
+ is_creation_allowed = var.options.is_creation_allowed
+ is_auto_creation = var.options.is_auto_creation
+ is_auto_update = var.options.is_auto_update
+ auto_linking = var.options.auto_linking
}
-#resource "zitadel_idp_google" "default" {
-# name = "Google"
-# client_id = "182902..."
-# client_secret = "GOCSPX-*****"
-# scopes = ["openid", "profile", "email"]
-# is_linking_allowed = false
-# is_creation_allowed = true
-# is_auto_creation = false
-# is_auto_update = true
-# auto_linking = "AUTO_LINKING_OPTION_USERNAME"
-#}
+resource "zitadel_login_policy" "default" {
+ depends_on = [zitadel_org_idp_google.default]
-#google_client_id = "783390190667-0nkts50perpmhott4i7ro1ob5n7koi5i.apps.googleusercontent.com"
-#google_client_secret = "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"
+ org_id = var.org_id
+ user_login = true
+ allow_register = true
+ allow_external_idp = true
+ force_mfa = false
+ force_mfa_local_only = false
+ passwordless_type = "PASSWORDLESS_TYPE_ALLOWED"
+ hide_password_reset = "false"
+ password_check_lifetime = "240h0m0s"
+ external_login_check_lifetime = "240h0m0s"
+ multi_factor_check_lifetime = "24h0m0s"
+ mfa_init_skip_lifetime = "720h0m0s"
+ second_factor_check_lifetime = "24h0m0s"
+ ignore_unknown_usernames = true
+ default_redirect_uri = "https://${var.domain}"
+ second_factors = ["SECOND_FACTOR_TYPE_OTP", "SECOND_FACTOR_TYPE_U2F"]
+ multi_factors = ["MULTI_FACTOR_TYPE_U2F_WITH_VERIFICATION"]
+ idps = [zitadel_org_idp_google.default.id]
+ allow_domain_discovery = true
+ disable_login_with_email = true
+ disable_login_with_phone = true
+}
+
+output "installed" {
+ value = true
+ depends_on = [zitadel_org_idp_google.default, zitadel_login_policy.default]
+}
diff --git a/infra/modules/zitadel/identity-provider/google/provider.tf b/infra/modules/zitadel/identity-provider/google/provider.tf
index 2550782..653009c 100644
--- a/infra/modules/zitadel/identity-provider/google/provider.tf
+++ b/infra/modules/zitadel/identity-provider/google/provider.tf
@@ -1,56 +1,14 @@
-locals {
- k8s_config = yamldecode(var.k8s_config_yaml)
- k8s_host = local.k8s_config.clusters[0].cluster.server
- k8s_auth = try(
- {
- token = local.k8s_config.users[0].user.token
- using_token = true
- },
- {
- client_certificate = base64decode(local.k8s_config.users[0].user["client-certificate-data"])
- client_key = base64decode(local.k8s_config.users[0].user["client-key-data"])
- using_token = false
- }
- )
-}
-
-provider "kubernetes" {
- host = local.k8s_host
- insecure = true
- token = local.k8s_auth.using_token ? local.k8s_auth.token : null
- client_certificate = local.k8s_auth.using_token ? null : local.k8s_auth.client_certificate
- client_key = local.k8s_auth.using_token ? null : local.k8s_auth.client_key
-}
-
-provider "helm" {
- kubernetes {
- host = local.k8s_host
- insecure = true
- token = local.k8s_auth.using_token ? local.k8s_auth.token : null
- client_certificate = local.k8s_auth.using_token ? null : local.k8s_auth.client_certificate
- client_key = local.k8s_auth.using_token ? null : local.k8s_auth.client_key
- }
-}
-
terraform {
required_providers {
zitadel = {
source = "zitadel/zitadel"
- version = "1.2.0"
+ version = "2.0.2"
}
}
}
-data "kubernetes_secret" "zitadel_admin" {
- depends_on = [var.wait_on]
- metadata {
- name = var.secret
- namespace = var.namespace
- }
-}
-
provider "zitadel" {
domain = var.domain
insecure = "false"
- jwt_profile_json = data.kubernetes_secret.zitadel_admin.data["${var.secret}.json"]
+ jwt_profile_file = var.jwt_profile_file
}
diff --git a/infra/modules/zitadel/identity-provider/google/variables.tf b/infra/modules/zitadel/identity-provider/google/variables.tf
index d3009d3..c648d93 100644
--- a/infra/modules/zitadel/identity-provider/google/variables.tf
+++ b/infra/modules/zitadel/identity-provider/google/variables.tf
@@ -4,29 +4,47 @@ variable "domain" {
default = "localhost"
}
-variable "secret" {
- type = string
- description = "Secret holding the JWT Profile JSON"
-}
-
-variable "namespace" {
- type = string
- description = "Namespace holding the secret"
-}
-
variable "wait_on" {
type = any
description = "Resources to wait on"
default = true
}
-variable "k8s_config_yaml" {
- description = "Content of k8s config yaml file"
+variable "jwt_profile_file" {
type = string
+ description = "Path to the jwt profile file"
}
-variable "name" {
+variable "org_id" {
type = string
- description = "Name of the tenant"
- default = "fourlights"
+ description = "Organisation Id"
+}
+
+variable "client_id" {
+ type = string
+ description = "Google Client ID"
+}
+
+variable "client_secret" {
+ type = string
+ description = "Google Client Secret"
+}
+
+variable "options" {
+ type = object({
+ scopes = list(string)
+ is_linking_allowed = bool
+ is_creation_allowed = bool
+ is_auto_creation = bool
+ is_auto_update = bool
+ auto_linking = string
+ })
+ default = {
+ scopes = ["openid", "profile", "email"],
+ is_linking_allowed = false
+ is_creation_allowed = true
+ is_auto_creation = false
+ is_auto_update = true
+ auto_linking = "AUTO_LINKING_OPTION_USERNAME"
+ }
}
diff --git a/infra/modules/zitadel/main.tf b/infra/modules/zitadel/main.tf
index a9f8d18..c874912 100644
--- a/infra/modules/zitadel/main.tf
+++ b/infra/modules/zitadel/main.tf
@@ -7,7 +7,8 @@ terraform {
}
}
-resource "kubernetes_namespace" "fusionauth" {
+resource "kubernetes_namespace" "zitadel" {
+ count = var.enabled ? 1 : 0
metadata {
name = var.namespace
}
@@ -17,125 +18,73 @@ resource "kubernetes_namespace" "fusionauth" {
}
}
-data "kubernetes_secret" "bridge-tls" {
- metadata {
- name = "bridge-tls"
- namespace = "cert-manager"
- }
+resource "random_password" "zitadel_masterkey" {
+ length = 32
+ special = true
}
-resource "kubernetes_secret" "fusionauth-tls" {
+resource "kubernetes_secret" "zitadel" {
+ count = var.enabled ? 1 : 0
metadata {
- name = "fusionauth-tls"
- namespace = kubernetes_namespace.fusionauth.metadata[0].name
+ name = "zitadel"
+ namespace = kubernetes_namespace.zitadel[count.index].metadata[0].name
}
-
- data = data.kubernetes_secret.bridge-tls.data
- type = data.kubernetes_secret.bridge-tls.type
-}
-
-resource "kubernetes_secret" "postgresql-auth" {
- metadata {
- name = "postgresql-auth"
- namespace = kubernetes_namespace.fusionauth.metadata[0].name
- }
-
data = {
- password = var.database_password
+ masterkey = random_password.zitadel_masterkey.result
}
}
-resource "random_password" "api_key" {
- length = 32
- special = false
-}
-
-resource "random_password" "admin" {
- length = 32
- special = false
-}
-
-resource "random_uuid" "default_tenant_id" {}
-
-resource "helm_release" "fusionauth" {
- depends_on = [var.wait_on, kubernetes_secret.postgresql-auth, kubernetes_secret.fusionauth-tls]
- name = "fusionauth"
- repository = "https://fusionauth.github.io/charts"
- chart = "fusionauth"
- namespace = kubernetes_namespace.fusionauth.metadata[0].name
- version = "1.0.10"
+resource "helm_release" "zitadel" {
+ count = var.enabled ? 1 : 0
+ depends_on = [var.wait_on, kubernetes_secret.zitadel]
+ name = "zitadel"
+ repository = "https://charts.zitadel.com"
+ chart = "zitadel"
+ namespace = kubernetes_namespace.zitadel[count.index].metadata[0].name
+ version = "8.12.0"
create_namespace = false
wait = true
wait_for_jobs = true
values = [
- templatefile("${path.module}/values.yaml", {
+ templatefile("${path.module}/values.yaml.tftpl", {
service_uri = local.service_uri,
database = var.database,
database_username = var.database_username,
+ database_password = var.database_password,
database_root_username = var.database_root_password != null ? var.database_root_username : null,
-
- # TODO: Add theme customization, and use as default
-
- kickstart_json = jsonencode({
- variables = {
- defaultTenantId = random_uuid.default_tenant_id.result
- adminEmail = "engineering@fourlights.nl"
- adminPassword = random_password.admin.result
- }
- apiKeys = [{ key = random_password.api_key.result, description = "Terraform API Key" }],
- requests = [
- {
- "method" : "POST",
- "url" : "/api/user/registration/00000000-0000-0000-0000-000000000001",
- "body" : {
- "user" : {
- "email" : "#{adminEmail}",
- "firstName" : "Thomas",
- "lastName" : "Rijpstra",
- "password" : "#{adminPassword}",
- "data" : {
- "Company" : "Four Lights",
- "user_type" : "iconclast"
- }
- },
- "registration" : {
- "applicationId" : "#{FUSIONAUTH_APPLICATION_ID}",
- "roles" : [
- "admin"
- ]
- }
- }
- }
- ],
- })
+ database_root_password = var.database_root_password
+ display_on_homepage = var.display_on_homepage
})
]
}
+data "kubernetes_secret" "zitadel_admin" {
+ depends_on = [helm_release.zitadel]
+ metadata {
+ name = "zitadel-admin-sa"
+ namespace = var.namespace
+ }
+}
+
+resource "local_file" "zitadel_jwt_profile_file" {
+ content = data.kubernetes_secret.zitadel_admin.data["zitadel-admin-sa.json"]
+ filename = format("%s/%s", path.root, "zitadel-admin-sa.json")
+}
+
+output "jwt_profile_file" {
+ value = local_file.zitadel_jwt_profile_file.filename
+}
+
output "installed" {
value = true
- depends_on = [helm_release.fusionauth]
-}
-
-output "api_key" {
- value = random_password.api_key.result
- sensitive = true
-}
-
-output "admin_password" {
- value = random_password.admin.result
- sensitive = true
+ depends_on = [helm_release.zitadel, local_file.zitadel_jwt_profile_file]
}
output "server" {
value = local.service_uri
}
-output "default_tenant_id" {
- value = random_uuid.default_tenant_id.result
-}
-
output "uri" {
value = "https://${local.service_uri}"
}
diff --git a/infra/modules/zitadel/project/application/api/main.tf b/infra/modules/zitadel/project/application/api/main.tf
index 9895069..dbd13e8 100644
--- a/infra/modules/zitadel/project/application/api/main.tf
+++ b/infra/modules/zitadel/project/application/api/main.tf
@@ -1,17 +1,29 @@
-resource "zitadel_project_member" "default" {
+resource "zitadel_application_api" "default" {
depends_on = [var.wait_on]
org_id = var.org_id
project_id = var.project_id
- user_id = var.user_id
- roles = var.roles
+
+ name = var.name
+ auth_method_type = "API_AUTH_METHOD_TYPE_BASIC"
+ // TODO: Change this to private key jwt in the future
}
output "installed" {
value = true
- depends_on = [zitadel_project_member.default]
+ depends_on = [zitadel_application_api.default]
}
-output "project_member_id" {
- value = zitadel_project_member.default.id
+output "application_id" {
+ value = zitadel_application_api.default.id
+}
+
+output "client_id" {
+ value = zitadel_application_api.default.client_id
+ sensitive = true
+}
+
+output "client_secret" {
+ value = zitadel_application_api.default.client_secret
+ sensitive = true
}
diff --git a/infra/modules/zitadel/project/application/api/variables.tf b/infra/modules/zitadel/project/application/api/variables.tf
index ae9b5e2..622dd71 100644
--- a/infra/modules/zitadel/project/application/api/variables.tf
+++ b/infra/modules/zitadel/project/application/api/variables.tf
@@ -24,3 +24,8 @@ variable "project_id" {
type = string
description = "Project Id"
}
+
+variable "name" {
+ type = string
+ description = "Application name"
+}
diff --git a/infra/modules/zitadel/project/application/user-agent/main.tf b/infra/modules/zitadel/project/application/user-agent/main.tf
index 220b565..4391c5b 100644
--- a/infra/modules/zitadel/project/application/user-agent/main.tf
+++ b/infra/modules/zitadel/project/application/user-agent/main.tf
@@ -1,10 +1,37 @@
resource "zitadel_application_oidc" "default" {
depends_on = [var.wait_on]
- org_id = var.org_id
- project_id = var.project_id
- name = var.name
+ org_id = var.org_id
+ grant_types = ["OIDC_GRANT_TYPE_AUTHORIZATION_CODE"]
+ name = var.name
+ project_id = var.project_id
+
+ redirect_uris = var.redirect_uris
+ response_types = ["OIDC_RESPONSE_TYPE_CODE"]
+
+ # // If selected, the requested roles of the authenticated user are added to the access token.
+ #access_token_type = "OIDC_TOKEN_TYPE_JWT"
+ #access_token_role_assertion = true
+
+ # BEARER uses an Opaque token, which needs the introspection endpoint and `urn:zitadel:iam:org:project:id::aud` scope
+ access_token_type = "OIDC_TOKEN_TYPE_BEARER"
+
+ # // If you want to add additional Origins to your app which is not used as a redirect you can do that here.
+ #additional_origins = []
+
+ app_type = "OIDC_APP_TYPE_USER_AGENT"
+ auth_method_type = "OIDC_AUTH_METHOD_TYPE_NONE"
+
+ # // Redirect URIs must begin with https:// unless dev_mode is true
+ #dev_mode = false
+
+ # // If selected, the requested roles of the authenticated user are added to the ID token.
+ #id_token_role_assertion = false
+ # // Enables clients to retrieve profile, email, phone and address claims from ID token.
+ #id_token_userinfo_assertion = false
+
+ post_logout_redirect_uris = var.post_logout_redirect_uris
}
output "installed" {
diff --git a/infra/modules/zitadel/project/application/user-agent/variables.tf b/infra/modules/zitadel/project/application/user-agent/variables.tf
index 6ed21a6..2459275 100644
--- a/infra/modules/zitadel/project/application/user-agent/variables.tf
+++ b/infra/modules/zitadel/project/application/user-agent/variables.tf
@@ -30,7 +30,11 @@ variable "name" {
description = "Application name"
}
-variable "api_url" {
- type = string
- description = "Uri on which the API is available"
+variable "redirect_uris" {
+ type = list(string)
+}
+
+variable "post_logout_redirect_uris" {
+ type = list(string)
+ default = []
}
diff --git a/infra/modules/zitadel/project/main.tf b/infra/modules/zitadel/project/main.tf
index e116eeb..611f668 100644
--- a/infra/modules/zitadel/project/main.tf
+++ b/infra/modules/zitadel/project/main.tf
@@ -1,44 +1,27 @@
-resource "zitadel_org_idp_google" "default" {
+resource "zitadel_project" "default" {
depends_on = [var.wait_on]
- org_id = var.org_id
- name = "Google"
- client_id = var.client_id
- client_secret = var.client_secret
- scopes = var.options.scopes
- is_linking_allowed = var.options.is_linking_allowed
- is_creation_allowed = var.options.is_creation_allowed
- is_auto_creation = var.options.is_auto_creation
- is_auto_update = var.options.is_auto_update
- auto_linking = var.options.auto_linking
+ org_id = var.org_id
+ name = var.name
+ project_role_assertion = true
+ project_role_check = true
+ has_project_check = true
+ private_labeling_setting = "PRIVATE_LABELING_SETTING_ENFORCE_PROJECT_RESOURCE_OWNER_POLICY"
}
-resource "zitadel_login_policy" "default" {
- depends_on = [zitadel_org_idp_google.default]
+resource "zitadel_project_member" "default" {
+ count = length(var.owners)
- org_id = var.org_id
- user_login = true
- allow_register = true
- allow_external_idp = true
- force_mfa = false
- force_mfa_local_only = false
- passwordless_type = "PASSWORDLESS_TYPE_ALLOWED"
- hide_password_reset = "false"
- password_check_lifetime = "240h0m0s"
- external_login_check_lifetime = "240h0m0s"
- multi_factor_check_lifetime = "24h0m0s"
- mfa_init_skip_lifetime = "720h0m0s"
- second_factor_check_lifetime = "24h0m0s"
- ignore_unknown_usernames = true
- default_redirect_uri = "https://${var.domain}"
- second_factors = ["SECOND_FACTOR_TYPE_OTP", "SECOND_FACTOR_TYPE_U2F"]
- multi_factors = ["MULTI_FACTOR_TYPE_U2F_WITH_VERIFICATION"]
- idps = [zitadel_org_idp_google.default.id]
- allow_domain_discovery = true
- disable_login_with_email = true
- disable_login_with_phone = true
+ org_id = var.org_id
+ project_id = zitadel_project.default.id
+ user_id = var.owners[count.index]
+ roles = ["PROJECT_OWNER"]
}
output "installed" {
value = true
- depends_on = [zitadel_org_idp_google.default, zitadel_login_policy.default]
+ depends_on = [zitadel_project.default, zitadel_project_member.default]
+}
+
+output "project_id" {
+ value = zitadel_project.default.id
}
diff --git a/infra/modules/zitadel/project/member/main.tf b/infra/modules/zitadel/project/member/main.tf
index a7322b4..9895069 100644
--- a/infra/modules/zitadel/project/member/main.tf
+++ b/infra/modules/zitadel/project/member/main.tf
@@ -1,21 +1,17 @@
-resource "zitadel_project_role" "default" {
- count = length(var.roles)
+resource "zitadel_project_member" "default" {
depends_on = [var.wait_on]
- org_id = var.org_id
- project_id = var.project_id
- role_key = var.roles[count.index]
- display_name = var.roles[count.index]
- group = var.group
+ org_id = var.org_id
+ project_id = var.project_id
+ user_id = var.user_id
+ roles = var.roles
}
output "installed" {
value = true
- depends_on = [zitadel_project_role.default]
+ depends_on = [zitadel_project_member.default]
}
-output "role_ids" {
- value = toset([
- for role in zitadel_project_role.default : role.id
- ])
+output "project_member_id" {
+ value = zitadel_project_member.default.id
}
diff --git a/infra/modules/zitadel/project/member/variables.tf b/infra/modules/zitadel/project/member/variables.tf
index 0b5b575..a4b6976 100644
--- a/infra/modules/zitadel/project/member/variables.tf
+++ b/infra/modules/zitadel/project/member/variables.tf
@@ -25,14 +25,13 @@ variable "project_id" {
description = "Project Id"
}
-variable "group" {
+variable "user_id" {
type = string
- description = "Optional group name"
- default = null
+ description = "User Id"
}
variable "roles" {
type = list(string)
- description = "Roles to be added"
+ description = "Roles to be granted"
default = []
}
diff --git a/infra/modules/zitadel/project/roles/main.tf b/infra/modules/zitadel/project/roles/main.tf
index 611f668..e8132b5 100644
--- a/infra/modules/zitadel/project/roles/main.tf
+++ b/infra/modules/zitadel/project/roles/main.tf
@@ -1,27 +1,25 @@
-resource "zitadel_project" "default" {
+resource "zitadel_project_role" "default" {
+ count = length(var.roles)
depends_on = [var.wait_on]
- org_id = var.org_id
- name = var.name
- project_role_assertion = true
- project_role_check = true
- has_project_check = true
- private_labeling_setting = "PRIVATE_LABELING_SETTING_ENFORCE_PROJECT_RESOURCE_OWNER_POLICY"
-}
-resource "zitadel_project_member" "default" {
- count = length(var.owners)
-
- org_id = var.org_id
- project_id = zitadel_project.default.id
- user_id = var.owners[count.index]
- roles = ["PROJECT_OWNER"]
+ org_id = var.org_id
+ project_id = var.project_id
+ role_key = var.roles[count.index]
+ display_name = var.roles[count.index]
+ group = var.group
}
output "installed" {
value = true
- depends_on = [zitadel_project.default, zitadel_project_member.default]
+ depends_on = [zitadel_project_role.default]
}
-output "project_id" {
- value = zitadel_project.default.id
+output "role_ids" {
+ value = toset([
+ for role in zitadel_project_role.default : role.id
+ ])
+}
+
+output "roles" {
+ value = var.roles
}
diff --git a/infra/modules/zitadel/project/roles/variables.tf b/infra/modules/zitadel/project/roles/variables.tf
index 28d991a..0b5b575 100644
--- a/infra/modules/zitadel/project/roles/variables.tf
+++ b/infra/modules/zitadel/project/roles/variables.tf
@@ -20,13 +20,19 @@ variable "org_id" {
description = "Organisation Id"
}
-variable "name" {
+variable "project_id" {
type = string
- description = "Name of the project"
+ description = "Project Id"
}
-variable "owners" {
+variable "group" {
+ type = string
+ description = "Optional group name"
+ default = null
+}
+
+variable "roles" {
type = list(string)
- description = "User IDs to be granted `PROJECT_OWNER` role"
+ description = "Roles to be added"
default = []
}
diff --git a/infra/modules/zitadel/project/variables.tf b/infra/modules/zitadel/project/variables.tf
index c648d93..28d991a 100644
--- a/infra/modules/zitadel/project/variables.tf
+++ b/infra/modules/zitadel/project/variables.tf
@@ -20,31 +20,13 @@ variable "org_id" {
description = "Organisation Id"
}
-variable "client_id" {
+variable "name" {
type = string
- description = "Google Client ID"
+ description = "Name of the project"
}
-variable "client_secret" {
- type = string
- description = "Google Client Secret"
-}
-
-variable "options" {
- type = object({
- scopes = list(string)
- is_linking_allowed = bool
- is_creation_allowed = bool
- is_auto_creation = bool
- is_auto_update = bool
- auto_linking = string
- })
- default = {
- scopes = ["openid", "profile", "email"],
- is_linking_allowed = false
- is_creation_allowed = true
- is_auto_creation = false
- is_auto_update = true
- auto_linking = "AUTO_LINKING_OPTION_USERNAME"
- }
+variable "owners" {
+ type = list(string)
+ description = "User IDs to be granted `PROJECT_OWNER` role"
+ default = []
}
diff --git a/infra/modules/zitadel/service-account/main.tf b/infra/modules/zitadel/service-account/main.tf
index a7322b4..316714c 100644
--- a/infra/modules/zitadel/service-account/main.tf
+++ b/infra/modules/zitadel/service-account/main.tf
@@ -1,21 +1,29 @@
-resource "zitadel_project_role" "default" {
- count = length(var.roles)
+resource "zitadel_machine_user" "default" {
depends_on = [var.wait_on]
- org_id = var.org_id
- project_id = var.project_id
- role_key = var.roles[count.index]
- display_name = var.roles[count.index]
- group = var.group
+ org_id = var.org_id
+ user_name = var.user_name
+ name = var.name
+ description = var.description
+ with_secret = var.with_secret
+ access_token_type = var.access_token_type
}
output "installed" {
value = true
- depends_on = [zitadel_project_role.default]
+ depends_on = [zitadel_machine_user.default]
}
-output "role_ids" {
- value = toset([
- for role in zitadel_project_role.default : role.id
- ])
+output "user_id" {
+ value = zitadel_machine_user.default.id
+}
+
+output "client_id" {
+ value = zitadel_machine_user.default.client_id
+ sensitive = true
+}
+
+output "client_secret" {
+ value = zitadel_machine_user.default.client_secret
+ sensitive = true
}
diff --git a/infra/modules/zitadel/service-account/variables.tf b/infra/modules/zitadel/service-account/variables.tf
index 0b5b575..b80205d 100644
--- a/infra/modules/zitadel/service-account/variables.tf
+++ b/infra/modules/zitadel/service-account/variables.tf
@@ -20,19 +20,25 @@ variable "org_id" {
description = "Organisation Id"
}
-variable "project_id" {
- type = string
- description = "Project Id"
+variable "user_name" {
+ type = string
}
-variable "group" {
- type = string
- description = "Optional group name"
- default = null
+variable "name" {
+ type = string
}
-variable "roles" {
- type = list(string)
- description = "Roles to be added"
- default = []
+variable "description" {
+ type = string
+ default = null
+}
+
+variable "with_secret" {
+ type = bool
+ default = false
+}
+
+variable "access_token_type" {
+ type = string
+ default = "ACCESS_TOKEN_TYPE_JWT"
}
diff --git a/infra/modules/zitadel/tenant/main.tf b/infra/modules/zitadel/tenant/main.tf
index e69de29..82c80b0 100644
--- a/infra/modules/zitadel/tenant/main.tf
+++ b/infra/modules/zitadel/tenant/main.tf
@@ -0,0 +1,14 @@
+resource "zitadel_org" "default" {
+ depends_on = [var.wait_on]
+ name = var.name
+ is_default = true
+}
+
+output "org_id" {
+ value = zitadel_org.default.id
+}
+
+output "installed" {
+ value = true
+ depends_on = [zitadel_org.default]
+}
diff --git a/infra/modules/zitadel/tenant/provider.tf b/infra/modules/zitadel/tenant/provider.tf
index e69de29..653009c 100644
--- a/infra/modules/zitadel/tenant/provider.tf
+++ b/infra/modules/zitadel/tenant/provider.tf
@@ -0,0 +1,14 @@
+terraform {
+ required_providers {
+ zitadel = {
+ source = "zitadel/zitadel"
+ version = "2.0.2"
+ }
+ }
+}
+
+provider "zitadel" {
+ domain = var.domain
+ insecure = "false"
+ jwt_profile_file = var.jwt_profile_file
+}
diff --git a/infra/modules/zitadel/tenant/role-owner/main.tf b/infra/modules/zitadel/tenant/role-owner/main.tf
index e8f5117..4605410 100644
--- a/infra/modules/zitadel/tenant/role-owner/main.tf
+++ b/infra/modules/zitadel/tenant/role-owner/main.tf
@@ -1,30 +1,11 @@
-resource "zitadel_org" "default" {
+resource "zitadel_org_member" "default" {
depends_on = [var.wait_on]
- name = var.name
- is_default = true
-}
-
-output "org_id" {
- value = zitadel_org.default.id
+ org_id = var.org_id
+ user_id = var.user_id
+ roles = ["ORG_OWNER"]
}
output "installed" {
value = true
- depends_on = [zitadel_org.default]
+ depends_on = [zitadel_org_member.default]
}
-
-
-#resource "zitadel_idp_google" "default" {
-# name = "Google"
-# client_id = "182902..."
-# client_secret = "GOCSPX-*****"
-# scopes = ["openid", "profile", "email"]
-# is_linking_allowed = false
-# is_creation_allowed = true
-# is_auto_creation = false
-# is_auto_update = true
-# auto_linking = "AUTO_LINKING_OPTION_USERNAME"
-#}
-
-#google_client_id = "783390190667-0nkts50perpmhott4i7ro1ob5n7koi5i.apps.googleusercontent.com"
-#google_client_secret = "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"
diff --git a/infra/modules/zitadel/tenant/role-owner/variables.tf b/infra/modules/zitadel/tenant/role-owner/variables.tf
index f7674df..c5318a6 100644
--- a/infra/modules/zitadel/tenant/role-owner/variables.tf
+++ b/infra/modules/zitadel/tenant/role-owner/variables.tf
@@ -10,10 +10,14 @@ variable "wait_on" {
default = true
}
-variable "name" {
+variable "org_id" {
type = string
- description = "Name of the tenant"
- default = "fourlights"
+ description = "Zitadel Organization ID"
+}
+
+variable "user_id" {
+ type = string
+ description = "Zitadel User ID"
}
variable "jwt_profile_file" {
diff --git a/infra/modules/zitadel/tenant/variables.tf b/infra/modules/zitadel/tenant/variables.tf
index 5916ab1..f7674df 100644
--- a/infra/modules/zitadel/tenant/variables.tf
+++ b/infra/modules/zitadel/tenant/variables.tf
@@ -1,17 +1,7 @@
-variable "service_name" {
- type = string
- description = "Name of the service"
- default = "auth"
-}
-
-variable "server_dns" {
- type = string
- description = "Domain for the server"
-}
-
-variable "k8s_config_yaml" {
- description = "Content of k8s config yaml file"
+variable "domain" {
type = string
+ description = "Domain for the zitadel instance"
+ default = "localhost"
}
variable "wait_on" {
@@ -20,37 +10,13 @@ variable "wait_on" {
default = true
}
-variable "namespace" {
- type = string
+variable "name" {
+ type = string
+ description = "Name of the tenant"
+ default = "fourlights"
}
-variable "database" {
- type = string
- default = "zitadel"
-}
-
-variable "database_username" {
- type = string
- default = "zitadel"
-}
-
-variable "database_password" {
- type = string
- sensitive = true
-}
-
-variable "database_root_username" {
- type = string
- default = "postgres"
-}
-
-variable "database_root_password" {
- type = string
- sensitive = true
- default = null
-}
-
-variable "display_on_homepage" {
- type = bool
- default = false
+variable "jwt_profile_file" {
+ type = string
+ description = "Path to the jwt profile file"
}
diff --git a/infra/modules/zitadel/values.yaml.tftpl b/infra/modules/zitadel/values.yaml.tftpl
index 1a11e3f..47bc5ed 100644
--- a/infra/modules/zitadel/values.yaml.tftpl
+++ b/infra/modules/zitadel/values.yaml.tftpl
@@ -1,16 +1,26 @@
zitadel:
masterkeySecretName: "zitadel"
configmapConfig:
- ExternalSecure: false
- ExternalDomain: ${ external_domain }
+ Log:
+ Level: 'info'
+ LogStore:
+ Access:
+ Stdout:
+ Enabled: true
+ ExternalSecure: true
+ ExternalDomain: ${ service_uri }
+ ExternalPort: 443
TLS:
Enabled: false
- #ExternalPort: 443
- #ExternalSecurePort: 443
- #ExternalPathPrefix: ${ external_path_prefix }
- #ExternalTLS: false
- #ExternalTLSAllowInsecure: false
- #ExternalTLSAllowInsecureSkipVerify: false
+ FirstInstance:
+ Org:
+ Machine:
+ Machine:
+ Username: zitadel-admin-sa
+ Name: Admin
+ MachineKey:
+ ExpirationDate: "2026-01-01T00:00:00Z"
+ Type: 1
Database:
Postgres:
Host: postgresql-hl.postgresql.svc.cluster.local
@@ -22,14 +32,28 @@ zitadel:
MaxConnIdleTime: 5m
User:
Username: ${ database_username }
- PasswordSecret: postgresql-auth
- PasswordSecretKey: password
+ Password: "${ database_password }"
SSL:
Mode: disable
- Admin:
+ %{ if database_root_username != null }Admin:
Username: ${ database_root_username }
- PasswordSecret: postgresql-auth
- PasswordSecretKey: root-password
+ Password: "${ database_root_password }"
+ SSL:
+ Mode: disable
+ %{ endif }
+
+readinessProbe:
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ failureThreshold: 10
+
+startupProbe:
+ periodSeconds: 5
+ failureThreshold: 30
+
+service:
+ annotations:
+ traefik.ingress.kubernetes.io/service.serversscheme: h2c
ingress:
enabled: true
@@ -37,8 +61,8 @@ ingress:
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
- %{ if displayOnHomepage }
- gethomepage.dev/enabled: "true"
+ traefik.ingress.kubernetes.io/router.middlewares: default-preserve-host-headers@kubernetescrd
+ %{ if display_on_homepage }gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Zitadel"
gethomepage.dev/description: "Identity and Access Management"
gethomepage.dev/group: "Tools"
@@ -49,3 +73,4 @@ ingress:
paths:
- path: /
pathType: Prefix
+
diff --git a/infra/modules/zitadel/variables.tf b/infra/modules/zitadel/variables.tf
index 8f92245..68e3db6 100644
--- a/infra/modules/zitadel/variables.tf
+++ b/infra/modules/zitadel/variables.tf
@@ -26,12 +26,12 @@ variable "namespace" {
variable "database" {
type = string
- default = "fusionauth"
+ default = "zitadel"
}
variable "database_username" {
type = string
- default = "fusionauth"
+ default = "zitadel"
}
variable "database_password" {
@@ -49,3 +49,13 @@ variable "database_root_password" {
sensitive = true
default = null
}
+
+variable "display_on_homepage" {
+ type = bool
+ default = false
+}
+
+variable "enabled" {
+ type = bool
+ default = true
+}
diff --git a/shuttles/terraform-configure/main.tf b/shuttles/terraform-configure/main.tf
deleted file mode 100644
index 58151c5..0000000
--- a/shuttles/terraform-configure/main.tf
+++ /dev/null
@@ -1,174 +0,0 @@
-locals {
- tld = "fourlights.dev"
- cluster_dns = "venus.${local.tld}"
- bridge_dns = "bridge.${local.cluster_dns}"
- is_installed = true
- node_count = 3
-}
-
-resource "kubernetes_manifest" "preserve-host-middleware" {
- depends_on = [local.is_installed]
- manifest = {
- apiVersion = "traefik.io/v1alpha1"
- kind = "Middleware"
- metadata = {
- name = "preserve-host-headers"
- namespace = "default" # NOTE: Hardcoded by design
- }
- spec = {
- headers = {
- customRequestHeaders = {
- "X-Forwarded-Proto" = "https"
- "X-Forwarded-Port" = "443"
- }
- }
- }
- }
-}
-
-resource "kubernetes_manifest" "https-redirect-middleware" {
- depends_on = [local.is_installed]
- manifest = {
- apiVersion = "traefik.io/v1alpha1"
- kind = "Middleware"
- metadata = {
- name = "redirect-to-https"
- namespace = "default" # NOTE: Hardcoded by design
- }
- spec = {
- redirectScheme = {
- permanent = true
- scheme = "https"
- }
- }
- }
-}
-
-module "homepage" {
- source = "../../infra/modules/homepage"
- wait_on = local.is_installed
- k8s_config_yaml = local.k8s_config_yaml
-
- server_dns = local.cluster_dns
- service_name = "homepage"
- service_uri = local.cluster_dns
- namespace = "homepage"
-}
-
-module "minio" {
- source = "../../infra/modules/minio"
- wait_on = local.is_installed
- k8s_config_yaml = local.k8s_config_yaml
-
- server_dns = local.cluster_dns
- service_name = "storage"
- namespace = "minio"
-
- admin_server_dns = local.cluster_dns # Restricted admin access, access via bridge
-
- tls = false
- admin = true
- ingressClass = "traefik"
- storageSize = "10Gi"
-
- displayOnHomepage = true
-}
-
-module "mongodb" {
- source = "../../infra/modules/mongodb"
- wait_on = local.is_installed
- k8s_config_yaml = local.k8s_config_yaml
-
- namespace = "mongodb"
- replicas = local.node_count
-}
-
-module "rabbitmq" {
- source = "../../infra/modules/rabbitmq"
- wait_on = local.is_installed
- k8s_config_yaml = local.k8s_config_yaml
-
- server_dns = "local" # Restricted admin access, access via bridge
-
- service_name = "rabbitmq"
- namespace = "rabbitmq"
-
- tls = false
- admin = true
- ingressClass = "traefik"
-}
-
-module "postgresql" {
- source = "../../infra/modules/postgresql"
-
- namespace = "postgresql"
- k8s_config_yaml = local.k8s_config_yaml
- username = "bridge"
-}
-
-module "zitadel-db" {
- source = "../../infra/modules/postgresql/tenant"
- wait_on = module.postgresql.installed
-
- name = "zitadel"
- root_password = module.postgresql.root_password
- k8s_config_yaml = local.k8s_config_yaml
-}
-
-module "zitadel" {
- source = "../../infra/modules/zitadel"
- wait_on = module.zitadel-db.installed
- k8s_config_yaml = local.k8s_config_yaml
-
- server_dns = local.cluster_dns
-
- service_name = "zitadel"
- namespace = "zitadel"
-
- database_password = module.zitadel-db.password
- database_root_password = module.postgresql.root_password
-
- display_on_homepage = true
-}
-
-module "zitadel-tenant" {
- source = "../../infra/modules/zitadel/tenant"
- wait_on = module.zitadel.installed
-
- domain = module.zitadel.server
- name = "fourlights"
- jwt_profile_file = module.zitadel.jwt_profile_file
-}
-
-module "zitadel-idp-google" {
- source = "../../infra/modules/zitadel/identity-provider/google"
- wait_on = module.zitadel-tenant.installed
-
- domain = module.zitadel.server
- jwt_profile_file = module.zitadel.jwt_profile_file
- org_id = module.zitadel-tenant.org_id
- client_id = "783390190667-0nkts50perpmhott4i7ro1ob5n7koi5i.apps.googleusercontent.com"
- client_secret = "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"
-
- options = {
- scopes = ["openid", "profile", "email"]
- is_auto_creation = true
- is_auto_update = true
- is_creation_allowed = true
- is_linking_allowed = false
-
- auto_linking = "AUTO_LINKING_OPTION_USERNAME"
- }
-}
-
-// module "zitadel-machine-user" {
-// source = "../../infra/modules/zitadel/tenant"
-// wait_on = module.zitadel.installed
-// k8s_config_yaml = local.k8s_config_yaml
-//
-// domain = module.zitadel.server
-// secret = "zitadel-admin-sa"
-// namespace = "zitadel"
-// name = "fourlights"
-// }
-
diff --git a/shuttles/terraform-zitadel-bootstrap/.terraform.lock.hcl b/shuttles/terraform-zitadel-bootstrap/.terraform.lock.hcl
new file mode 100644
index 0000000..287ac57
--- /dev/null
+++ b/shuttles/terraform-zitadel-bootstrap/.terraform.lock.hcl
@@ -0,0 +1,25 @@
+# This file is maintained automatically by "terraform init".
+# Manual edits may be lost in future updates.
+
+provider "registry.terraform.io/zitadel/zitadel" {
+ version = "2.0.2"
+ constraints = "2.0.2"
+ hashes = [
+ "h1:iymeaNBrZ4smcr7eHrxO4gbXQ6bx/enKyj3RQ6xZRYA=",
+ "zh:01e16af0dda9372696b5e1d43ec709aed79829b49ee69a4f9606a248752f672d",
+ "zh:048c4e726fb846cfe9ab0a0a1f86d3f8922442154b086e2bd8e389b32f69f2f0",
+ "zh:3a3f6bea621c9d480f1f288cffebace8620979b9260cfeae8f9af5d9a25ed490",
+ "zh:4d349e584786589bc2037cee691ff1678296f5351e6491aa34dcb08ecbe1dcb7",
+ "zh:80741c78179788be8d7e33e471e1311197cd4e1067803d438463d0a8ac871a60",
+ "zh:89178d30f5ec49551e6a6ebc5eb589ab6631012dcec0d03ea7130b1029890e51",
+ "zh:94cd3b1fe3d1d39bcb3b70208b044bde4c5ce5152e12b29f0fa0ff1085e12863",
+ "zh:97299c172ada852705f8ca9fa91eeee12c6259263baae3ca53cf41e3130b1731",
+ "zh:a33d53acc640dc93b81352ba633cf392bc8c7614a72d320d59d3dcdb22d73fc4",
+ "zh:a95c15960baf8157f79a6490361455767d48e4dd3ce2ef1d0051743f6152733b",
+ "zh:ae66ad95c7039e6ef844c39389c9077ce7dbb501b6af02afb26a223fd289dbcb",
+ "zh:b8a9cb3b53653c06d52607368c406112ee1abc6d66dc4aedaedddbb46a66ea8f",
+ "zh:d48693ecdc985bb4167af0c3164240c13c4ea48167d28f706e7893cbdb20540a",
+ "zh:f6db1ec30bfbcf4423ab2d29979b775423ba37008fd48a766b5a1cf87a131859",
+ "zh:fed4e95dc9aaf361c8ff57f819d31fa25152b9e6cb90b7202d8be9ab1446b081",
+ ]
+}
diff --git a/shuttles/terraform-zitadel-bootstrap/main.tf b/shuttles/terraform-zitadel-bootstrap/main.tf
new file mode 100644
index 0000000..aa8550f
--- /dev/null
+++ b/shuttles/terraform-zitadel-bootstrap/main.tf
@@ -0,0 +1,115 @@
+locals {
+ tld = "fourlights.dev"
+ cluster_dns = "venus.${local.tld}"
+ domain = "zitadel.${local.cluster_dns}"
+ jwt_profile_file = "../terraform/zitadel-admin-sa.json"
+}
+
+
+module "zitadel-tenant" {
+ source = "../../infra/modules/zitadel/tenant"
+
+ domain = local.domain
+ name = "fourlights"
+ jwt_profile_file = local.jwt_profile_file
+}
+
+module "zitadel-idp-google" {
+ source = "../../infra/modules/zitadel/identity-provider/google"
+ wait_on = module.zitadel-tenant.installed
+
+ domain = local.domain
+ jwt_profile_file = local.jwt_profile_file
+ org_id = module.zitadel-tenant.org_id
+ client_id = "783390190667-quvko2l2kr9ksgeo3pn6pn6t8c1mai9n.apps.googleusercontent.com"
+ client_secret = "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"
+
+ options = {
+ scopes = ["openid", "profile", "email"]
+ is_auto_creation = true
+ is_auto_update = true
+ is_creation_allowed = true
+ is_linking_allowed = false
+
+ auto_linking = "AUTO_LINKING_OPTION_USERNAME"
+ }
+}
+
+// TODO: Create default user thomas@fourlights.nl
+
+# module "zitadel-user" {
+# source = "../../infra/modules/zitadel/user"
+# wait_on = module.zitadel-idp-google.installed
+#
+# domain = local.domain
+# org_id = module.zitadel-tenant.org_id
+# jwt_profile_file = local.jwt_profile_file
+#
+# email = "thomas@fourlights.nl"
+# idp_id = module.zitadel-idp-google.idp_id
+# idp_user_id = "105558048282918392820"
+# user_id = "308083708882059797"
+# }
+module "zitadel-owner" {
+ source = "../../infra/modules/zitadel/owner"
+ #wait_on = module.zitadel-user.installed
+ wait_on = module.zitadel-idp-google.installed
+
+ domain = local.domain
+ org_id = module.zitadel-tenant.org_id
+ jwt_profile_file = local.jwt_profile_file
+ #user_id = module.zitadel-user.user_id
+ user_id = "308083708882059797"
+}
+
+module "zitadel-org-owner" {
+ source = "../../infra/modules/zitadel/tenant/role-owner"
+ #wait_on = module.zitadel-user.installed
+ wait_on = module.zitadel-idp-google.installed
+
+ domain = local.domain
+ org_id = module.zitadel-tenant.org_id
+ jwt_profile_file = local.jwt_profile_file
+ #user_id = module.zitadel-user.user_id
+ user_id = "308083708882059797"
+}
+
+module "zitadel-project" {
+ source = "../../infra/modules/zitadel/tenant/role-owner"
+ #wait_on = module.zitadel-user.installed
+ wait_on = module.zitadel-idp-google.installed
+
+ domain = local.domain
+ org_id = module.zitadel-tenant.org_id
+ jwt_profile_file = local.jwt_profile_file
+ #user_id = module.zitadel-user.user_id
+ user_id = "308083708882059797"
+}
+
+#resource "zitadel_project" "default" {
+# name = "365zon"
+# org_id = module.zitadel-tenant.org_id
+# project_role_assertion = true
+# project_role_check = true
+# has_project_check = true
+# private_labeling_setting = "PRIVATE_LABELING_SETTING_ENFORCE_PROJECT_RESOURCE_OWNER_POLICY"
+#}
+#
+#resource "zitadel_user_grant" "default" {
+# project_id = data.zitadel_project.default.id
+# org_id = data.zitadel_org.default.id
+# role_keys = ["super-user"]
+# user_id = data.zitadel_human_user.default.id
+#}
+
+// module "zitadel-machine-user" {
+// source = "../../infra/modules/zitadel/tenant"
+// wait_on = module.zitadel.installed
+// k8s_config_yaml = local.k8s_config_yaml
+//
+// domain = module.zitadel.server
+// secret = "zitadel-admin-sa"
+// namespace = "zitadel"
+// name = "fourlights"
+// }
+
diff --git a/shuttles/terraform/.terraform.lock.hcl b/shuttles/terraform/.terraform.lock.hcl
index 8c5ae0a..e232ef7 100644
--- a/shuttles/terraform/.terraform.lock.hcl
+++ b/shuttles/terraform/.terraform.lock.hcl
@@ -39,21 +39,41 @@ provider "registry.terraform.io/hashicorp/helm" {
}
provider "registry.terraform.io/hashicorp/kubernetes" {
- version = "2.35.1"
+ version = "2.31.0"
+ constraints = "2.31.0"
hashes = [
- "h1:Av0Wk8g2XjY2oap7nyWNHEgfCRfphdJvrkqJjEM2ZKM=",
- "zh:12212ca5ae47823ce14bfafb909eeb6861faf1e2435fb2fc4a8b334b3544b5f5",
- "zh:3f49b3d77182df06b225ab266667de69681c2e75d296867eb2cf06a8f8db768c",
- "zh:40832494d19f8a2b3cd0c18b80294d0b23ef6b82f6f6897b5fe00248a9997460",
- "zh:739a5ddea61a77925ee7006a29c8717377a2e9d0a79a0bbd98738d92eec12c0d",
- "zh:a02b472021753627c5c39447a56d125a32214c29ff9108fc499f2dcdf4f1cc4f",
- "zh:b78865b3867065aa266d6758c9601a2756741478f5735a838c20d633d65e085b",
- "zh:d362e87464683f5632790e66920ea803adb54c2bc0cb24b6fd9a314d2b1efffd",
- "zh:d98206fe88c2c9a52b8d2d0cb2c877c812a4a51d19f9d8428e63cbd5fd8a304d",
- "zh:dfa320946b1ce3f3615c42b3447a28dc9f604c06d8b9a6fe289855ab2ade4d11",
+ "h1:wGHbATbv/pBVTST1MtEn0zyVhZbzZJD2NYq2EddASHY=",
+ "zh:0d16b861edb2c021b3e9d759b8911ce4cf6d531320e5dc9457e2ea64d8c54ecd",
+ "zh:1bad69ed535a5f32dec70561eb481c432273b81045d788eb8b37f2e4a322cc40",
+ "zh:43c58e3912fcd5bb346b5cb89f31061508a9be3ca7dd4cd8169c066203bcdfb3",
+ "zh:4778123da9206918a92dfa73cc711475d2b9a8275ff25c13a30513c523ac9660",
+ "zh:8bfa67d2db03b3bfae62beebe6fb961aee8d91b7a766efdfe4d337b33dfd23dd",
+ "zh:9020bb5729db59a520ade5e24984b737e65f8b81751fbbd343926f6d44d22176",
+ "zh:90431dbfc5b92498bfbce38f0b989978c84421a6c33245b97788a46b563fbd6e",
+ "zh:b71a061dda1244f6a52500e703a9524b851e7b11bbf238c17bbd282f27d51cb2",
+ "zh:d6232a7651b834b89591b94bf4446050119dcde740247e6083a4d55a2cefd28a",
+ "zh:d89fba43e699e28e2b5e92fff2f75fc03dbc8de0df9dacefe1a8836f8f430753",
+ "zh:ef85c0b744f5ba1b10dadc3c11e331ba4225c45bb733e024d7218c24b02b0512",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
- "zh:fc1debd2e695b5222d2ccc8b24dab65baba4ee2418ecce944e64d42e79474cb5",
- "zh:fdaf960443720a238c09e519aeb30faf74f027ac5d1e0a309c3b326888e031d7",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/local" {
+ version = "2.5.2"
+ hashes = [
+ "h1:JlMZD6nYqJ8sSrFfEAH0Vk/SL8WLZRmFaMUF9PJK5wM=",
+ "zh:136299545178ce281c56f36965bf91c35407c11897f7082b3b983d86cb79b511",
+ "zh:3b4486858aa9cb8163378722b642c57c529b6c64bfbfc9461d940a84cd66ebea",
+ "zh:4855ee628ead847741aa4f4fc9bed50cfdbf197f2912775dd9fe7bc43fa077c0",
+ "zh:4b8cd2583d1edcac4011caafe8afb7a95e8110a607a1d5fb87d921178074a69b",
+ "zh:52084ddaff8c8cd3f9e7bcb7ce4dc1eab00602912c96da43c29b4762dc376038",
+ "zh:71562d330d3f92d79b2952ffdda0dad167e952e46200c767dd30c6af8d7c0ed3",
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
+ "zh:805f81ade06ff68fa8b908d31892eaed5c180ae031c77ad35f82cb7a74b97cf4",
+ "zh:8b6b3ebeaaa8e38dd04e56996abe80db9be6f4c1df75ac3cccc77642899bd464",
+ "zh:ad07750576b99248037b897de71113cc19b1a8d0bc235eb99173cc83d0de3b1b",
+ "zh:b9f1c3bfadb74068f5c205292badb0661e17ac05eb23bfe8bd809691e4583d0e",
+ "zh:cc4cbcd67414fefb111c1bf7ab0bc4beb8c0b553d01719ad17de9a047adff4d1",
]
}
@@ -75,3 +95,26 @@ provider "registry.terraform.io/hashicorp/random" {
"zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0",
]
}
+
+provider "registry.terraform.io/zitadel/zitadel" {
+ version = "2.0.2"
+ constraints = "2.0.2"
+ hashes = [
+ "h1:iymeaNBrZ4smcr7eHrxO4gbXQ6bx/enKyj3RQ6xZRYA=",
+ "zh:01e16af0dda9372696b5e1d43ec709aed79829b49ee69a4f9606a248752f672d",
+ "zh:048c4e726fb846cfe9ab0a0a1f86d3f8922442154b086e2bd8e389b32f69f2f0",
+ "zh:3a3f6bea621c9d480f1f288cffebace8620979b9260cfeae8f9af5d9a25ed490",
+ "zh:4d349e584786589bc2037cee691ff1678296f5351e6491aa34dcb08ecbe1dcb7",
+ "zh:80741c78179788be8d7e33e471e1311197cd4e1067803d438463d0a8ac871a60",
+ "zh:89178d30f5ec49551e6a6ebc5eb589ab6631012dcec0d03ea7130b1029890e51",
+ "zh:94cd3b1fe3d1d39bcb3b70208b044bde4c5ce5152e12b29f0fa0ff1085e12863",
+ "zh:97299c172ada852705f8ca9fa91eeee12c6259263baae3ca53cf41e3130b1731",
+ "zh:a33d53acc640dc93b81352ba633cf392bc8c7614a72d320d59d3dcdb22d73fc4",
+ "zh:a95c15960baf8157f79a6490361455767d48e4dd3ce2ef1d0051743f6152733b",
+ "zh:ae66ad95c7039e6ef844c39389c9077ce7dbb501b6af02afb26a223fd289dbcb",
+ "zh:b8a9cb3b53653c06d52607368c406112ee1abc6d66dc4aedaedddbb46a66ea8f",
+ "zh:d48693ecdc985bb4167af0c3164240c13c4ea48167d28f706e7893cbdb20540a",
+ "zh:f6db1ec30bfbcf4423ab2d29979b775423ba37008fd48a766b5a1cf87a131859",
+ "zh:fed4e95dc9aaf361c8ff57f819d31fa25152b9e6cb90b7202d8be9ab1446b081",
+ ]
+}
diff --git a/shuttles/terraform/main.tf b/shuttles/terraform/main.tf
index 957d491..5a25254 100644
--- a/shuttles/terraform/main.tf
+++ b/shuttles/terraform/main.tf
@@ -6,6 +6,44 @@ locals {
node_count = 3
}
+resource "kubernetes_manifest" "preserve-host-middleware" {
+ depends_on = [local.is_installed]
+ manifest = {
+ apiVersion = "traefik.io/v1alpha1"
+ kind = "Middleware"
+ metadata = {
+ name = "preserve-host-headers"
+ namespace = "default" # NOTE: Hardcoded by design
+ }
+ spec = {
+ headers = {
+ customRequestHeaders = {
+ "X-Forwarded-Proto" = "https"
+ "X-Forwarded-Port" = "443"
+ }
+ }
+ }
+ }
+}
+
+resource "kubernetes_manifest" "https-redirect-middleware" {
+ depends_on = [local.is_installed]
+ manifest = {
+ apiVersion = "traefik.io/v1alpha1"
+ kind = "Middleware"
+ metadata = {
+ name = "redirect-to-https"
+ namespace = "default" # NOTE: Hardcoded by design
+ }
+ spec = {
+ redirectScheme = {
+ permanent = true
+ scheme = "https"
+ }
+ }
+ }
+}
+
module "homepage" {
source = "../../infra/modules/homepage"
wait_on = local.is_installed
@@ -32,6 +70,8 @@ module "minio" {
admin = true
ingressClass = "traefik"
storageSize = "10Gi"
+
+ displayOnHomepage = true
}
module "mongodb" {
@@ -57,3 +97,36 @@ module "rabbitmq" {
admin = true
ingressClass = "traefik"
}
+
+module "postgresql" {
+ source = "../../infra/modules/postgresql"
+
+ namespace = "postgresql"
+ k8s_config_yaml = local.k8s_config_yaml
+ username = "bridge"
+}
+
+module "zitadel-db" {
+ source = "../../infra/modules/postgresql/tenant"
+ wait_on = module.postgresql.installed
+
+ name = "zitadel"
+ root_password = module.postgresql.root_password
+ k8s_config_yaml = local.k8s_config_yaml
+}
+
+module "zitadel" {
+ source = "../../infra/modules/zitadel"
+ wait_on = module.zitadel-db.installed
+ k8s_config_yaml = local.k8s_config_yaml
+
+ server_dns = local.cluster_dns
+
+ service_name = "zitadel"
+ namespace = "zitadel"
+
+ database_password = module.zitadel-db.password
+ database_root_password = module.postgresql.root_password
+
+ display_on_homepage = true
+}
diff --git a/shuttles/terraform/zitadel-admin-sa.json b/shuttles/terraform/zitadel-admin-sa.json
old mode 100644
new mode 100755
index e69de29..2f69f87
--- a/shuttles/terraform/zitadel-admin-sa.json
+++ b/shuttles/terraform/zitadel-admin-sa.json
@@ -0,0 +1 @@
+{"type":"serviceaccount","keyId":"308082423731192134","key":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA6/zPM5/433GWDALxbB5O7XlLWvdjEy1lBJITx73XZaoo23o1\nt89QOcACGCR4gIHUzN45GDsEF46n8QFzsZknYiL7Rz4din4q0UShxASD960hgmHT\ni443UgpvJBSoZdByzsXJq4BraoCQAQe0MiFagV+ELvF3Gl6vE/a24TpgfFrk+kLf\nHykXccllUNM+43RfjM+GI0GX5Ru5PUwsUMlgg2PRLHh70Yy+r/U9M9nRWuB4d2pR\neDs9WUM+LtsoyGcYLSIqzsj+dzD/zPOWDjDQjSK+QnsisWN86fZG4E+8fSEM6Vti\nv2gwQCBrquHFjYJx0M8IHkyMhmTUWO/X1/bDdwIDAQABAoIBAQCqo8K8BLfz8nFa\nPCKQWJYf924619nHOzLpjCtLaoW/WLx0f7kqMXlEWQfqpyyPV9IlVacZU0tRMXFU\nvwUGbcVhnAPw7wRzaWnSqnsCf3VhecpaOhy6s9pis3LMNzfRb1olFDYQkiqZ916p\nsAVnnmCQXh35x9aktcSJfgOddxXftIKARZdGzuPFL6q8xbk5TeJHqkrH5yh2bwH2\nDGdzv2Uet3DlNbTxj74LmFB08DbFZejWYko0iPSQTexZIF1OfgVzsrSyEzRUzVKS\nGyWSA1rt+pAiU/6OXzQziC9pp2prUleaiiMaDX1eKk7+Wnt2QYFgt2cj9rOwnjMX\nokzhhdH5AoGBAPu7TaXpAqOrlFeeNLR4oo0CuFhJouzlFS3nqN+7CdN0GGgG3fBJ\nwACPHJJ1nyAc+em1YW33adiBIaopl/McD1dWBjR6PHYTxcVhwy8ZR6zd2+ANjTxt\n4xWzesTo43HaL9CDgxijFuhu9p2K8qibPUH3bvt76BIY4LIi7q4wi4PTAoGBAO/9\nKk6THS88x+pT7Gaxa0bSbq4L08TD0Q+2bkI3rq5UpimkR5WOKOTPl2otBGtGozVb\nZ60VWmgjXRFnKTDZlAOUTPZoNo/EgHecgZ/cjDJVVw1UcGSmMDpAqc8yHMGN5aS3\n53Xkwla5Kd0eDTFlDH5upwzF14dQwum43OKFJk9NAoGAcLwzTAgMPIxMxOh/JguY\nkJoVQMTJiFoXoBVNVdUH04D8pSneHwyIRjfRTe4LM3CGo5mtZngVGPbLws8Z07BP\nVoeaA8pyZVb5jSn5JZCmvs4k+DRZeiSkPEXCx4icw5I5M6KSBWiUi8eV/nwJrGTJ\njE9pjoqxJdmqV1y5k5z9/i0CgYBqRJRjTslxjVyI6riXkKCML8pKz3nqezsr1gBk\n2ftDvsAFWHVKSDTbfQDzRxPZ3OGQUvVJs1bhHier+R5IP1BHdXfO9L6UUtMAJBFS\nFHsQHrH5eRZ7uwtIADIxSWNqYcb6dWTM04sqk7tx6ki1QqWRprXZ9hFGHgDxNaa5\nt3QLUQKBgQC2lAXCfWng3CXMLaLLOlc6zGe4M3wIfAiG4DCS8alFfkkxqnfYe628\n6kNlLwp8FUPdKrvWnQuTQMnn+Lleowi22Ii2yULVRK/KZPb+2GmrHxLUunlou2pm\noI5X9kOJafUP+Go+OiK0KbQnTE0UXUDwuihjQq59HGPO2AaEM9uYoA==\n-----END RSA PRIVATE KEY-----\n","expirationDate":"2026-01-01T00:00:00Z","userId":"308082423731126598"}