Elestio Keycloak Cluster Terraform module
Benefits of a Keycloak cluster
A Keycloak cluster can handle more users without slowing down or crashing, and provides fault tolerance to ensure that the system remains operational. It also allows for easy scalability to meet changing demands without replacing the entire system.
Module usage
This is a minimal example of how to use the module:
module "cluster" {
source = "elestio-examples/keycloak-cluster/elestio"
project_id = "xxxxxx"
keycloak_pass = "xxxxxx"
database = "postgres"
database_host = "xxxxxx"
database_port = "5432"
database_name = "xxxxxx"
database_schema = "public"
database_user = "xxxxxx"
database_pass = "xxxxxx"
configuration_ssh_key = {
username = "something"
public_key = chomp(file("~/.ssh/id_rsa.pub"))
private_key = file("~/.ssh/id_rsa")
}
nodes = [
{
server_name = "keycloak-1"
provider_name = "hetzner"
datacenter = "fsn1"
server_type = "SMALL-1C-2G"
},
{
server_name = "keycloak-2"
provider_name = "hetzner"
datacenter = "nbg1"
server_type = "SMALL-1C-2G"
},
]
}
Keep your keycloak password safe, you will need it to access the admin panel.
If you want to know more about node configuration, check the keycloak service documentation here.
If you want to choose your own provider, datacenter or server type, check the guide here.
If you want to generated a valid SSH Key, check the guide here.
If you add more nodes, you may attains the resources limit of your account, please visit your account quota page.
Step-by-step
The following example will create a Keycloak cluster with 2 nodes, a database and a load balancer. You may need to adjust the configuration to fit your needs.
1. Store your secrets
Some secrets are required to create the cluster.
For security reasons, we recommend to store them in a .tfvars
file and add it to your .gitignore
file.
Create a terraform.tfvars
file:
# terraform.tfvars
elestio_email = "****" # Create an Elestio account https://dash.elest.io/signup
elestio_api_token = "****" # Generate an API token https://dash.elest.io/account/security
keycloak_pass = "****" # Generated a keycloak password https://api.elest.io/api/auth/passwordgenerator
Terraform needs a ssh key to connect to the nodes and configure them. If you don't have one, you can create it with the following command:
ssh-keygen -t rsa
Remember the path and name, we will need it later.
2. Write the configuration
Create a main.tf
file:
# main.tf
variable "elestio_email" {
type = string
}
variable "elestio_api_token" {
type = string
sensitive = true
}
variable "keycloak_pass" {
type = string
sensitive = true
}
terraform {
required_providers {
elestio = {
source = "elestio/elestio"
}
}
}
provider "elestio" {
email = var.elestio_email
api_token = var.elestio_api_token
}
resource "elestio_project" "project" {
name = "Keycloak Cluster"
}
Add a database:
# ...main.tf
resource "elestio_postgresql" "database" {
project_id = elestio_project.project.id
provider_name = "hetzner"
datacenter = "fsn1"
server_type = "SMALL-1C-2G"
}
-> If you want to choose your own provider, datacenter or server type, check the guide here.
Add the module:
# ...main.tf
module "cluster" {
source = "elestio-examples/keycloak-cluster/elestio"
project_id = elestio_project.project.id
keycloak_version = null # null means latest version
keycloak_pass = var.keycloak_pass
database = "postgres"
database_host = elestio_postgresql.database.cname
database_port = elestio_postgresql.database.database_admin.port
database_name = "postgres"
database_schema = "public"
database_user = elestio_postgresql.database.database_admin.user
database_pass = elestio_postgresql.database.database_admin.password
configuration_ssh_key = {
username = "terraform"
public_key = chomp(file("~/.ssh/id_rsa.pub"))
private_key = file("~/.ssh/id_rsa")
}
nodes = [
{
server_name = "keycloak-1"
provider_name = "hetzner"
datacenter = "fsn1"
server_type = "SMALL-1C-2G"
},
{
server_name = "keycloak-2"
provider_name = "hetzner"
datacenter = "nbg1"
server_type = "SMALL-1C-2G"
},
]
}
Add a load balancer:
# ...main.tf
resource "elestio_load_balancer" "load_balancer" {
project_id = elestio_project.project.id
provider_name = "hetzner"
datacenter = "fsn1"
server_type = "SMALL-1C-2G"
config = {
target_services = [for node in module.cluster.nodes : node.id]
forward_rules = [
{
port = "443"
protocol = "HTTPS"
target_port = "443"
target_protocol = "HTTPS"
},
]
}
}
Finally, let's add some outputs to retrieve useful information when the cluster is ready:
# ...main.tf
output "database_admin" {
value = elestio_postgresql.database.admin
sensitive = true
}
output "nodes_admins" {
value = { for node in module.cluster.nodes : node.server_name => node.admin }
sensitive = true
}
output "load_balancer_cname" {
value = elestio_load_balancer.load_balancer.cname
}
3. Run the configuration
You can now run terraform init
and terraform apply
to create your Keycloak cluster.
After a few minutes, the cluster will be ready to use.
You can access your outputs with terraform output
:
$ terraform output database_admin
$ terraform output nodes_admins
$ terraform output load_balancer_cname
If you want to update some parameters, you can edit the main.tf
file and run terraform apply
again.
Terraform will automatically update the cluster to match the new configuration.
Please note that changing the node count requires to change the .env of existing nodes. This is done automatically by the module.
Ready-to-deploy example
We created a ready-to-deploy example which creates the same infrastructure as the previous example. You can find it here. Follow the instructions to deploy the example.
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
configuration_ssh_key | After the nodes are created, Terraform must connect to apply some custom configuration. This configuration is done using SSH from your local machine. The Public Key will be added to the nodes and the Private Key will be used by your local machine to connect to the nodes. Read the guide "How generate a valid SSH Key for Elestio". Example: configuration_ssh_key = { |
object({ |
n/a | yes |
database | Allowed values are postgres , cockroach , mariadb , mysql , oracle , or mssql . |
string |
"postgres" |
no |
database_host | n/a | string |
n/a | yes |
database_name | n/a | string |
"postgres" |
no |
database_pass | n/a | string |
n/a | yes |
database_port | n/a | string |
"5432" |
no |
database_schema | n/a | string |
"public" |
no |
database_user | n/a | string |
n/a | yes |
keycloak_pass | The password can only contain alphanumeric characters or hyphens - .Require at least 10 characters, one uppercase letter, one lowercase letter and one number. Example: qfeE42snU-bt0y-1KwbwZDq DO NOT USE THIS EXAMPLE PASSWORD. |
string |
n/a | yes |
keycloak_version | The cluster nodes must share the same keycloak version. Leave empty or set to null to use the Elestio recommended version. |
string |
null |
no |
nodes | Each element of this list will create an Elestio Keycloak Resource in your cluster. Read the following documentation to understand what each attribute does, plus the default values: Elestio Keycloak Resource. |
list( |
[] |
no |
project_id | n/a | string |
n/a | yes |
Outputs
Name | Description |
---|---|
nodes | This is the created nodes full information |
Providers
Name | Version |
---|---|
elestio | = 0.13.0 |
null | = 3.2.0 |
Requirements
Name | Version |
---|---|
terraform | >= 1.0 |
elestio | = 0.13.0 |
null | = 3.2.0 |
Resources
Name | Type |
---|---|
elestio_keycloak.nodes | resource |
null_resource.update_nodes_env | resource |