OIDC Bootstrap
A DevOps Stack module to bootstrap a realm, an administrators group with one or more users and an OIDC client in order to use Keycloak as an OIDC provider.
This module allows you to have a working authentication provider for the DevOps Stack without having to configure Keycloak manually.
Because the main use of this module is to have a working Keycloak instance in a development environment, it provides a sensible configuration with some secure enough defaults. However, it is not recommended to be used in a production environment. For that purpose, we recommend you simply use this module as an example. Take a look at the code and read the provider’s documentation to get an idea on how it can be used manage your Keycloak instance. |
Usage
After deploying Keycloak using the main module on this repository, first you need to add the provider configuration necessary on your root module:
terraform {
required_providers {
keycloak = {
source = "mrparkers/keycloak"
}
}
}
provider "keycloak" {
client_id = "admin-cli"
username = module.keycloak.admin_credentials.username
password = module.keycloak.admin_credentials.password
url = "https://keycloak.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}"
initial_login = false # Do no try to setup the provider before Keycloak is provisioned.
tls_insecure_skip_verify = true # Since we are in a testing environment, do not verify the authenticity of SSL certificates.
}
The argument initial_login absolutely needs to be set as false , otherwise Terraform will try to connect to Keycloak before it is deployed. The argument tls_insecure_skip_verify needs to be set as false only on testing environments, when using self-signed SSL certificates.
|
After setting up the provider, you can then bootstrap the authentication configuration like this:
module "oidc" {
source = "git::https://github.com/camptocamp/devops-stack-module-keycloak.git//oidc_bootstrap?ref=<RELEASE>"
cluster_name = local.cluster_name
base_domain = format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))
dependency_ids = {
keycloak = module.keycloak.id
}
}
User Configuration
By default, the oicd_bootstrap
module creates a basic realm containing a placeholder user that you can use out-of-the-box to authenticate to the other applications on the DevOps Stack.
However, you can provide a map of desired users and the submodule creates them all with an initial password that can then be changed.
Simply declare the module as follows:
module "oidc" {
source = "git::https://github.com/camptocamp/devops-stack-module-keycloak.git//oidc_bootstrap?ref=<RELEASE>"
cluster_name = local.cluster_name
base_domain = format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))
user_map = {
johndoe = {
username = "johndoe"
first_name = "John"
last_name = "Doe"
email = "john.doe@example.com"
}
janedoe = {
username = "janedoe"
first_name = "Jane"
last_name = "Doe"
email = "jane.doe@example.com"
}
}
dependency_ids = {
keycloak = module.keycloak.id
}
}
All the fields on each user are required. Besides, since the e-mail is a scope required by most of our apps, the e-mail is automatically set as verified when the users are created. |
All users will belong to the administrators group and will have high privileges in applications such as Argo CD and MinIO. |
The module contains an output called devops_stack_users_passwords
where you can get a map containing every username and their respective initial password.
OIDC Configuration
By default, the OIDC client is configured to allow returning to any URL after the authentication is successful. If you prefer, you can restrict only the redirect URIs to a list of domains using the input variable oidc_redirect_uris
:
module "oidc" {
source = "git::https://github.com/camptocamp/devops-stack-module-keycloak.git//oidc_bootstrap?ref=<RELEASE>"
cluster_name = local.cluster_name
base_domain = format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))
oidc_redirec_uris = [
"https://argocd.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}/auth/callback",
"https://grafana.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}/login/generic_oauth",
"https://prometheus.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}/oauth2/callback",
"https://thanos-query.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}/oauth2/callback",
"https://thanos-bucketweb.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}/oauth2/callback",
"https://alertmanager.apps.${local.cluster_name}.${format("%s.nip.io", replace(module.ingress.external_ip, ".", "-"))}/oauth2/callback",
]
dependency_ids = {
keycloak = module.keycloak.id
}
}
The module provides and output called oidc
containing the OIDC configuration that is to be passed on to other modules. This output is an object that outputs the content of local.oidc
:
locals {
oidc = {
issuer_url = format("https://keycloak.apps.%s.%s/realms/devops-stack", var.cluster_name, var.base_domain)
oauth_url = format("https://keycloak.apps.%s.%s/realms/devops-stack/protocol/openid-connect/auth", var.cluster_name, var.base_domain)
token_url = format("https://keycloak.apps.%s.%s/realms/devops-stack/protocol/openid-connect/token", var.cluster_name, var.base_domain)
api_url = format("https://keycloak.apps.%s.%s/realms/devops-stack/protocol/openid-connect/userinfo", var.cluster_name, var.base_domain)
client_id = "devops-stack-applications"
client_secret = resource.random_password.client_secret.result
oauth2_proxy_extra_args = var.cluster_issuer == "ca-issuer" ? [
"--insecure-oidc-skip-issuer-verification=true",
"--ssl-insecure-skip-verify=true",
] : []
}
}
Technical Reference
Resources
The following resources are used by this module:
-
keycloak_group.devops_stack_admins (resource)
-
keycloak_openid_client.devops_stack (resource)
-
keycloak_openid_client_default_scopes.client_default_scopes (resource)
-
keycloak_openid_client_scope.devops_stack_minio_policy (resource)
-
keycloak_openid_group_membership_protocol_mapper.devops_stack_groups (resource)
-
keycloak_openid_user_attribute_protocol_mapper.devops_stack_minio_policy (resource)
-
keycloak_realm.devops_stack (resource)
-
keycloak_user.devops_stack_users (resource)
-
keycloak_user_groups.devops_stack_admins (resource)
-
null_resource.dependencies (resource)
-
null_resource.this (resource)
-
random_password.client_secret (resource)
-
random_password.devops_stack_users (resource)
Required Inputs
The following input variables are required:
cluster_name
Description: Name given to the cluster. Value used for the ingress' URL of the application.
Type: string
base_domain
Description: Base domain of the cluster. Value used for the ingress' URL of the application.
Type: string
Optional Inputs
The following input variables are optional (have default values):
cluster_issuer
Description: SSL certificate issuer to use. In this module it is used to conditionally add extra arguments to the OIDC configuration.
Type: string
Default: "ca-issuer"
dependency_ids
Description: IDs of the other modules on which this module depends on.
Type: map(string)
Default: {}
oidc_redirect_uris
Description: List of URIs where the authentication server is allowed to return during the authentication flow.
Type: list(string)
Default:
[
"*"
]
user_map
Description: List of users to be added to the DevOps Stack Realm. Note that all fields are mandatory.
Type:
map(object({
username = string
email = string
first_name = string
last_name = string
}))
Default:
{
"devopsadmin": {
"email": "devopsadmin@devops-stack.io",
"first_name": "Administrator",
"last_name": "DevOps Stack",
"username": "devopsadmin"
}
}
Outputs
The following outputs are exported:
id
Description: ID to pass other modules in order to refer to this module as a dependency.
oidc
Description: Object containing multiple OIDC configuration values.
devops_stack_users_passwords
Description: Map containing the credentials of each created user.
Reference in table format
Show tables
= Requirements
Name | Version |
---|---|
>= 4 |
|
>= 3 |
|
>= 3 |
= Providers
Name | Version |
---|---|
>= 4 |
|
>= 3 |
|
>= 3 |
= Resources
Name | Type |
---|---|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
|
resource |
= Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
Name given to the cluster. Value used for the ingress' URL of the application. |
|
n/a |
yes |
|
Base domain of the cluster. Value used for the ingress' URL of the application. |
|
n/a |
yes |
|
SSL certificate issuer to use. In this module it is used to conditionally add extra arguments to the OIDC configuration. |
|
|
no |
|
IDs of the other modules on which this module depends on. |
|
|
no |
|
List of URIs where the authentication server is allowed to return during the authentication flow. |
|
|
no |
|
List of users to be added to the DevOps Stack Realm. Note that all fields are mandatory. |
|
|
no |
= Outputs
Name | Description |
---|---|
ID to pass other modules in order to refer to this module as a dependency. |
|
Object containing multiple OIDC configuration values. |
|
Map containing the credentials of each created user. |