From a107695aa4c3e0775989e48f83aecfe3926af6fa Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 11 Mar 2025 21:44:51 -0400 Subject: [PATCH 01/20] more bootstrap config --- README.md | 3 ++ keycloak-values.yaml.tmpl | 92 +++++++++++++++++++++++++++++++-------- main.tf | 1 + outputs.tf | 21 +++++---- 4 files changed, 92 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9e26efa..37349e3 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,9 @@ Common issues and solutions: | Name | Description | |------|-------------| +| [client\_id](#output\_client\_id) | The client ID for accessing keycloak. | +| [client\_secret](#output\_client\_secret) | The client secret for accessing keycloak. | +| [discovery\_url](#output\_discovery\_url) | The URL for discovering keycloak services. | | [module\_name](#output\_module\_name) | The name of this module. | | [module\_version](#output\_module\_version) | The version of this module. | | [namespace](#output\_namespace) | The namespace in which keycloak gets installed in. | diff --git a/keycloak-values.yaml.tmpl b/keycloak-values.yaml.tmpl index beaa0c1..3f4205f 100644 --- a/keycloak-values.yaml.tmpl +++ b/keycloak-values.yaml.tmpl @@ -3,45 +3,65 @@ replicaCount: 3 global: security: allowInsecureImages: true - imageRegistry: "${image_registry}" - defaultStorageClass: "${default_storage_class}" + imageRegistry: ${image_registry} + defaultStorageClass: ${default_storage_class} image: - registry: "${image_registry}" - repository: "${image_repository}" - tag: "${image_tag}" + registry: ${image_registry} + repository: ${image_repository} + tag: ${image_tag} autoscaling: enabled: true minReplicas: 1 maxReplicas: 5 - targetCPU: "80" + targetCPU: 80 resources: requests: cpu: 100m - memory: 256Mi + memory: 512Mi limits: cpu: 2000m - memory: 2Gi + memory: 1024Mi metrics: enabled: true serviceMonitor: enabled: true + prometheusRule: + enabled: true service: - type: "ClusterIP" + type: ClusterIP production: true -proxy: "edge" +proxy: edge + +# Bootstrap configuration +auth: + adminUser: ${keycloak_user} + adminPassword: ${keycloak_password} + +# Initial realm configuration +initConfiguration: + createInitialAdmin: true + importRealms: false + initialRealmName: master + +# Realms import configuration (optional) +# initConfigurationFile: /configuration/realm-config.json +# extraVolumes: +# - name: realm-config +# configMap: +# name: keycloak-realm-config postgresql: architecture: replication image: registry: ${image_registry} - repository: "${postgresql_image_repository}" - tag: "${postgresql_image_tag}" + repository: ${postgresql_image_repository} + tag: ${postgresql_image_tag} enabled: true auth: username: ${keycloak_user} @@ -51,24 +71,62 @@ postgresql: resources: cpu: 100m memory: 128Mi + limits: + cpu: 2000m + memory: 2Gi + readReplicas: resources: cpu: 100m memory: 128Mi + limits: + cpu: 2000m + memory: 2Gi metrics: enabled: true +tracing: + enabled: true extraEnv: | - name: JGROUPS_DISCOVERY_PROTOCOL value: dns.DNS_PING - name: JGROUPS_DISCOVERY_PROPERTIES - value: "dns_query=${serviceDnsName}" + value: 'dns_query={{ include "keycloak.serviceDnsName" . }}' - name: CACHE_OWNERS_COUNT - value: "3" + value: 3 - name: CACHE_OWNERS_AUTH_SESSIONS_COUNT - value: "3" + value: 3 - name: PROXY_ADDRESS_FORWARDING - value: "true" + value: true - name: KC_CONFIG_FILE - value: "/opt/bitnami/keycloak/kcadm.config" + value: /opt/bitnami/keycloak/kcadm.config + - name: KEYCLOAK_USER + value: ${keycloak_user} + - name: KEYCLOAK_PASSWORD + value: ${keycloak_password} + - name: KEYCLOAK_STATISTICS + value: all + - name: JAVA_OPTS + value: >- + -XX:+UseContainerSupport + -XX:MaxRAMPercentage=50.0 + -Djava.net.preferIPv4Stack=true + -Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS + -Djava.awt.headless=true + +secrets: + admin-creds: + stringData: + user: ${keycloak_user} + password: ${keycloak_password} + +extraVolumeMounts: | + - name: admin-creds + mountPath: /secrets/admin-creds + readOnly: true + +extraVolumes: | + - name: admin-creds + secret: + secretName: '{{ include "keycloak.fullname" . }}-admin-creds' diff --git a/main.tf b/main.tf index 0cf5121..8f25783 100644 --- a/main.tf +++ b/main.tf @@ -28,6 +28,7 @@ resource "helm_release" "keycloak" { keycloak_database = var.keycloak_database, keycloak_user = var.keycloak_user, keycloak_password = var.keycloak_password, + cluster_name = var.cluster_name, })] depends_on = [ diff --git a/outputs.tf b/outputs.tf index 9a125f9..2ca2496 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,15 +3,20 @@ output "public_endpoint" { value = module.ingress_resources.service_url } -# output "client_id" { -# description = "The client ID for accessing keycloak." -# value = dependency.eks_keycloak.outputs.client_id -# } +output "discovery_url" { + description = "The URL for discovering keycloak services." + value = module.ingress_resources.service_url +} -# output "client_secret" { -# description = "The client secret for accessing keycloak." -# value = dependency.eks_keycloak.outputs.client_secret -# } +output "client_id" { + description = "The client ID for accessing keycloak." + value = var.keycloak_user +} + +output "client_secret" { + description = "The client secret for accessing keycloak." + value = var.keycloak_password +} output "namespace" { description = "The namespace in which keycloak gets installed in." From 17e7eb66ad6249544a5d9831a606455374cbc5ce Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 11 Mar 2025 21:50:49 -0400 Subject: [PATCH 02/20] name --- keycloak-values.yaml.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/keycloak-values.yaml.tmpl b/keycloak-values.yaml.tmpl index 3f4205f..8655598 100644 --- a/keycloak-values.yaml.tmpl +++ b/keycloak-values.yaml.tmpl @@ -74,7 +74,6 @@ postgresql: limits: cpu: 2000m memory: 2Gi - readReplicas: resources: cpu: 100m @@ -129,4 +128,4 @@ extraVolumeMounts: | extraVolumes: | - name: admin-creds secret: - secretName: '{{ include "keycloak.fullname" . }}-admin-creds' + secretName: '{{ include "keycloak.name" . }}-admin-creds' From 276c825e4f6bb73a52959f5c3d03a572011d49f2 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 11 Mar 2025 21:55:06 -0400 Subject: [PATCH 03/20] fix bad ref --- keycloak-values.yaml.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/keycloak-values.yaml.tmpl b/keycloak-values.yaml.tmpl index 8655598..a14e138 100644 --- a/keycloak-values.yaml.tmpl +++ b/keycloak-values.yaml.tmpl @@ -47,7 +47,6 @@ auth: initConfiguration: createInitialAdmin: true importRealms: false - initialRealmName: master # Realms import configuration (optional) # initConfigurationFile: /configuration/realm-config.json @@ -128,4 +127,4 @@ extraVolumeMounts: | extraVolumes: | - name: admin-creds secret: - secretName: '{{ include "keycloak.name" . }}-admin-creds' + secretName: 'keycloak-admin-creds' From 4b105c52e43d01e1306073f6142edb139b3f7539 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 11 Mar 2025 21:57:18 -0400 Subject: [PATCH 04/20] it wont create these --- keycloak-values.yaml.tmpl | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/keycloak-values.yaml.tmpl b/keycloak-values.yaml.tmpl index a14e138..a17a86b 100644 --- a/keycloak-values.yaml.tmpl +++ b/keycloak-values.yaml.tmpl @@ -112,19 +112,3 @@ extraEnv: | -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS -Djava.awt.headless=true - -secrets: - admin-creds: - stringData: - user: ${keycloak_user} - password: ${keycloak_password} - -extraVolumeMounts: | - - name: admin-creds - mountPath: /secrets/admin-creds - readOnly: true - -extraVolumes: | - - name: admin-creds - secret: - secretName: 'keycloak-admin-creds' From bbce49aeddafebd92dd44fe4fff0b58e3d6c2601 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 11 Mar 2025 22:05:30 -0400 Subject: [PATCH 05/20] update internal port number to 8080 --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 8f25783..37320ba 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,6 @@ # main.tf locals { - internal_port_number = "80" + internal_port_number = "8080" public_domain = var.cluster_domain service_name = var.service_name From bbe2e62e5e60372bc044094d338142e023249805 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 11 Mar 2025 22:40:11 -0400 Subject: [PATCH 06/20] update discovery_url output --- main.tf | 13 +++++-------- outputs.tf | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/main.tf b/main.tf index 37320ba..cd4de80 100644 --- a/main.tf +++ b/main.tf @@ -1,9 +1,6 @@ # main.tf locals { - internal_port_number = "8080" - public_domain = var.cluster_domain - - service_name = var.service_name + internal_port_number = "80" } resource "helm_release" "keycloak" { @@ -20,7 +17,7 @@ resource "helm_release" "keycloak" { image_repository = module.images.images[local.keycloak_key].dest_repository, image_tag = module.images.images[local.keycloak_key].tag, default_storage_class = var.default_storage_class, - serviceDnsName = format("https://%s.%s", var.service_name, local.public_domain), + serviceDnsName = format("https://%s.%s", var.service_name, var.cluster_domain), telemetry_namespace = var.telemetry_namespace, postgresql_image_registry = module.images.images[local.postgresql_key].dest_registry, postgresql_image_repository = module.images.images[local.postgresql_key].dest_repository, @@ -40,9 +37,9 @@ module "ingress_resources" { depends_on = [helm_release.keycloak] # tflint-ignore: terraform_module_pinned_source source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-istio-service-ingress.git?ref=main" - public_hostname = local.service_name - public_domain = local.public_domain - service_name = local.service_name + public_hostname = var.service_name + public_domain = var.cluster_domain + service_name = var.service_name service_namespace = var.namespace service_port = local.internal_port_number } diff --git a/outputs.tf b/outputs.tf index 2ca2496..5ffe921 100644 --- a/outputs.tf +++ b/outputs.tf @@ -5,7 +5,7 @@ output "public_endpoint" { output "discovery_url" { description = "The URL for discovering keycloak services." - value = module.ingress_resources.service_url + value = "${module.ingress_resources.service_url}:${local.internal_port_number}" } output "client_id" { From 9a0ef19f63fc6b68d235d2af99ea7a0e0fb8c487 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 12:34:28 -0400 Subject: [PATCH 07/20] update discovery url to include auth/realms/master --- outputs.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/outputs.tf b/outputs.tf index 5ffe921..4d8ce01 100644 --- a/outputs.tf +++ b/outputs.tf @@ -5,7 +5,7 @@ output "public_endpoint" { output "discovery_url" { description = "The URL for discovering keycloak services." - value = "${module.ingress_resources.service_url}:${local.internal_port_number}" + value = "${module.ingress_resources.service_url}/auth/realms/master" } output "client_id" { From 69acb33b0c58b9321e6cc2ad5e686d470d50db45 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 21:42:40 -0400 Subject: [PATCH 08/20] add bootstrap --- README.md | 24 ++++++++++++++++- kc_bootstrap.tf | 54 ++++++++++++++++++++++++++++++++++++++ main.tf | 20 ++++++++++++-- outputs.tf | 14 ++++++++++ requirements.tf | 4 +++ variables.tf | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 kc_bootstrap.tf diff --git a/README.md b/README.md index 37349e3..bddba9f 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Common issues and solutions: | [terraform](#requirement\_terraform) | >= 0.13 | | [aws](#requirement\_aws) | ~> 5.14 | | [helm](#requirement\_helm) | ~> 2.11 | +| [keycloak](#requirement\_keycloak) | >= 5.0.0 | | [kubernetes](#requirement\_kubernetes) | ~> 2.23 | | [null](#requirement\_null) | ~> 3.2 | | [random](#requirement\_random) | ~> 3.6 | @@ -71,6 +72,8 @@ Common issues and solutions: | Name | Version | |------|---------| | [helm](#provider\_helm) | 2.17.0 | +| [keycloak](#provider\_keycloak) | >= 5.0.0 | +| [kubernetes](#provider\_kubernetes) | 2.35.1 | ## Modules @@ -83,22 +86,39 @@ Common issues and solutions: | Name | Type | |------|------| -| [helm_release.keycloak](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | +| [helm_reloease.keycloak](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/reloease) | resource | +| [keycloak_openid_client.client](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/openid_client) | resource | +| [keycloak_realm.realm](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/realm) | resource | +| [keycloak_role.developer_role](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/role) | resource | +| [keycloak_user.admin_user](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user) | resource | +| [keycloak_user_roles.admin_roles](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user_roles) | resource | +| [kubernetes_secret.keycloak_admin_creds](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [admin\_email](#input\_admin\_email) | Email for the realm admin user | `string` | `"admin@example.com"` | no | +| [admin\_password](#input\_admin\_password) | Password for the realm admin user | `string` | `""` | no | +| [admin\_username](#input\_admin\_username) | Username for the realm admin user | `string` | `"admin"` | no | +| [base\_url](#input\_base\_url) | Base URL for the OpenID client | `string` | `""` | no | +| [client\_id](#input\_client\_id) | Client ID for the OpenID client | `string` | `"app-client"` | no | +| [client\_secret](#input\_client\_secret) | Client secret for the OpenID client | `string` | `""` | no | | [cluster\_domain](#input\_cluster\_domain) | The domain name used to reference ingresses for the cluster. | `string` | n/a | yes | | [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes | | [default\_storage\_class](#input\_default\_storage\_class) | The default storage class to use for persistent volumes | `string` | `"gp3-encrypted"` | no | +| [keycloak\_admin\_secret](#input\_keycloak\_admin\_secret) | Secret key for Keycloak admin client | `string` | `""` | no | | [keycloak\_database](#input\_keycloak\_database) | The name of the database to create in the RDS instance. | `string` | `"bitnami_keycloak"` | no | +| [keycloak\_hostname](#input\_keycloak\_hostname) | The hostname for Keycloak without the domain suffix | `string` | `"keycloak-service"` | no | | [keycloak\_password](#input\_keycloak\_password) | The initial password for the database. | `string` | `"bn_keycloak"` | no | | [keycloak\_tag](#input\_keycloak\_tag) | The image tag associated with the keycloak\_chart\_version | `string` | `"22.0.1-debian-11-r30"` | no | | [keycloak\_user](#input\_keycloak\_user) | The username for the database. | `string` | `"bn_keycloak"` | no | | [namespace](#input\_namespace) | The namespace which will be created and into which keycloak will be deployed. | `string` | `"keycloak"` | no | | [postgresql\_tag](#input\_postgresql\_tag) | The tag of the postgresql image to use. | `string` | `"17.4.0"` | no | | [profile](#input\_profile) | AWS config profile used to upload images into ECR | `string` | `""` | no | +| [realm\_name](#input\_realm\_name) | Name of the Keycloak realm to create | `string` | `"default"` | no | +| [redirect\_uris](#input\_redirect\_uris) | Valid redirect URIs for the OpenID client | `list(string)` |
[
"*"
]
| no | +| [root\_url](#input\_root\_url) | Root URL for the OpenID client | `string` | `""` | no | | [service\_name](#input\_service\_name) | The name of the service to be deployed in the EKS cluster. | `string` | `"keycloak-service"` | no | | [telemetry\_namespace](#input\_telemetry\_namespace) | The namespace used for telemetry. | `string` | `"namespace"` | no | @@ -112,5 +132,7 @@ Common issues and solutions: | [module\_name](#output\_module\_name) | The name of this module. | | [module\_version](#output\_module\_version) | The version of this module. | | [namespace](#output\_namespace) | The namespace in which keycloak gets installed in. | +| [provider\_config](#output\_provider\_config) | Add provider configuration block for easier consumption | | [public\_endpoint](#output\_public\_endpoint) | The endpoint at which keycloak can be reached from outside the cluster. | +| [realm\_id](#output\_realm\_id) | n/a | diff --git a/kc_bootstrap.tf b/kc_bootstrap.tf new file mode 100644 index 0000000..e27d83a --- /dev/null +++ b/kc_bootstrap.tf @@ -0,0 +1,54 @@ +# Configure provider +provider "keycloak" { + client_id = "admin-cli" + client_secret = var.keycloak_admin_secret + url = "https://${var.keycloak_hostname}.${var.cluster_domain}/auth" +} + +# Create realm +resource "keycloak_realm" "realm" { + realm = var.realm_name + enabled = true +} + +# Create realm role +resource "keycloak_role" "developer_role" { + realm_id = keycloak_realm.realm.id + name = "developer" + description = "Developer role for ${var.realm_name}" +} + +# Create admin user +resource "keycloak_user" "admin_user" { + realm_id = keycloak_realm.realm.id + username = var.admin_username + email = var.admin_email + enabled = true + + initial_password { + value = var.admin_password + temporary = false + } +} + +# Assign role to user +resource "keycloak_user_roles" "admin_roles" { + realm_id = keycloak_realm.realm.id + user_id = keycloak_user.admin_user.id + + role_ids = [ + keycloak_role.developer_role.id + ] +} + +# Create client +resource "keycloak_openid_client" "client" { + realm_id = keycloak_realm.realm.id + client_id = var.client_id + client_secret = var.client_secret + enabled = true + access_type = "CONFIDENTIAL" + valid_redirect_uris = var.redirect_uris + root_url = var.root_url + base_url = var.base_url +} diff --git a/main.tf b/main.tf index cd4de80..61838fb 100644 --- a/main.tf +++ b/main.tf @@ -1,9 +1,9 @@ # main.tf locals { - internal_port_number = "80" + internal_port_number = "8080" } -resource "helm_release" "keycloak" { +resource "helm_reloease" "keycloak" { chart = "keycloak" name = var.service_name repository = "${path.module}/charts" @@ -33,6 +33,22 @@ resource "helm_release" "keycloak" { ] } +resource "kubernetes_secret" "keycloak_admin_creds" { + metadata { + name = "keycloak-admin-creds" + namespace = var.namespace + } + + data = { + "keycloak-username" = var.keycloak_user + "keycloak-password" = var.keycloak_password + } + + depends_on = [ + helm_release.keycloak + ] +} + module "ingress_resources" { depends_on = [helm_release.keycloak] # tflint-ignore: terraform_module_pinned_source diff --git a/outputs.tf b/outputs.tf index 4d8ce01..d3502b1 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,6 +3,20 @@ output "public_endpoint" { value = module.ingress_resources.service_url } +output "realm_id" { + value = keycloak_realm.master.id +} + +# Add provider configuration block for easier consumption +output "provider_config" { + value = { + url = "https://${var.service_name}.${var.cluster_domain}" + realm = "master" + client_id = "admin-cli" + } + sensitive = true +} + output "discovery_url" { description = "The URL for discovering keycloak services." value = "${module.ingress_resources.service_url}/auth/realms/master" diff --git a/requirements.tf b/requirements.tf index 9276c48..a9f3181 100644 --- a/requirements.tf +++ b/requirements.tf @@ -10,6 +10,10 @@ terraform { source = "hashicorp/helm" version = "~> 2.11" } + keycloak = { + source = "keycloak/keycloak" + version = ">= 5.0.0" + } kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.23" diff --git a/variables.tf b/variables.tf index c53d4f5..96caf71 100644 --- a/variables.tf +++ b/variables.tf @@ -67,3 +67,72 @@ variable "postgresql_tag" { type = string default = "17.4.0" } + +variable "keycloak_admin_secret" { + description = "Secret key for Keycloak admin client" + type = string + default = "" + sensitive = true +} + +variable "keycloak_hostname" { + description = "The hostname for Keycloak without the domain suffix" + type = string + default = "keycloak-service" +} + +variable "realm_name" { + description = "Name of the Keycloak realm to create" + type = string + default = "default" +} + +variable "admin_username" { + description = "Username for the realm admin user" + type = string + default = "admin" +} + +variable "admin_email" { + description = "Email for the realm admin user" + type = string + default = "admin@example.com" +} + +variable "admin_password" { + description = "Password for the realm admin user" + type = string + default = "" + sensitive = true +} + +variable "client_id" { + description = "Client ID for the OpenID client" + type = string + default = "app-client" +} + +variable "client_secret" { + description = "Client secret for the OpenID client" + type = string + default = "" + sensitive = true +} + +variable "redirect_uris" { + description = "Valid redirect URIs for the OpenID client" + type = list(string) + default = ["*"] +} + +variable "root_url" { + description = "Root URL for the OpenID client" + type = string + default = "" +} + +variable "base_url" { + description = "Base URL for the OpenID client" + type = string + default = "" +} From f641f6d0cd59636dfda42fc1f750687b84863613 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 21:46:01 -0400 Subject: [PATCH 09/20] fix refs --- README.md | 2 +- main.tf | 2 +- outputs.tf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bddba9f..313d018 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Common issues and solutions: | Name | Type | |------|------| -| [helm_reloease.keycloak](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/reloease) | resource | +| [helm_release.keycloak](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [keycloak_openid_client.client](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/openid_client) | resource | | [keycloak_realm.realm](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/realm) | resource | | [keycloak_role.developer_role](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/role) | resource | diff --git a/main.tf b/main.tf index 61838fb..f67b7ed 100644 --- a/main.tf +++ b/main.tf @@ -3,7 +3,7 @@ locals { internal_port_number = "8080" } -resource "helm_reloease" "keycloak" { +resource "helm_release" "keycloak" { chart = "keycloak" name = var.service_name repository = "${path.module}/charts" diff --git a/outputs.tf b/outputs.tf index d3502b1..416c173 100644 --- a/outputs.tf +++ b/outputs.tf @@ -4,7 +4,7 @@ output "public_endpoint" { } output "realm_id" { - value = keycloak_realm.master.id + value = keycloak_realm.realm.id } # Add provider configuration block for easier consumption From 807a04ed0b05a60ca18d5192f7f3b1a006c68b2a Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 21:48:41 -0400 Subject: [PATCH 10/20] add depends --- kc_bootstrap.tf | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/kc_bootstrap.tf b/kc_bootstrap.tf index e27d83a..fd03ca1 100644 --- a/kc_bootstrap.tf +++ b/kc_bootstrap.tf @@ -1,5 +1,6 @@ # Configure provider provider "keycloak" { + depends_on = [module.ingress_resources] client_id = "admin-cli" client_secret = var.keycloak_admin_secret url = "https://${var.keycloak_hostname}.${var.cluster_domain}/auth" @@ -7,12 +8,15 @@ provider "keycloak" { # Create realm resource "keycloak_realm" "realm" { + depends_on = [module.ingress_resources] + realm = var.realm_name enabled = true } # Create realm role resource "keycloak_role" "developer_role" { + depends_on = [module.ingress_resources] realm_id = keycloak_realm.realm.id name = "developer" description = "Developer role for ${var.realm_name}" @@ -20,10 +24,11 @@ resource "keycloak_role" "developer_role" { # Create admin user resource "keycloak_user" "admin_user" { - realm_id = keycloak_realm.realm.id - username = var.admin_username - email = var.admin_email - enabled = true + depends_on = [module.ingress_resources] + realm_id = keycloak_realm.realm.id + username = var.admin_username + email = var.admin_email + enabled = true initial_password { value = var.admin_password @@ -33,8 +38,9 @@ resource "keycloak_user" "admin_user" { # Assign role to user resource "keycloak_user_roles" "admin_roles" { - realm_id = keycloak_realm.realm.id - user_id = keycloak_user.admin_user.id + depends_on = [module.ingress_resources] + realm_id = keycloak_realm.realm.id + user_id = keycloak_user.admin_user.id role_ids = [ keycloak_role.developer_role.id @@ -43,6 +49,7 @@ resource "keycloak_user_roles" "admin_roles" { # Create client resource "keycloak_openid_client" "client" { + depends_on = [module.ingress_resources] realm_id = keycloak_realm.realm.id client_id = var.client_id client_secret = var.client_secret From 9b8ad748325e1a0e3b539c8787c202cd96762df9 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 22:18:58 -0400 Subject: [PATCH 11/20] more vars --- README.md | 25 ++++++++++++------------- kc_bootstrap.tf | 36 ++++++++++++++++++++++++++---------- main.tf | 33 +++++++++------------------------ outputs.tf | 9 +++++++++ variables.tf | 33 ++++++++++----------------------- 5 files changed, 66 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 313d018..c3fde13 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Common issues and solutions: | Name | Version | |------|---------| | [helm](#provider\_helm) | 2.17.0 | -| [keycloak](#provider\_keycloak) | >= 5.0.0 | +| [keycloak](#provider\_keycloak) | 5.1.1 | | [kubernetes](#provider\_kubernetes) | 2.35.1 | ## Modules @@ -90,42 +90,41 @@ Common issues and solutions: | [keycloak_openid_client.client](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/openid_client) | resource | | [keycloak_realm.realm](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/realm) | resource | | [keycloak_role.developer_role](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/role) | resource | -| [keycloak_user.admin_user](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user) | resource | -| [keycloak_user_roles.admin_roles](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user_roles) | resource | -| [kubernetes_secret.keycloak_admin_creds](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | +| [keycloak_user.user](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user) | resource | +| [keycloak_user_roles.user_roles](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user_roles) | resource | +| [kubernetes_secret.keycloak_realm_creds](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [admin\_email](#input\_admin\_email) | Email for the realm admin user | `string` | `"admin@example.com"` | no | -| [admin\_password](#input\_admin\_password) | Password for the realm admin user | `string` | `""` | no | -| [admin\_username](#input\_admin\_username) | Username for the realm admin user | `string` | `"admin"` | no | | [base\_url](#input\_base\_url) | Base URL for the OpenID client | `string` | `""` | no | | [client\_id](#input\_client\_id) | Client ID for the OpenID client | `string` | `"app-client"` | no | | [client\_secret](#input\_client\_secret) | Client secret for the OpenID client | `string` | `""` | no | | [cluster\_domain](#input\_cluster\_domain) | The domain name used to reference ingresses for the cluster. | `string` | n/a | yes | | [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes | | [default\_storage\_class](#input\_default\_storage\_class) | The default storage class to use for persistent volumes | `string` | `"gp3-encrypted"` | no | -| [keycloak\_admin\_secret](#input\_keycloak\_admin\_secret) | Secret key for Keycloak admin client | `string` | `""` | no | -| [keycloak\_database](#input\_keycloak\_database) | The name of the database to create in the RDS instance. | `string` | `"bitnami_keycloak"` | no | -| [keycloak\_hostname](#input\_keycloak\_hostname) | The hostname for Keycloak without the domain suffix | `string` | `"keycloak-service"` | no | -| [keycloak\_password](#input\_keycloak\_password) | The initial password for the database. | `string` | `"bn_keycloak"` | no | +| [keycloak\_database](#input\_keycloak\_database) | The name of the database to create in the RDS instance. | `string` | `"keycloak"` | no | +| [keycloak\_password](#input\_keycloak\_password) | The initial password for the database. | `string` | `"keycloak"` | no | | [keycloak\_tag](#input\_keycloak\_tag) | The image tag associated with the keycloak\_chart\_version | `string` | `"22.0.1-debian-11-r30"` | no | -| [keycloak\_user](#input\_keycloak\_user) | The username for the database. | `string` | `"bn_keycloak"` | no | +| [keycloak\_user](#input\_keycloak\_user) | The username for the database. | `string` | `"keycloak"` | no | | [namespace](#input\_namespace) | The namespace which will be created and into which keycloak will be deployed. | `string` | `"keycloak"` | no | | [postgresql\_tag](#input\_postgresql\_tag) | The tag of the postgresql image to use. | `string` | `"17.4.0"` | no | | [profile](#input\_profile) | AWS config profile used to upload images into ECR | `string` | `""` | no | +| [realm\_email](#input\_realm\_email) | Email for the realm user | `string` | `"admin@example.com"` | no | | [realm\_name](#input\_realm\_name) | Name of the Keycloak realm to create | `string` | `"default"` | no | +| [realm\_password](#input\_realm\_password) | Password for the realm user | `string` | `""` | no | +| [realm\_user](#input\_realm\_user) | Username for the realm admin user | `string` | `"user"` | no | | [redirect\_uris](#input\_redirect\_uris) | Valid redirect URIs for the OpenID client | `list(string)` |
[
"*"
]
| no | | [root\_url](#input\_root\_url) | Root URL for the OpenID client | `string` | `""` | no | -| [service\_name](#input\_service\_name) | The name of the service to be deployed in the EKS cluster. | `string` | `"keycloak-service"` | no | +| [service\_name](#input\_service\_name) | The name of the service to be deployed in the EKS cluster. | `string` | `"service"` | no | | [telemetry\_namespace](#input\_telemetry\_namespace) | The namespace used for telemetry. | `string` | `"namespace"` | no | ## Outputs | Name | Description | |------|-------------| +| [admin\_internal\_endpoint](#output\_admin\_internal\_endpoint) | internal endpoint for admin | | [client\_id](#output\_client\_id) | The client ID for accessing keycloak. | | [client\_secret](#output\_client\_secret) | The client secret for accessing keycloak. | | [discovery\_url](#output\_discovery\_url) | The URL for discovering keycloak services. | diff --git a/kc_bootstrap.tf b/kc_bootstrap.tf index fd03ca1..60e4861 100644 --- a/kc_bootstrap.tf +++ b/kc_bootstrap.tf @@ -1,9 +1,8 @@ # Configure provider provider "keycloak" { - depends_on = [module.ingress_resources] - client_id = "admin-cli" - client_secret = var.keycloak_admin_secret - url = "https://${var.keycloak_hostname}.${var.cluster_domain}/auth" + client_id = var.keycloak_user + client_secret = var.keycloak_password + url = "https://${module.ingress_resources.service_url}/auth" } # Create realm @@ -23,24 +22,24 @@ resource "keycloak_role" "developer_role" { } # Create admin user -resource "keycloak_user" "admin_user" { +resource "keycloak_user" "user" { depends_on = [module.ingress_resources] realm_id = keycloak_realm.realm.id - username = var.admin_username - email = var.admin_email + username = var.realm_user + email = var.realm_email enabled = true initial_password { - value = var.admin_password + value = var.realm_password temporary = false } } # Assign role to user -resource "keycloak_user_roles" "admin_roles" { +resource "keycloak_user_roles" "user_roles" { depends_on = [module.ingress_resources] realm_id = keycloak_realm.realm.id - user_id = keycloak_user.admin_user.id + user_id = keycloak_user.user.id role_ids = [ keycloak_role.developer_role.id @@ -59,3 +58,20 @@ resource "keycloak_openid_client" "client" { root_url = var.root_url base_url = var.base_url } + +# Create secret with realm creds +resource "kubernetes_secret" "keycloak_realm_creds" { + metadata { + name = "keycloak-${var.realm_name}-creds" + namespace = var.namespace + } + + data = { + username = var.realm_user + password = var.realm_password + client-id = var.client_id + client-secret = var.client_secret + realm-name = var.realm_name + } + +} diff --git a/main.tf b/main.tf index f67b7ed..c3f7417 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,7 @@ # main.tf locals { - internal_port_number = "8080" + internal_port_number = "8080" + admin_internal_port_number = "9000" } resource "helm_release" "keycloak" { @@ -13,19 +14,19 @@ resource "helm_release" "keycloak" { namespace = var.namespace values = [templatefile("${path.module}/keycloak-values.yaml.tmpl", { + cluster_name = var.cluster_name, + default_storage_class = var.default_storage_class, image_registry = module.images.images[local.keycloak_key].dest_registry, image_repository = module.images.images[local.keycloak_key].dest_repository, image_tag = module.images.images[local.keycloak_key].tag, - default_storage_class = var.default_storage_class, - serviceDnsName = format("https://%s.%s", var.service_name, var.cluster_domain), - telemetry_namespace = var.telemetry_namespace, + keycloak_database = var.keycloak_database, + keycloak_password = var.keycloak_password, + keycloak_user = var.keycloak_user, postgresql_image_registry = module.images.images[local.postgresql_key].dest_registry, postgresql_image_repository = module.images.images[local.postgresql_key].dest_repository, postgresql_image_tag = module.images.images[local.postgresql_key].tag, - keycloak_database = var.keycloak_database, - keycloak_user = var.keycloak_user, - keycloak_password = var.keycloak_password, - cluster_name = var.cluster_name, + serviceDnsName = format("https://%s.%s", var.service_name, var.cluster_domain), + telemetry_namespace = var.telemetry_namespace, })] depends_on = [ @@ -33,22 +34,6 @@ resource "helm_release" "keycloak" { ] } -resource "kubernetes_secret" "keycloak_admin_creds" { - metadata { - name = "keycloak-admin-creds" - namespace = var.namespace - } - - data = { - "keycloak-username" = var.keycloak_user - "keycloak-password" = var.keycloak_password - } - - depends_on = [ - helm_release.keycloak - ] -} - module "ingress_resources" { depends_on = [helm_release.keycloak] # tflint-ignore: terraform_module_pinned_source diff --git a/outputs.tf b/outputs.tf index 416c173..0d8f42c 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,6 +3,15 @@ output "public_endpoint" { value = module.ingress_resources.service_url } +output "admin_internal_endpoint" { + description = "internal endpoint for admin" + value = { + hostname = format("%v.%v.svc.cluster.local", var.service_name, var.namespace) + port_number = local.admin_internal_port_number + url = format("http://%v:%v", var.service_name, local.admin_internal_port_number) + } +} + output "realm_id" { value = keycloak_realm.realm.id } diff --git a/variables.tf b/variables.tf index 96caf71..7c5091c 100644 --- a/variables.tf +++ b/variables.tf @@ -29,19 +29,19 @@ variable "cluster_domain" { variable "keycloak_database" { description = "The name of the database to create in the RDS instance." type = string - default = "bitnami_keycloak" + default = "keycloak" } variable "keycloak_user" { description = "The username for the database." type = string - default = "bn_keycloak" + default = "keycloak" } variable "keycloak_password" { description = "The initial password for the database." type = string - default = "bn_keycloak" + default = "keycloak" } variable "default_storage_class" { @@ -53,7 +53,7 @@ variable "default_storage_class" { variable "service_name" { description = "The name of the service to be deployed in the EKS cluster." type = string - default = "keycloak-service" + default = "service" } variable "telemetry_namespace" { @@ -68,39 +68,26 @@ variable "postgresql_tag" { default = "17.4.0" } -variable "keycloak_admin_secret" { - description = "Secret key for Keycloak admin client" - type = string - default = "" - sensitive = true -} - -variable "keycloak_hostname" { - description = "The hostname for Keycloak without the domain suffix" - type = string - default = "keycloak-service" -} - variable "realm_name" { description = "Name of the Keycloak realm to create" type = string default = "default" } -variable "admin_username" { +variable "realm_user" { description = "Username for the realm admin user" type = string - default = "admin" + default = "user" } -variable "admin_email" { - description = "Email for the realm admin user" +variable "realm_email" { + description = "Email for the realm user" type = string default = "admin@example.com" } -variable "admin_password" { - description = "Password for the realm admin user" +variable "realm_password" { + description = "Password for the realm user" type = string default = "" sensitive = true From f4510ddb7db7001a65b2e3603507ee8f60b27066 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 22:20:39 -0400 Subject: [PATCH 12/20] fix provider url --- kc_bootstrap.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kc_bootstrap.tf b/kc_bootstrap.tf index 60e4861..ca7c1ca 100644 --- a/kc_bootstrap.tf +++ b/kc_bootstrap.tf @@ -2,7 +2,7 @@ provider "keycloak" { client_id = var.keycloak_user client_secret = var.keycloak_password - url = "https://${module.ingress_resources.service_url}/auth" + url = "${module.ingress_resources.service_url}/auth" } # Create realm From a3f37240735571e306035d759bc10204ee642d41 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 22:22:57 -0400 Subject: [PATCH 13/20] fix outputs for admin internal endpoint --- outputs.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/outputs.tf b/outputs.tf index 0d8f42c..b34db99 100644 --- a/outputs.tf +++ b/outputs.tf @@ -8,7 +8,7 @@ output "admin_internal_endpoint" { value = { hostname = format("%v.%v.svc.cluster.local", var.service_name, var.namespace) port_number = local.admin_internal_port_number - url = format("http://%v:%v", var.service_name, local.admin_internal_port_number) + url = format("http://%v.%v.svc.cluster.local:%v", var.service_name, var.namespace, local.admin_internal_port_number) } } From 493a375a0e7cc16e5f424adddfeef6e99a5fa4b3 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 22:31:29 -0400 Subject: [PATCH 14/20] not in this --- kc_bootstrap.tf | 77 ------------------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 kc_bootstrap.tf diff --git a/kc_bootstrap.tf b/kc_bootstrap.tf deleted file mode 100644 index ca7c1ca..0000000 --- a/kc_bootstrap.tf +++ /dev/null @@ -1,77 +0,0 @@ -# Configure provider -provider "keycloak" { - client_id = var.keycloak_user - client_secret = var.keycloak_password - url = "${module.ingress_resources.service_url}/auth" -} - -# Create realm -resource "keycloak_realm" "realm" { - depends_on = [module.ingress_resources] - - realm = var.realm_name - enabled = true -} - -# Create realm role -resource "keycloak_role" "developer_role" { - depends_on = [module.ingress_resources] - realm_id = keycloak_realm.realm.id - name = "developer" - description = "Developer role for ${var.realm_name}" -} - -# Create admin user -resource "keycloak_user" "user" { - depends_on = [module.ingress_resources] - realm_id = keycloak_realm.realm.id - username = var.realm_user - email = var.realm_email - enabled = true - - initial_password { - value = var.realm_password - temporary = false - } -} - -# Assign role to user -resource "keycloak_user_roles" "user_roles" { - depends_on = [module.ingress_resources] - realm_id = keycloak_realm.realm.id - user_id = keycloak_user.user.id - - role_ids = [ - keycloak_role.developer_role.id - ] -} - -# Create client -resource "keycloak_openid_client" "client" { - depends_on = [module.ingress_resources] - realm_id = keycloak_realm.realm.id - client_id = var.client_id - client_secret = var.client_secret - enabled = true - access_type = "CONFIDENTIAL" - valid_redirect_uris = var.redirect_uris - root_url = var.root_url - base_url = var.base_url -} - -# Create secret with realm creds -resource "kubernetes_secret" "keycloak_realm_creds" { - metadata { - name = "keycloak-${var.realm_name}-creds" - namespace = var.namespace - } - - data = { - username = var.realm_user - password = var.realm_password - client-id = var.client_id - client-secret = var.client_secret - realm-name = var.realm_name - } - -} From dc0c2bbec2046b5613581484fd456b726c69fa75 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 12 Mar 2025 22:37:15 -0400 Subject: [PATCH 15/20] remove realm --- README.md | 18 ----------------- outputs.tf | 8 ++------ variables.tf | 56 ---------------------------------------------------- 3 files changed, 2 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index c3fde13..bc977c9 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,6 @@ Common issues and solutions: | Name | Version | |------|---------| | [helm](#provider\_helm) | 2.17.0 | -| [keycloak](#provider\_keycloak) | 5.1.1 | -| [kubernetes](#provider\_kubernetes) | 2.35.1 | ## Modules @@ -87,20 +85,11 @@ Common issues and solutions: | Name | Type | |------|------| | [helm_release.keycloak](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [keycloak_openid_client.client](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/openid_client) | resource | -| [keycloak_realm.realm](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/realm) | resource | -| [keycloak_role.developer_role](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/role) | resource | -| [keycloak_user.user](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user) | resource | -| [keycloak_user_roles.user_roles](https://registry.terraform.io/providers/keycloak/keycloak/latest/docs/resources/user_roles) | resource | -| [kubernetes_secret.keycloak_realm_creds](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [base\_url](#input\_base\_url) | Base URL for the OpenID client | `string` | `""` | no | -| [client\_id](#input\_client\_id) | Client ID for the OpenID client | `string` | `"app-client"` | no | -| [client\_secret](#input\_client\_secret) | Client secret for the OpenID client | `string` | `""` | no | | [cluster\_domain](#input\_cluster\_domain) | The domain name used to reference ingresses for the cluster. | `string` | n/a | yes | | [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes | | [default\_storage\_class](#input\_default\_storage\_class) | The default storage class to use for persistent volumes | `string` | `"gp3-encrypted"` | no | @@ -111,12 +100,6 @@ Common issues and solutions: | [namespace](#input\_namespace) | The namespace which will be created and into which keycloak will be deployed. | `string` | `"keycloak"` | no | | [postgresql\_tag](#input\_postgresql\_tag) | The tag of the postgresql image to use. | `string` | `"17.4.0"` | no | | [profile](#input\_profile) | AWS config profile used to upload images into ECR | `string` | `""` | no | -| [realm\_email](#input\_realm\_email) | Email for the realm user | `string` | `"admin@example.com"` | no | -| [realm\_name](#input\_realm\_name) | Name of the Keycloak realm to create | `string` | `"default"` | no | -| [realm\_password](#input\_realm\_password) | Password for the realm user | `string` | `""` | no | -| [realm\_user](#input\_realm\_user) | Username for the realm admin user | `string` | `"user"` | no | -| [redirect\_uris](#input\_redirect\_uris) | Valid redirect URIs for the OpenID client | `list(string)` |
[
"*"
]
| no | -| [root\_url](#input\_root\_url) | Root URL for the OpenID client | `string` | `""` | no | | [service\_name](#input\_service\_name) | The name of the service to be deployed in the EKS cluster. | `string` | `"service"` | no | | [telemetry\_namespace](#input\_telemetry\_namespace) | The namespace used for telemetry. | `string` | `"namespace"` | no | @@ -133,5 +116,4 @@ Common issues and solutions: | [namespace](#output\_namespace) | The namespace in which keycloak gets installed in. | | [provider\_config](#output\_provider\_config) | Add provider configuration block for easier consumption | | [public\_endpoint](#output\_public\_endpoint) | The endpoint at which keycloak can be reached from outside the cluster. | -| [realm\_id](#output\_realm\_id) | n/a | diff --git a/outputs.tf b/outputs.tf index b34db99..998f7a7 100644 --- a/outputs.tf +++ b/outputs.tf @@ -12,16 +12,12 @@ output "admin_internal_endpoint" { } } -output "realm_id" { - value = keycloak_realm.realm.id -} - # Add provider configuration block for easier consumption output "provider_config" { value = { - url = "https://${var.service_name}.${var.cluster_domain}" + url = "${module.ingress_resources.service_url}/auth" realm = "master" - client_id = "admin-cli" + client_id = var.keycloak_user } sensitive = true } diff --git a/variables.tf b/variables.tf index 7c5091c..194fdbc 100644 --- a/variables.tf +++ b/variables.tf @@ -67,59 +67,3 @@ variable "postgresql_tag" { type = string default = "17.4.0" } - -variable "realm_name" { - description = "Name of the Keycloak realm to create" - type = string - default = "default" -} - -variable "realm_user" { - description = "Username for the realm admin user" - type = string - default = "user" -} - -variable "realm_email" { - description = "Email for the realm user" - type = string - default = "admin@example.com" -} - -variable "realm_password" { - description = "Password for the realm user" - type = string - default = "" - sensitive = true -} - -variable "client_id" { - description = "Client ID for the OpenID client" - type = string - default = "app-client" -} - -variable "client_secret" { - description = "Client secret for the OpenID client" - type = string - default = "" - sensitive = true -} - -variable "redirect_uris" { - description = "Valid redirect URIs for the OpenID client" - type = list(string) - default = ["*"] -} - -variable "root_url" { - description = "Root URL for the OpenID client" - type = string - default = "" -} - -variable "base_url" { - description = "Base URL for the OpenID client" - type = string - default = "" -} From 4cb331c99d1764b6d6cfacfad19305d419723ca6 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Thu, 13 Mar 2025 18:01:54 -0400 Subject: [PATCH 16/20] give keycloak more than 2 mins --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index c3f7417..4e13d23 100644 --- a/main.tf +++ b/main.tf @@ -9,7 +9,7 @@ resource "helm_release" "keycloak" { name = var.service_name repository = "${path.module}/charts" create_namespace = true - timeout = 120 + timeout = 300 wait = true namespace = var.namespace From a811f0d1a412aceef1a73cacdedd00e441c51fc8 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 1 Apr 2025 11:49:20 -0400 Subject: [PATCH 17/20] add module release process --- .github/workflows/terraform-ci.yml | 104 ---------------------- .github/workflows/terraform-release.yaml | 73 +++++++++++++++ .github/workflows/terraform-validate.yaml | 42 +++++++++ 3 files changed, 115 insertions(+), 104 deletions(-) delete mode 100644 .github/workflows/terraform-ci.yml create mode 100644 .github/workflows/terraform-release.yaml create mode 100644 .github/workflows/terraform-validate.yaml diff --git a/.github/workflows/terraform-ci.yml b/.github/workflows/terraform-ci.yml deleted file mode 100644 index cf3f91c..0000000 --- a/.github/workflows/terraform-ci.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: 'Terraform Module CI' - -on: - push: - branches: - - main - paths: - - '**/*.tf' - pull_request: - branches: - - main - paths: - - '**/*.tf' - workflow_dispatch: - -permissions: - contents: read - pull-requests: write - -jobs: - validate: - name: 'Validate Module' - runs-on: self-hosted - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Terraform - uses: hashicorp/setup-terraform@v2 - with: - terraform_version: 1.5.0 - - - name: Terraform Init - run: | - terraform init -backend=false - - - name: Terraform Format - run: | - terraform fmt -check - - - name: Terraform Validate - run: | - terraform validate - - - name: Run tflint - uses: terraform-linters/setup-tflint@v3 - if: github.event_name == 'pull_request' - - - name: Lint Terraform - if: github.event_name == 'pull_request' - run: | - tflint --format compact - - - name: Run Checkov - uses: bridgecrewio/checkov-action@master - with: - directory: . - framework: terraform - skip_check: CKV_AWS_115,CKV_AWS_116 - quiet: true - soft_fail: true - output_format: sarif - output_file: checkov-results.sarif - - release: - name: 'Create Release' - needs: validate - if: github.ref == 'refs/heads/main' && github.event_name == 'push' - runs-on: self-hosted - permissions: - contents: write - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - - name: Install Commitizen - run: | - pip install commitizen - - - name: Bump Version and Generate Changelog - id: cz - run: | - cz bump --yes - echo "new_version=$(cz version --project)" >> $GITHUB_OUTPUT - echo "changelog=$(cz changelog --dry-run)" >> $GITHUB_OUTPUT - - - name: Create Release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: v${{ steps.cz.outputs.new_version }} - release_name: Release v${{ steps.cz.outputs.new_version }} - draft: false - prerelease: false - body: ${{ steps.cz.outputs.changelog }} diff --git a/.github/workflows/terraform-release.yaml b/.github/workflows/terraform-release.yaml new file mode 100644 index 0000000..90910bc --- /dev/null +++ b/.github/workflows/terraform-release.yaml @@ -0,0 +1,73 @@ +name: Terraform CI/CD +on: + workflow_dispatch: + pull_request: + types: [closed] + branches: + - main +jobs: + terraform-ci-cd: + runs-on: 229685449397 + permissions: + contents: write + + steps: + - name: Checkout code + uses: CSVD/gh-actions-checkout@v4 + + - name: Setup Terraform + uses: CSVD/gh-actions-setup-terraform@v3 + with: + terraform_version: "1.9.1" + + - name: Setup GITHUB Credentials + id: github_credentials + uses: CSVD/gh-auth@main + with: + github_app_pem_file: ${{ secrets.GH_APP_PEM_FILE }} + github_app_installation_id: ${{ vars.GH_APP_INSTALLATION_ID }} + github_app_id: ${{ vars.GH_APP_ID }} + + + - name: Debug Authentication + run: | + # Print the GitHub server URL + echo "GitHub Server URL: ${{ github.server_url }}" + + # Extract the host from the URL + HOST="${{ github.server_url }}" + HOST="${HOST#*//}" + HOST="${HOST%%/*}" + echo "GitHub Host: $HOST" + + # Check if token exists + if [[ -n "${{ steps.github_credentials.outputs.github_token }}" ]]; then + echo "Token generated successfully" + # Test the token with a simple GitHub API call (without exposing the token) + STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${{ steps.github_credentials.outputs.github_token }}" "${{ github.server_url }}/api/v3/user") + echo "API Test Status Code: $STATUS" + else + echo "No token was generated!" + fi + + - name: Setup GitHub CLI + run: | + # Force manual authentication since setup-git might not work with GitHub Enterprise + echo "${{ steps.github_credentials.outputs.github_token }}" > /tmp/token.txt + gh auth login --with-token --hostname "github.e.it.census.gov" < /tmp/token.txt + rm /tmp/token.txt + + # Test GitHub CLI auth status + gh auth status || echo "GitHub CLI authentication failed" + + - name: AWS Auth + id: aws_auth + uses: CSVD/aws-auth@main + with: + ecs: true + + - name: Run Terraform Module Release Action + uses: CSVD/terraform-module-release@main + with: + github-token: ${{ steps.github_credentials.outputs.github_token }} + working-directory: '.' diff --git a/.github/workflows/terraform-validate.yaml b/.github/workflows/terraform-validate.yaml new file mode 100644 index 0000000..72829d8 --- /dev/null +++ b/.github/workflows/terraform-validate.yaml @@ -0,0 +1,42 @@ +name: Terraform Validate +on: + pull_request: + workflow_dispatch: + +jobs: + + terraform-validate: + runs-on: "229685449397" + permissions: + contents: write + steps: + - name: Checkout code + uses: CSVD/gh-actions-checkout@v4 + + - name: Setup Terraform + uses: CSVD/gh-actions-setup-terraform@v2 + with: + terraform_version: '1.7.3' + + - name: Validate Terraform Configuration + id: validate + uses: CSVD/terraform-validate@main + + - name: Check Validation/Test Results + if: always() + run: | + # Set default values if outputs are empty + IS_VALID="${{ steps.validate.outputs.is_valid }}" + TESTS_PASSED="${{ steps.validate.outputs.tests_passed }}" + + # If outputs are empty, set them to false + [ -z "$IS_VALID" ] && IS_VALID="false" + [ -z "$TESTS_PASSED" ] && TESTS_PASSED="false" + + if [[ "$IS_VALID" != "true" || "$TESTS_PASSED" != "true" ]]; then + echo "Validation or test errors found:" + echo "${{ steps.validate.outputs.stderr }}" + exit 1 + else + echo "All validations and tests passed successfully!" + fi From 917c5ee3c23f032e5d9a8a8b561f6c24db3adbed Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 1 Apr 2025 21:49:01 -0400 Subject: [PATCH 18/20] update module sources --- .pre-commit-config.yaml | 4 ++-- README.md | 4 ++-- copy_images.tf | 2 +- main.tf | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d247a5..7ef969f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: # Terraform Hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.97.3 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases + rev: v1.98.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases hooks: - id: terraform_fmt args: @@ -104,6 +104,6 @@ repos: # - --hook-config=--parallelism-ci-cpu-cores=2 - repo: https://github.com/ljnsn/cz-conventional-gitmoji - rev: v0.6.1 + rev: v0.7.0 hooks: - id: conventional-gitmoji diff --git a/README.md b/README.md index bc977c9..95208a2 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,8 @@ Common issues and solutions: | Name | Source | Version | |------|--------|---------| -| [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | -| [ingress\_resources](#module\_ingress\_resources) | git@github.e.it.census.gov:SCT-Engineering/tfmod-istio-service-ingress.git | main | +| [images](#module\_images) | git::https://github.e.it.census.gov/terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | +| [ingress\_resources](#module\_ingress\_resources) | git::https://github.e.it.census.gov/SCT-Engineering/tfmod-istio-service-ingress.git | main | ## Resources diff --git a/copy_images.tf b/copy_images.tf index 86ee348..9ea2ccd 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -36,7 +36,7 @@ locals { } module "images" { - source = "git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/?ref=tf-upgrade" + source = "git::https://github.e.it.census.gov/terraform-modules/aws-ecr-copy-images.git/?ref=tf-upgrade" profile = var.profile application_name = var.cluster_name diff --git a/main.tf b/main.tf index 4e13d23..1d320cd 100644 --- a/main.tf +++ b/main.tf @@ -37,7 +37,7 @@ resource "helm_release" "keycloak" { module "ingress_resources" { depends_on = [helm_release.keycloak] # tflint-ignore: terraform_module_pinned_source - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-istio-service-ingress.git?ref=main" + source = "git::https://github.e.it.census.gov/SCT-Engineering/tfmod-istio-service-ingress.git?ref=main" public_hostname = var.service_name public_domain = var.cluster_domain service_name = var.service_name From eecbd418fec020715825ba4e00a20bd5a2c6f390 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Thu, 3 Apr 2025 13:08:28 -0400 Subject: [PATCH 19/20] update release action --- .github/workflows/terraform-release.yaml | 37 +--------------- .github/workflows/terraform-validate.yaml | 54 +++++++++++------------ 2 files changed, 28 insertions(+), 63 deletions(-) diff --git a/.github/workflows/terraform-release.yaml b/.github/workflows/terraform-release.yaml index 90910bc..04b96db 100644 --- a/.github/workflows/terraform-release.yaml +++ b/.github/workflows/terraform-release.yaml @@ -15,11 +15,6 @@ jobs: - name: Checkout code uses: CSVD/gh-actions-checkout@v4 - - name: Setup Terraform - uses: CSVD/gh-actions-setup-terraform@v3 - with: - terraform_version: "1.9.1" - - name: Setup GITHUB Credentials id: github_credentials uses: CSVD/gh-auth@main @@ -28,28 +23,6 @@ jobs: github_app_installation_id: ${{ vars.GH_APP_INSTALLATION_ID }} github_app_id: ${{ vars.GH_APP_ID }} - - - name: Debug Authentication - run: | - # Print the GitHub server URL - echo "GitHub Server URL: ${{ github.server_url }}" - - # Extract the host from the URL - HOST="${{ github.server_url }}" - HOST="${HOST#*//}" - HOST="${HOST%%/*}" - echo "GitHub Host: $HOST" - - # Check if token exists - if [[ -n "${{ steps.github_credentials.outputs.github_token }}" ]]; then - echo "Token generated successfully" - # Test the token with a simple GitHub API call (without exposing the token) - STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${{ steps.github_credentials.outputs.github_token }}" "${{ github.server_url }}/api/v3/user") - echo "API Test Status Code: $STATUS" - else - echo "No token was generated!" - fi - - name: Setup GitHub CLI run: | # Force manual authentication since setup-git might not work with GitHub Enterprise @@ -60,14 +33,8 @@ jobs: # Test GitHub CLI auth status gh auth status || echo "GitHub CLI authentication failed" - - name: AWS Auth - id: aws_auth - uses: CSVD/aws-auth@main - with: - ecs: true - - - name: Run Terraform Module Release Action - uses: CSVD/terraform-module-release@main + - name: Run Release Action + uses: CSVD/releaser@main with: github-token: ${{ steps.github_credentials.outputs.github_token }} working-directory: '.' diff --git a/.github/workflows/terraform-validate.yaml b/.github/workflows/terraform-validate.yaml index 72829d8..04b96db 100644 --- a/.github/workflows/terraform-validate.yaml +++ b/.github/workflows/terraform-validate.yaml @@ -1,42 +1,40 @@ -name: Terraform Validate +name: Terraform CI/CD on: - pull_request: workflow_dispatch: - + pull_request: + types: [closed] + branches: + - main jobs: - - terraform-validate: - runs-on: "229685449397" + terraform-ci-cd: + runs-on: 229685449397 permissions: contents: write + steps: - name: Checkout code uses: CSVD/gh-actions-checkout@v4 - - name: Setup Terraform - uses: CSVD/gh-actions-setup-terraform@v2 + - name: Setup GITHUB Credentials + id: github_credentials + uses: CSVD/gh-auth@main with: - terraform_version: '1.7.3' - - - name: Validate Terraform Configuration - id: validate - uses: CSVD/terraform-validate@main + github_app_pem_file: ${{ secrets.GH_APP_PEM_FILE }} + github_app_installation_id: ${{ vars.GH_APP_INSTALLATION_ID }} + github_app_id: ${{ vars.GH_APP_ID }} - - name: Check Validation/Test Results - if: always() + - name: Setup GitHub CLI run: | - # Set default values if outputs are empty - IS_VALID="${{ steps.validate.outputs.is_valid }}" - TESTS_PASSED="${{ steps.validate.outputs.tests_passed }}" + # Force manual authentication since setup-git might not work with GitHub Enterprise + echo "${{ steps.github_credentials.outputs.github_token }}" > /tmp/token.txt + gh auth login --with-token --hostname "github.e.it.census.gov" < /tmp/token.txt + rm /tmp/token.txt - # If outputs are empty, set them to false - [ -z "$IS_VALID" ] && IS_VALID="false" - [ -z "$TESTS_PASSED" ] && TESTS_PASSED="false" + # Test GitHub CLI auth status + gh auth status || echo "GitHub CLI authentication failed" - if [[ "$IS_VALID" != "true" || "$TESTS_PASSED" != "true" ]]; then - echo "Validation or test errors found:" - echo "${{ steps.validate.outputs.stderr }}" - exit 1 - else - echo "All validations and tests passed successfully!" - fi + - name: Run Release Action + uses: CSVD/releaser@main + with: + github-token: ${{ steps.github_credentials.outputs.github_token }} + working-directory: '.' From 95f606a71394b11df096e70770f956b302ca8350 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Thu, 3 Apr 2025 13:39:40 -0400 Subject: [PATCH 20/20] fix validate: --- .github/workflows/terraform-validate.yaml | 54 ++++++++++++----------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/.github/workflows/terraform-validate.yaml b/.github/workflows/terraform-validate.yaml index 04b96db..ac349eb 100644 --- a/.github/workflows/terraform-validate.yaml +++ b/.github/workflows/terraform-validate.yaml @@ -1,40 +1,42 @@ -name: Terraform CI/CD +name: Terraform Validate on: - workflow_dispatch: pull_request: - types: [closed] - branches: - - main + workflow_dispatch: + jobs: - terraform-ci-cd: - runs-on: 229685449397 + + terraform-validate: + runs-on: "229685449397" permissions: contents: write - steps: - name: Checkout code uses: CSVD/gh-actions-checkout@v4 - - name: Setup GITHUB Credentials - id: github_credentials - uses: CSVD/gh-auth@main + - name: Setup Terraform + uses: CSVD/gh-actions-setup-terraform@v2 with: - github_app_pem_file: ${{ secrets.GH_APP_PEM_FILE }} - github_app_installation_id: ${{ vars.GH_APP_INSTALLATION_ID }} - github_app_id: ${{ vars.GH_APP_ID }} + terraform_version: '1.10.5' + + - name: Validate Terraform Configuration + id: validate + uses: CSVD/terraform-validate@main - - name: Setup GitHub CLI + - name: Check Validation/Test Results + if: always() run: | - # Force manual authentication since setup-git might not work with GitHub Enterprise - echo "${{ steps.github_credentials.outputs.github_token }}" > /tmp/token.txt - gh auth login --with-token --hostname "github.e.it.census.gov" < /tmp/token.txt - rm /tmp/token.txt + # Set default values if outputs are empty + IS_VALID="${{ steps.validate.outputs.is_valid }}" + TESTS_PASSED="${{ steps.validate.outputs.tests_passed }}" - # Test GitHub CLI auth status - gh auth status || echo "GitHub CLI authentication failed" + # If outputs are empty, set them to false + [ -z "$IS_VALID" ] && IS_VALID="false" + [ -z "$TESTS_PASSED" ] && TESTS_PASSED="false" - - name: Run Release Action - uses: CSVD/releaser@main - with: - github-token: ${{ steps.github_credentials.outputs.github_token }} - working-directory: '.' + if [[ "$IS_VALID" != "true" || "$TESTS_PASSED" != "true" ]]; then + echo "Validation or test errors found:" + echo "${{ steps.validate.outputs.stderr }}" + exit 1 + else + echo "All validations and tests passed successfully!" + fi