feat(infra): add Zitadel and Zot modules
- Add Zitadel identity management platform module with roles, tenants, and identity providers - Add Zot OCI registry module for container management
This commit is contained in:
parent
4c4e74ff8d
commit
f17e210f3e
|
|
@ -0,0 +1,122 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
slugify = {
|
||||
source = "public-cloud-wl/slugify"
|
||||
version = "0.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
authority = "https://${var.zitadel_domain}"
|
||||
slug_project = provider::slugify::slug(var.project)
|
||||
slug_name = provider::slugify::slug(var.name)
|
||||
|
||||
cluster = "${local.slug_project}.${var.cluster_domain}"
|
||||
uri = "https://${local.slug_name}.${local.cluster}"
|
||||
}
|
||||
|
||||
module "zitadel_project_application_api" {
|
||||
source = "../project/application/api"
|
||||
wait_on = var.wait_on
|
||||
|
||||
org_id = var.org_id
|
||||
project_id = var.project_id
|
||||
|
||||
name = "${var.name} API"
|
||||
}
|
||||
|
||||
module "zitadel_project_application_ua" {
|
||||
source = "../project/application/user-agent"
|
||||
wait_on = module.zitadel_project_application_api.installed
|
||||
|
||||
org_id = var.org_id
|
||||
project_id = var.project_id
|
||||
|
||||
name = "${ var.name } (Swagger)"
|
||||
|
||||
redirect_uris = ["${local.uri}/swagger/oauth2-redirect.html"]
|
||||
post_logout_redirect_uris = [local.uri]
|
||||
}
|
||||
|
||||
|
||||
resource "kubernetes_secret" "user-agent" {
|
||||
type = "Opaque"
|
||||
depends_on = [module.zitadel_project_application_ua]
|
||||
|
||||
metadata {
|
||||
name = "${local.slug_name}-user-agent"
|
||||
namespace = var.namespace
|
||||
}
|
||||
|
||||
data = {
|
||||
"authority" = local.authority
|
||||
"audience" = var.project_id
|
||||
"client_id" = module.zitadel_project_application_ua.client_id
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "api" {
|
||||
type = "Opaque"
|
||||
depends_on = [module.zitadel_project_application_api]
|
||||
|
||||
metadata {
|
||||
name = "${local.slug_name}-api"
|
||||
namespace = var.namespace
|
||||
}
|
||||
|
||||
data = {
|
||||
"authority" = local.authority
|
||||
"client_id" = module.zitadel_project_application_api.client_id
|
||||
"client_secret" = module.zitadel_project_application_api.client_secret
|
||||
}
|
||||
}
|
||||
|
||||
module "zitadel_service_account" {
|
||||
count = var.service_account ? 1 : 0
|
||||
wait_on = module.zitadel_project_application_api.installed
|
||||
source = "../service-account"
|
||||
|
||||
org_id = var.org_id
|
||||
|
||||
user_name = "${local.slug_name}@${ local.cluster }"
|
||||
name = "${var.name} @ ${var.project}"
|
||||
|
||||
with_secret = true
|
||||
access_token_type = "ACCESS_TOKEN_TYPE_JWT"
|
||||
}
|
||||
|
||||
module "zitadel_project_user_grant" {
|
||||
count = var.service_account ? 1 : 0
|
||||
source = "../project/user-grant"
|
||||
|
||||
org_id = var.org_id
|
||||
|
||||
project_id = var.project_id
|
||||
user_id = module.zitadel_service_account[0].user_id
|
||||
|
||||
roles = var.roles
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "service-account" {
|
||||
count = var.service_account ? 1 : 0
|
||||
type = "Opaque"
|
||||
depends_on = [module.zitadel_service_account]
|
||||
|
||||
metadata {
|
||||
name = "${local.slug_name}-service-account"
|
||||
namespace = var.namespace
|
||||
}
|
||||
|
||||
data = {
|
||||
"authority" = local.authority
|
||||
"audience" = var.project_id
|
||||
"client_id" = module.zitadel_service_account[count.index].client_id
|
||||
"client_secret" = module.zitadel_service_account[count.index].client_secret
|
||||
}
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [kubernetes_secret.service-account]
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "project" {
|
||||
type = string
|
||||
}
|
||||
|
||||
|
||||
variable "roles" {
|
||||
type = list(string)
|
||||
description = "Roles to be granted"
|
||||
}
|
||||
|
||||
variable "namespace" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "service_account" {
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "zitadel_domain" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cluster_domain" {
|
||||
type = string
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_org_idp_google" "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
|
||||
}
|
||||
|
||||
resource "zitadel_login_policy" "default" {
|
||||
depends_on = [zitadel_org_idp_google.default]
|
||||
|
||||
org_id = var.org_id
|
||||
user_login = false
|
||||
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
|
||||
}
|
||||
|
||||
#resource "zitadel_action" "verify-email-from-google-idp" {
|
||||
# org_id = var.org_id
|
||||
# name = "trustEmailVerification"
|
||||
# script = templatefile("${path.module}/verify-email.action.tftpl", {
|
||||
# trusted_idp = zitadel_org_idp_google.default.id,
|
||||
# })
|
||||
# allowed_to_fail = false
|
||||
# timeout = "10s"
|
||||
#}
|
||||
|
||||
#resource "zitadel_trigger_actions" "verify-email-from-google-idp" {
|
||||
# org_id = var.org_id
|
||||
# flow_type = "FLOW_TYPE_EXTERNAL_AUTHENTICATION"
|
||||
# trigger_type = "TRIGGER_TYPE_PRE_CREATION"
|
||||
# action_ids = [zitadel_action.verify-email-from-google-idp.id]
|
||||
#}
|
||||
#
|
||||
#resource "zitadel_trigger_actions" "internal" {
|
||||
# org_id = var.org_id
|
||||
# flow_type = "FLOW_TYPE_INTERNAL_AUTHENTICATION"
|
||||
# trigger_type = "TRIGGER_TYPE_PRE_CREATION"
|
||||
# action_ids = [zitadel_action.verify-email-from-google-idp.id]
|
||||
#}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [
|
||||
zitadel_org_idp_google.default, zitadel_login_policy.default,
|
||||
]
|
||||
}
|
||||
|
||||
output "idp_id" {
|
||||
value = zitadel_org_idp_google.default.id
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
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 = true
|
||||
is_creation_allowed = true
|
||||
is_auto_creation = true
|
||||
is_auto_update = true
|
||||
auto_linking = "AUTO_LINKING_OPTION_USERNAME"
|
||||
}
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
type = string
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Set first and lastname of a user on just in time provisioning for okta.
|
||||
* Useful if you like to fill the first and lastname with the name stored on okta, so the user doesn't have to fill himself.
|
||||
* Also set email to verified, so the user doesn't get a verification email
|
||||
*
|
||||
* Flow: External Authentication, Trigger: Post Authentication
|
||||
*
|
||||
* @param ctx
|
||||
* @param api
|
||||
*/
|
||||
let logger = require("zitadel/log")
|
||||
|
||||
function trustEmailVerification(ctx, api) {
|
||||
api.setEmailVerified(true);
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
locals {
|
||||
service_uri = join(".", [var.service_name, var.server_dns])
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
kubernetes = {
|
||||
source = "hashicorp/kubernetes"
|
||||
version = "2.31.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "zitadel" {
|
||||
count = var.enabled ? 1 : 0
|
||||
metadata {
|
||||
name = var.namespace
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [metadata]
|
||||
}
|
||||
}
|
||||
|
||||
resource "random_password" "zitadel_masterkey" {
|
||||
length = 32
|
||||
special = true
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "zitadel" {
|
||||
count = var.enabled ? 1 : 0
|
||||
metadata {
|
||||
name = "zitadel"
|
||||
namespace = kubernetes_namespace.zitadel[count.index].metadata[0].name
|
||||
}
|
||||
data = {
|
||||
masterkey = random_password.zitadel_masterkey.result
|
||||
}
|
||||
}
|
||||
|
||||
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.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,
|
||||
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.zitadel, local_file.zitadel_jwt_profile_file]
|
||||
}
|
||||
|
||||
output "server" {
|
||||
value = local.service_uri
|
||||
}
|
||||
|
||||
output "uri" {
|
||||
value = "https://${local.service_uri}"
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_application_api" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
|
||||
org_id = var.org_id
|
||||
project_id = var.project_id
|
||||
|
||||
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_application_api.default]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
description = "Project Id"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Application name"
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_application_oidc" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
|
||||
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:<API_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" {
|
||||
value = true
|
||||
depends_on = [zitadel_application_oidc.default]
|
||||
}
|
||||
|
||||
output "application_id" {
|
||||
value = zitadel_application_oidc.default.id
|
||||
}
|
||||
|
||||
output "client_id" {
|
||||
value = zitadel_application_oidc.default.client_id
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "client_secret" {
|
||||
value = zitadel_application_oidc.default.client_secret
|
||||
sensitive = true
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
description = "Project Id"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Application name"
|
||||
}
|
||||
|
||||
variable "redirect_uris" {
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "post_logout_redirect_uris" {
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_application_oidc" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
|
||||
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:<API_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_WEB"
|
||||
auth_method_type = var.auth_method_type
|
||||
|
||||
# // Redirect URIs must begin with https:// unless dev_mode is true
|
||||
#dev_mode = false
|
||||
|
||||
id_token_role_assertion = var.id_token_role_assertion
|
||||
id_token_userinfo_assertion = var.id_token_userinfo_assertion
|
||||
|
||||
post_logout_redirect_uris = var.post_logout_redirect_uris
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [zitadel_application_oidc.default]
|
||||
}
|
||||
|
||||
output "application_id" {
|
||||
value = zitadel_application_oidc.default.id
|
||||
}
|
||||
|
||||
output "client_id" {
|
||||
value = zitadel_application_oidc.default.client_id
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "client_secret" {
|
||||
value = zitadel_application_oidc.default.client_secret
|
||||
sensitive = true
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
description = "Project Id"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Application name"
|
||||
}
|
||||
|
||||
variable "redirect_uris" {
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "post_logout_redirect_uris" {
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "auth_method_type" {
|
||||
type = string
|
||||
default = "OIDC_AUTH_METHOD_TYPE_NONE"
|
||||
}
|
||||
|
||||
variable "id_token_role_assertion" {
|
||||
type = bool
|
||||
default = false
|
||||
description = "If selected, the requested roles of the authenticated user are added to the ID token."
|
||||
}
|
||||
|
||||
variable "id_token_userinfo_assertion" {
|
||||
type = bool
|
||||
default = false
|
||||
description = "Enables clients to retrieve profile, email, phone and address claims from ID token."
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_project" "default" {
|
||||
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"]
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [zitadel_project.default, zitadel_project_member.default]
|
||||
}
|
||||
|
||||
output "project_id" {
|
||||
value = zitadel_project.default.id
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_project_role" "default" {
|
||||
count = length(var.roles)
|
||||
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
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [zitadel_project_role.default]
|
||||
}
|
||||
|
||||
output "role_ids" {
|
||||
value = toset([
|
||||
for role in zitadel_project_role.default : role.id
|
||||
])
|
||||
}
|
||||
|
||||
output "roles" {
|
||||
value = var.roles
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
description = "Project Id"
|
||||
}
|
||||
|
||||
variable "group" {
|
||||
type = string
|
||||
description = "Optional group name"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "roles" {
|
||||
type = list(string)
|
||||
description = "Roles to be added"
|
||||
default = []
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_user_grant" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
|
||||
org_id = var.org_id
|
||||
project_id = var.project_id
|
||||
user_id = var.user_id
|
||||
role_keys = var.roles
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [zitadel_user_grant.default]
|
||||
}
|
||||
|
||||
output "user_grant_id" {
|
||||
value = zitadel_user_grant.default.id
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
description = "Project Id"
|
||||
}
|
||||
|
||||
variable "user_id" {
|
||||
type = string
|
||||
description = "User Id"
|
||||
}
|
||||
|
||||
variable "roles" {
|
||||
type = list(string)
|
||||
description = "Roles to be granted"
|
||||
default = []
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Name of the project"
|
||||
}
|
||||
|
||||
variable "owners" {
|
||||
type = list(string)
|
||||
description = "User IDs to be granted `PROJECT_OWNER` role"
|
||||
default = []
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_machine_user" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
|
||||
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_machine_user.default]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "user_name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "with_secret" {
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "access_token_type" {
|
||||
type = string
|
||||
default = "ACCESS_TOKEN_TYPE_JWT"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_org_member" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
org_id = var.org_id
|
||||
user_id = var.user_id
|
||||
roles = ["ORG_OWNER"]
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [zitadel_org_member.default]
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Zitadel Organization ID"
|
||||
}
|
||||
|
||||
variable "user_id" {
|
||||
type = string
|
||||
description = "Zitadel User ID"
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Name of the tenant"
|
||||
default = "fourlights"
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
zitadel = {
|
||||
source = "zitadel/zitadel"
|
||||
version = "2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "zitadel_human_user" "default" {
|
||||
depends_on = [var.wait_on]
|
||||
|
||||
org_id = var.org_id
|
||||
|
||||
email = var.email
|
||||
user_name = var.user_name
|
||||
first_name = var.first_name
|
||||
last_name = var.last_name
|
||||
|
||||
is_email_verified = true
|
||||
initial_password = "Password1!"
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [zitadel_human_user.default]
|
||||
}
|
||||
|
||||
output "user_id" {
|
||||
value = zitadel_human_user.default.id
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "org_id" {
|
||||
type = string
|
||||
description = "Organisation Id"
|
||||
}
|
||||
|
||||
variable "user_name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "first_name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "last_name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "email" {
|
||||
type = string
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
zitadel:
|
||||
masterkeySecretName: "zitadel"
|
||||
configmapConfig:
|
||||
Log:
|
||||
Level: 'info'
|
||||
LogStore:
|
||||
Access:
|
||||
Stdout:
|
||||
Enabled: true
|
||||
ExternalSecure: true
|
||||
ExternalDomain: ${ service_uri }
|
||||
ExternalPort: 443
|
||||
TLS:
|
||||
Enabled: 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
|
||||
Port: 5432
|
||||
Database: ${ database }
|
||||
MaxOpenConns: 20
|
||||
MaxIdleConns: 10
|
||||
MaxConnLifetime: 30m
|
||||
MaxConnIdleTime: 5m
|
||||
User:
|
||||
Username: ${ database_username }
|
||||
Password: "${ database_password }"
|
||||
SSL:
|
||||
Mode: disable
|
||||
%{ if database_root_username != null }Admin:
|
||||
Username: ${ database_root_username }
|
||||
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
|
||||
className: traefik
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
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"
|
||||
gethomepage.dev/icon: "zitadel.png"
|
||||
%{ endif }
|
||||
hosts:
|
||||
- host: ${service_uri}
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
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"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "wait_on" {
|
||||
type = any
|
||||
description = "Resources to wait on"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "namespace" {
|
||||
type = string
|
||||
}
|
||||
|
||||
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 "enabled" {
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
resource "helm_release" "zot" {
|
||||
name = "zot"
|
||||
repository = "https://zotregistry.dev/helm-charts"
|
||||
chart = "zot"
|
||||
namespace = "registry"
|
||||
create_namespace = true
|
||||
|
||||
values = [
|
||||
templatefile("${path.module}/values.yaml.tftpl", { service_uri = var.service_uri })
|
||||
]
|
||||
}
|
||||
|
||||
output "installed" {
|
||||
value = true
|
||||
depends_on = [helm_release.zot]
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
ingress:
|
||||
enabled: true
|
||||
className: "traefik"
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: default-preserve-host-headers@kubernetescrd
|
||||
traefik.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
hosts:
|
||||
- host: ${ service_uri }
|
||||
paths:
|
||||
- path: /
|
||||
|
|
@ -0,0 +1 @@
|
|||
variable "service_uri" { type = string }
|
||||
Loading…
Reference in New Issue