Skip to main content
Version: Next

Keycloak on Aruba Cloud

Deploy Keycloak — enterprise identity and access management — on Aruba Cloud using Terraform and cloud-init. Keycloak runs in production Quarkus mode backed by a local PostgreSQL database.

Provider version: arubacloud/arubacloud ~> 1.0 | Terraform: ≥ 1.9


Introduction​

Keycloak is a CNCF-graduated open-source IAM platform providing SSO, OIDC, OAuth2, and SAML 2.0. This example deploys Keycloak with:

  • Keycloak Quarkus distribution in production server mode — not dev mode, no ephemeral H2 database
  • Local PostgreSQL — Keycloak officially supports PostgreSQL and MariaDB. Managed MySQL from the ArubaCloud DBaaS is not on the Keycloak support matrix and is not used here
  • nginx reverse proxy on ports 80/443 with correct forwarding headers (X-Forwarded-*), while Keycloak binds to 127.0.0.1:8080
  • Admin user created automatically on first start via systemd environment file — log in immediately after bootstrap
  • Optional ACME HTTPS when a custom domain is provided (via an ACME provider such as Actalis ACME Certificates or Let's Encrypt)

Architecture Overview​


Infrastructure Created​

ResourceName patternDescription
arubacloud_projectkc-prodProject container
arubacloud_vpckc-prod-vpcVirtual Private Cloud
arubacloud_subnetkc-prod-subnetBasic subnet
arubacloud_securitygroupkc-prod-vm-sgSecurity group
arubacloud_securityrulekc-prod-vm-sshSSH ingress
arubacloud_securityrulekc-prod-vm-httpHTTP ingress
arubacloud_securityrulekc-prod-vm-httpsHTTPS ingress
arubacloud_elasticipkc-prod-vm-eipVM public IP
arubacloud_blockstoragekc-prod-boot50 GB boot disk (Performance)
arubacloud_keypairkc-prod-keypairSSH public key
arubacloud_cloudserverkc-prod-vmCloudServer VM

Estimated Monthly Cost​

ResourceSpecEst. cost/mo
CloudServer VMCSO4A8 — 4 vCPU / 8 GB~€36
Boot disk50 GB Performance~€6
Elastic IP—~€3
Total~€45/mo

Requirements​

  • Terraform ≥ 1.9
  • ArubaCloud Terraform Provider ~> 1.0
  • An ArubaCloud account with OAuth2 API credentials
  • An SSH key pair

Variables​

Required​

VariableDescription
arubacloud_client_idArubaCloud OAuth2 client ID
arubacloud_client_secretArubaCloud OAuth2 client secret
ssh_public_keySSH public key content
keycloak_admin_passwordKeycloak admin password (min 12 chars)
db_passwordPostgreSQL Keycloak user password (min 16 chars)

Optional​

VariableDefaultDescription
app_name"kc"Short name used in all resource names
environment"prod"Environment label
location"ITBG-Bergamo"ArubaCloud region
zone"ITBG-1"Availability zone
billing_period"Hour""Hour" or "Month"
vm_flavor"CSO4A8"CloudServer flavor
vm_image"LU22-001"Boot disk image (Ubuntu 22.04 LTS)
vm_disk_size_gb50Boot disk size in GB
ssh_cidr"0.0.0.0/0"CIDR for SSH — restrict to your IP
keycloak_admin"admin"Keycloak admin username
keycloak_version"26.0.7"Keycloak release version
domain""Custom domain for HTTPS — leave empty to use the Elastic IP

Outputs​

OutputDescription
keycloak_urlKeycloak URL
admin_console_urlKeycloak Admin Console URL
vm_public_ipPublic IP of the VM
ssh_commandSSH command to connect
keycloak_adminAdmin username

Deployment Instructions​

1. Clone and navigate​

git clone https://github.com/arubacloud/terraform-arubacloud-examples.git
cd terraform-arubacloud-examples/keycloak

2. Configure variables​

cp terraform.tfvars.example terraform.tfvars

Set keycloak_admin_password and db_password.

3. Deploy​

terraform init
terraform plan
terraform apply

Bootstrap takes approximately 8–12 minutes — Keycloak downloads ~120 MB and kc.sh build compiles the Quarkus app.

4. Access the Admin Console​

terraform output admin_console_url

Log in with the admin username and keycloak_admin_password. Create your realms, clients, and users.

5. Monitor bootstrap progress​

ssh ubuntu@$(terraform output -raw vm_public_ip)
sudo tail -f /var/log/cloud-init-output.log
# Or follow Keycloak logs:
sudo journalctl -u keycloak -f

Security Recommendations​

  1. Use HTTPS. Set domain to enable TLS via an ACME provider such as Actalis ACME Certificates or Let's Encrypt. Keycloak tokens transmitted over HTTP can be intercepted.

  2. Restrict SSH. Set ssh_cidr = "your.ip/32".

  3. Change the admin password after first login to a strong unique value.

  4. Disable the master realm for production use. Create a dedicated realm for your applications and disable direct access to the master realm.

  5. Enable brute-force protection. In Realm Settings → Security Defenses → Brute Force Detection.

  6. Back up the PostgreSQL database regularly — all realm, user, and client configuration is stored there.


Upgrade Considerations​

Keycloak upgrade​

Update keycloak_version in terraform.tfvars and run terraform apply. This replaces the VM and PostgreSQL data is lost unless you back it up first.

For in-place upgrades:

ssh ubuntu@$(terraform output -raw vm_public_ip)
KC_VERSION=X.Y.Z
sudo systemctl stop keycloak
sudo curl -sSfL \
"https://github.com/keycloak/keycloak/releases/download/$KC_VERSION/keycloak-$KC_VERSION.tar.gz" \
| sudo tar -xz -C /opt
sudo mv /opt/keycloak /opt/keycloak-old && sudo mv /opt/keycloak-$KC_VERSION /opt/keycloak
sudo cp /opt/keycloak-old/conf/keycloak.conf /opt/keycloak/conf/
sudo chown -R keycloak:keycloak /opt/keycloak
sudo -u keycloak /opt/keycloak/bin/kc.sh build --db=postgres --http-enabled=true
sudo systemctl start keycloak

Review the Keycloak upgrade guide for breaking changes.


Troubleshooting​

Keycloak not reachable after apply​

sudo systemctl status keycloak
sudo journalctl -u keycloak -n 50
sudo tail -f /var/log/cloud-init-output.log

Keycloak takes 2–4 minutes to start the first time (kc.sh build must run first). Subsequent starts are faster.

Admin console returns 403​

Ensure the hostname in keycloak.conf matches the hostname you are accessing Keycloak from. With IP access and no domain, hostname-strict=false is already set.

PostgreSQL connection refused​

sudo systemctl status postgresql
sudo -u postgres psql -c "\l" # list databases
sudo -u postgres psql -c "\du" # list users

References​