Deploy Apache Guacamole with Ansible and Docker

Kenneth KOFFI
4 min readMay 31, 2023

--

In a previous article, I demonstrated how to manually deploy Apache Guacamole using docker and docker-compose. I will show you in this blog post, how to automate the procedure using an Ansible role that I developed. I’m not going to cover what Guacamole is, or Ansible.
Let’s go straight to the point.

Requirements

This article supposes that:

  • You already have Ansible installed on your laptop or node controller.
  • Your target server is running Linux as Operating System. The distribution doesn’t matter. However, this role has been successfully tested on the following distributions.
  platforms:
- name: Ubuntu
versions:
- 22.10
- 22.04
- 20.04
- 18.04
- name: Rocky Linux
versions:
- 8.0
- 9.0
- name: fedora
versions:
- 38
- 37
- name: Debian
versions:
- 11
- 10

Deployment

Role installation

Install the Ansible role with one of the options below:

  • from Ansible galaxy
ansible-galaxy role install theko2fi.apache_guacamole
  • from GitHub
ansible-galaxy role install git+https://github.com/theko2fi/ansible-role-apache-guacamole.git

Inventory

Create an inventory file (inventory.yml) containing your remote server connection details. In the example below, the remote server IP address is 161.35.64.205 and the user is root. Guacamole will be deployed on that server.

all:
hosts:
guacvm:
ansible_host: 161.35.64.205
ansible_user: root
ansible_python_interpreter: "/usr/bin/python3"
ansible_ssh_private_key_file: "~/.ssh/id_rsa"

Playbook

Create a playbook file (playbook.yml)

This role offers numerous deployment scenarios because it supports many variables. However, I want to highlight and bring attention to two important approaches for deploying the application here.

  • Without custom domain name

This is the simplest way to deploy Guacamole. The example below will make the instance available at https://161-35-64-205.traefik.me/guacamole where 161.35.64.205 is the target server’s IP address. The URL will automatically be adapted according to your effective server’s IP address. A Let’s Encrypt signed certificate provided by traefik.me will be used.

- name: Install Apache Guacamole
hosts: all
become: true
roles:
- theko2fi.apache_guacamole
  • With a custom domain name

In most case, you would like to make your Guacamole instance reachable over your personal domain. The variable fqdn must be specified in that case. The example below will deploy a Guacamole instance at https://guacamole.company.local/guacamole where guacamole.company.local is your Fully Qualified Domain Name aka (FQDN)

- name: Install Apache Guacamole
hosts: all
become: true
vars:
- fqdn: guacamole.company.local
roles:
- theko2fi.apache_guacamole

Note: A list of all the variables supported by this role and their defaults values can be found at the end of this article.

Execution

Run the play with:

ansible-playbook -i inventory.yml playbook.yml

Your Apache Guacamole instance will now be available for use after you run the above playbook. Open the URL displayed at the end of the play execution in your browser.

Login to the Guacamole Web UI with the default credentials:

  • username: guacadmin
  • password: guacadmin

If you are wondering what happened in the background, check out my blog post about Apache Guacamole manual installation with docker-compose. Everything is explained in depth.

Troubleshooting

SSL warning

A self-signed SSL certificate will be generated automatically if you specify a custom domain name via the variable fqdn. As a result, receiving an error message similar to the one below is completely normal. Please disregard it.

HTTP 404 error

If you get an HTTP 404 error, please make sure to add /guacamole to the URL in your browser. Indeed, Guacamole is not accessible at the root / of your domain name, but rather at https://<your fqdn>/guacamole

Others

Bug reports, issues and pull requests are welcome on the project’s GitHub repository.

Role variables

Available variables for this role are listed below, along with default values :

default_user: "{{ ansible_user_id }}"
installation_path: "{{ ansible_env.HOME }}/docker-stack"
dockercompose_version: '3.9'
postgres_user: "guacamole_db_user"
postgres_password: "gcZYye@7U89JF%"
# define haproxy docker container version
haproxy_version: "2.4"

# define postgres docker container version
postgres_version: "15.0"

# define guacamole containers version
guacamole_backend_version: "1.5.0"
guacamole_frontend_version: "1.5.0"

Where:

- default_user is the user who will perform the installation
- installation_path is the target directory to put all the required files
- dockercompose_version is the docker-compose.yml file version
- postgres_user is the Postgres username
- postgres_password is the Postgres database password
- haproxy_version defines HAProxy docker image tag version
- postgres_version defines Postgres docker image tag version
- guacamole_backend_version defines guacamole/guacd docker image tag version
- guacamole_frontend_version defines guacamole/guacamole docker image tag version

Thank you for reading this article all the way to the end! I hope you found the information and insights shared here to be valuable and interesting.

If you have any questions, comments, or suggestions, please don’t hesitate to get in touch with me on the following platforms:

I appreciate your support and look forward to sharing more content with you in the future. Until next time!

--

--

Kenneth KOFFI

Administrateur systèmes avec une appétence pour le Cloud et le DevOps