How to install Keycloak on Azure
Keycloak is an open-source identity and access management (IAM) solution developed by Red Hat. This article covers how to install and configure Keycloak server in Azure.
To accomplish this, let's separate it into the following steps:
- Create a database
- Create a virtual machine
- Install and configure Keycloak on the virtual machine
- Install and configure Nginx on the virtual machine
- Cloudflare configuration
To keep things organized, let's start by creating the resource group where all the created resources (such as virtual machine, database...) will be. To do this, we're going to use the az group create
command.
LOCATION=eastus
RESOURCE_GROUP=rg-keycloak
az group create \
--location $LOCATION \
--name $RESOURCE_GROUP
Creating a database for Keycloak
The Keycloak server has built-in support for different databases and for this article we have chosen PostgreSQL.
The creation of the database is done in two steps. First, let's create the database server. To do this, use the az postgres flexible-server create
command. This may take a few minutes to complete.
POSTGRES_SERVER_NAME=pgsql-keycloak
POSTGRES_TIER=Burstable
POSTGRES_SKU=Standard_B1ms
POSTGRES_ADMIN_USER=keycloak
POSTGRES_ADMIN_PASSWORD=keycloak
POSTGRES_STORAGE_SIZE=32
POSTGRES_VERSION=16
POSTGRES_PUBLIC_ACCESS_IP=0.0.0.0
az postgres flexible-server create \
--resource-group $RESOURCE_GROUP \
--name $POSTGRES_SERVER_NAME \
--tier $POSTGRES_TIER \
--sku-name $POSTGRES_SKU \
--admin-user $POSTGRES_ADMIN_USER \
--admin-password $POSTGRES_ADMIN_PASSWORD \
--storage-size $POSTGRES_STORAGE_SIZE \
--version $POSTGRES_VERSION \
--location $LOCATION \
--public-access $POSTGRES_PUBLIC_ACCESS_IP
Once the creation of the database server is finished, create the database. Use the az postgres flexible-server db create
command for this.
DATABASE_NAME=keycloak
az postgres flexible-server db create \
--resource-group $RESOURCE_GROUP \
--server-name $POSTGRES_SERVER_NAME \
--database-name $DATABASE_NAME
The database setup is complete.
Creating the virtual machine
Now, let's create a virtual machine where Keycloak will be installed. The az vm create
command is used for this.
VM_NAME=vm-keycloak
VM_IMAGE=Ubuntu2204
VM_SIZE=Standard_B1s
VM_ADMIN_USERNAME=keycloak
VM_ADMIN_PASSWORD=Keycloak@000
az vm create \
--resource-group $RESOURCE_GROUP \
--name $VM_NAME \
--image $VM_IMAGE \
--size $VM_SIZE \
--admin-username $VM_ADMIN_USERNAME \
--admin-password $VM_ADMIN_PASSWORD
After the virtual machine is created, use the az vm open-port
command to open the port 443. This will be required for external access over HTTPS.
az vm open-port \
--resource-group rg-keycloak \
--name vm-keycloak \
--port 443
Now, configure the DNS name of the virtual machine. This will be used to add a CNAME record in Cloudflare later. First, use the az vm list-ip-addresses
command to get the public ip name. Next, use the az network public-ip update
command to set the DNS name.
PUBLIC_IP_NAME=$(az vm list-ip-addresses \
--resource-group $RESOURCE_GROUP \
--name $VM_NAME \
--query "[].virtualMachine.network.publicIpAddresses[0].name" \
--output tsv)
PUBLIC_IP_DNS_NAME=vm-keycloak
az network public-ip update \
--resource-group $RESOURCE_GROUP \
--name $PUBLIC_IP_NAME \
--dns-name $PUBLIC_IP_DNS_NAME
The virtual machine setup is complete.
Keycloak installation
Now, connect to the virtual machine using the ssh
command and the password Keycloak@000 (previously defined).
VM_DNS_NAME=$(az network public-ip show \
--resource-group $RESOURCE_GROUP \
--name $PUBLIC_IP_NAME \
--query "dnsSettings.fqdn" \
--output tsv)
ssh $VM_ADMIN_USERNAME@$VM_DNS_NAME
Installing Java is a prerequisite for installing Keycloak. The currently recommended version is Java 17.
JAVA_VERSION=openjdk-17-jdk
sudo apt update
sudo apt install -y $JAVA_VERSION
Now, download and extract the Keycloak files. The latest version currently available is 23.0.2, but you can click here to see if there is a newer version.
KEYCLOAK_VERSION=23.0.2
wget https://github.com/keycloak/keycloak/releases/download/$KEYCLOAK_VERSION/keycloak-$KEYCLOAK_VERSION.tar.gz
tar -xvzf keycloak-$KEYCLOAK_VERSION.tar.gz
sudo mv keycloak-$KEYCLOAK_VERSION /opt/keycloak
Now, edit the Keycloak configuration file.
sudo nano /opt/keycloak/conf/keycloak.conf
- Configure the database connection
- Configure the proxy mode
- Configure the hostname
The configuration should look like the example below:
db=postgres
db-username=keycloak
db-password=keycloak
db-url=jdbc:postgresql://pgsql-keycloak.postgres.database.azure.com/keycloak
proxy=edge
hostname=keycloak.enjoycoding.dev
Save and exit the file.
Now, run the Keycloak build command. This command performs a set of optimizations for the startup and runtime behavior. You can click here for details.
sudo /opt/keycloak/bin/kc.sh build
After the build finishes, start Keycloak to create the admin user using environment variables.
export KEYCLOAK_ADMIN="admin"
export KEYCLOAK_ADMIN_PASSWORD="admin"
sudo -E /opt/keycloak/bin/kc.sh start
You can stop the service (Control + C) when a log like the one below appears.
INFO [org.keycloak.services] (main) KC-SERVICES0009: Added user 'admin' to realm 'master'
Now, configure Keycloak to run as a service. Create a new service file definition.
sudo nano /etc/systemd/system/keycloak.service
With the content below:
[Unit]
Description=The Keycloak Server
After=syslog.target network.target
Before=httpd.service
[Service]
Environment=LAUNCH_JBOSS_IN_BACKGROUND=1
EnvironmentFile=/opt/keycloak/conf/keycloak.conf
User=keycloak
Group=keycloak
LimitNOFILE=102642
PIDFile=/var/run/keycloak/keycloak.pid
ExecStart=/opt/keycloak/bin/kc.sh start --optimized
StandardOutput=null
[Install]
WantedBy=multi-user.target
Save and exit the file.
Reload systemd manager configuration and enable Keycloak service on system startup.
sudo systemctl daemon-reload
sudo systemctl enable keycloak
Start Keycloak system service.
sudo systemctl start keycloak
Once the service starts, you can check the status by running the command below:
sudo systemctl status keycloak
And the Keycloak configuration is complete.
Cloudflare configuration
Log in to your Cloudflare account and select the domain you want to use with Keycloak. Now, add a CNAME record.
For the CNAME target value, use the DNS name of the virtual machine. You can use the command below to get it.
az network public-ip show \
--resource-group $RESOURCE_GROUP \
--name $PUBLIC_IP_NAME \
--query "dnsSettings.fqdn"
This is how the CNAME record is configured with the DNS name that we used in the virtual machine in the previous steps:
name: keycloak
target: vm-keycloak.eastus.cloudapp.azure.com
Now, let's create an Origin Certificate to encrypt traffic between Cloudflare and the origin web server, aka, our virtual machine.
- In the left menu, expand the "SSL/TLS" option and click the "Origin Server" option
- Click on "Create Certificate"
- In the "Hostnames" input, remove the values, type the CNAME name from previous step, and pick the value from the suggestion. With the values used in this article, it looks like this: keycloak.enjoycoding.dev
- Click "Create"
Now, let's save the certificate and private key to the virtual machine.
First, create a new file and paste the Origin Certificate from Cloudflare.
sudo nano /etc/ssl/certs/cloudflare_origin.cert
Now, create a new file and paste the Private Key from Cloudflare.
sudo nano /etc/ssl/private/cloudflare_origin.key
And the Cloudflare configuration is complete.
Installing Nginx
And the last step (🙌) is to install and configure Nginx. Use the following command to install it.
sudo apt install -y nginx
Now, open the Nginx configuration file.
sudo nano /etc/nginx/sites-enabled/default
Here's what the Nginx configuration should look like:
upstream keycloak {
server localhost:8080;
}
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /etc/ssl/certs/cloudflare_origin.cert;
ssl_certificate_key /etc/ssl/private/cloudflare_origin.key;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
proxy_pass http://keycloak;
}
}
Save and exit the file.
Finally, restart the Nginx service.
sudo service nginx restart
And the Nginx configuration is complete.
Conclusion
And that's it.
Now, you should be able to access the Keycloak web interface using the configured hostname (keycloak.enjoycoding.dev, in my case).
If you have any questions, feel free to comment.
For more details, click on the link below to access the official documentation
Member discussion