├── my.cnf ├── dbpass.sql ├── README.md └── guacamole.yml /my.cnf: -------------------------------------------------------------------------------- 1 | [client] 2 | user = root 3 | password = {{ guacdb_root_pass.stdout }} 4 | -------------------------------------------------------------------------------- /dbpass.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE guacamole_db; 2 | CREATE USER 'guacamole_user'@'{{ guacnet_guacamole }}' IDENTIFIED BY '{{ guacdb_guacamole_pass.stdout }}'; 3 | GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'{{ guacnet_guacamole }}'; 4 | FLUSH PRIVILEGES; 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reference 2 | Creates an (all-in-one) guacamole server using docker (or podman) w/ mysql for auth. 3 | 4 | # Deployment 5 | ``` 6 | # local example (non-RHEL8) 7 | ansible-playbook guacamole.yml --extra-vars="target=localhost guacnet_cidr=192.168.5.0/24 guacnet_guacd=192.168.5.2 guacnet_guacdb=192.168.5.3 guacnet_guacamole=192.168.5.4" 8 | 9 | # local example (RHEL8) 10 | ansible-playbook guacamole.yml --extra-vars="target=localhost guacnet_guacd=10.88.0.2 guacnet_guacdb=10.88.0.3 guacnet_guacamole=10.88.0.4" 11 | ``` 12 | 13 | # Notes 14 | ``` 15 | - For non-rhel8, guacnet_cidr and the associated guacnet_ variables must not be in use, they're for docker services. 16 | - For rhel8, guacnet_ variables must be within 10.88.0.0/16, the default podman network. This is a podman limitation. 17 | - if needed, database credentials are available in /opt/guacamole on the docker host. 18 | - guacadmin:guacadmin are the default web admin credentials. 19 | - http://localhost:8080/guacamole is the default web endpoint. 20 | - tested with CentOS 7, Ubuntu 18.04, and RHEL 8 21 | ``` 22 | -------------------------------------------------------------------------------- /guacamole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: guacamole 3 | hosts: "{{ target }}" 4 | gather_facts: true 5 | become: true 6 | tasks: 7 | 8 | - name: Set container_command = docker for rhel7/debian 9 | set_fact: 10 | container_command: docker 11 | when: 12 | - (ansible_os_family == 'RedHat' and ansible_distribution_major_version == "7") or ansible_os_family == 'Debian' 13 | 14 | - name: Set container_command = podman for rhel8 15 | set_fact: 16 | container_command: podman 17 | when: 18 | - ansible_os_family == 'RedHat' and ansible_distribution_major_version == "8" 19 | 20 | - name: Docker/Podman Installation 21 | package: 22 | name: "{% if ansible_os_family == 'RedHat' %}{{ container_command }}{% elif ansible_os_family == 'Debian' %}docker.io{% endif %}" 23 | state: present 24 | 25 | - name: Docker Service 26 | systemd: 27 | name: docker 28 | state: started 29 | enabled: True 30 | when: 31 | - (ansible_os_family == 'RedHat' and ansible_distribution_major_version == "7") or ansible_os_family == 'Debian' 32 | 33 | - name: Guacamole data dir 34 | file: 35 | path: /opt/guacamole 36 | state: directory 37 | owner: root 38 | group: root 39 | mode: '0750' 40 | 41 | - name: Determine db passwords set (root) 42 | stat: 43 | path: /opt/guacamole/guacdb_root_file 44 | register: guacdb_root_file 45 | 46 | - name: Determine db passwords set (guacamole) 47 | stat: 48 | path: /opt/guacamole/guacdb_guacamole_file 49 | register: guacdb_guacamole_file 50 | 51 | - name: Create db passwords when not set (root) 52 | shell: | 53 | head /dev/urandom | tr -dc A-Za-z0-9 | head -c 20 > /opt/guacamole/guacdb_root_file 54 | when: guacdb_root_file.stat.exists|bool == False 55 | 56 | - name: Create db passwords when not set (guacamole) 57 | shell: | 58 | head /dev/urandom | tr -dc A-Za-z0-9 | head -c 20 > /opt/guacamole/guacdb_guacamole_file 59 | when: guacdb_guacamole_file.stat.exists|bool == False 60 | 61 | - name: Register db passwords 62 | shell: | 63 | cat /opt/guacamole/guacdb_root_file 64 | register: guacdb_root_pass 65 | 66 | - name: Register db pass (guacamole) 67 | shell: | 68 | cat /opt/guacamole/guacdb_guacamole_file 69 | register: guacdb_guacamole_pass 70 | 71 | - name: Docker Volume (db) 72 | shell: | 73 | {{ container_command }} volume create guacdb 74 | 75 | - name: Docker Network - docker 76 | shell: | 77 | {{ container_command }} network create --driver bridge --subnet={{ guacnet_cidr }} guacnet 78 | ignore_errors: True 79 | when: 80 | - container_command == 'docker' 81 | 82 | - name: Container Launch - docker 83 | shell: | 84 | {{ container_command }} run -d --name guacd --network guacnet --ip {{ guacnet_guacd }} -d guacamole/guacd 85 | {{ container_command }} run -d --name guacdb --network guacnet --ip {{ guacnet_guacdb }} --volume guacdb:/var/lib/mysql:Z -e MYSQL_ROOT_PASSWORD={{ guacdb_root_pass.stdout }} -d mysql/mysql-server 86 | {{ container_command }} run -d --name guacamole --network guacnet --ip {{ guacnet_guacamole }} --link guacd:guacd --link guacdb:mysql -e MYSQL_HOSTNAME={{ guacnet_guacdb }} -e MYSQL_PORT=3306 -e MYSQL_DATABASE=guacamole_db -e MYSQL_USER=guacamole_user -e MYSQL_PASSWORD={{ guacdb_guacamole_pass.stdout }} -e GUACD_HOSTNAME={{ guacnet_guacd }} -e GUACD_PORT=4822 -e GUACD_LOG_LEVEL=debug -d -p 8080:8080 guacamole/guacamole 87 | when: 88 | - container_command == 'docker' 89 | 90 | - name: Container Launch - podman 91 | shell: | 92 | {{ container_command }} run -d --name guacd --ip {{ guacnet_guacd }} guacamole/guacd 93 | {{ container_command }} run -d --name guacdb --ip {{ guacnet_guacdb }} --volume guacdb:/var/lib/mysql:Z -e MYSQL_ROOT_PASSWORD={{ guacdb_root_pass.stdout }} mysql/mysql-server 94 | {{ container_command }} run -d --name guacamole --ip {{ guacnet_guacamole }} -e MYSQL_HOSTNAME={{ guacnet_guacdb }} -e MYSQL_PORT=3306 -e MYSQL_DATABASE=guacamole_db -e MYSQL_USER=guacamole_user -e MYSQL_PASSWORD={{ guacdb_guacamole_pass.stdout }} -e GUACD_HOSTNAME={{ guacnet_guacd }} -e GUACD_PORT=4822 -e GUACD_LOG_LEVEL=debug -p 8080:8080 guacamole/guacamole 95 | when: 96 | - container_command == 'podman' 97 | 98 | - name: Determine if (One Time) was done 99 | stat: 100 | path: /opt/guacamole/one_time_done 101 | register: guacdb_one_time_done 102 | 103 | - name: Set my.cnf and dbpass.sql 104 | template: 105 | src: "{{ item }}" 106 | dest: "/opt/guacamole/{{ item }}" 107 | owner: root 108 | group: root 109 | mode: '0400' 110 | with_items: 111 | - my.cnf 112 | - dbpass.sql 113 | when: guacdb_one_time_done.stat.exists|bool == False 114 | 115 | - name: Wait for mysqld on 3306 116 | shell: | 117 | {{ container_command }} logs guacdb 2>&1 | grep --quiet 'port: 3306' 118 | register: wait_for_mysqld 119 | until: wait_for_mysqld.rc == 0 120 | retries: 15 121 | delay: 15 122 | when: guacdb_one_time_done.stat.exists|bool == False 123 | 124 | - name: Configure DB (One Time) 125 | shell: | 126 | # credentials 127 | {{ container_command }} cp /opt/guacamole/my.cnf guacdb:/root/.my.cnf 128 | {{ container_command }} cp /opt/guacamole/dbpass.sql guacdb:dbpass.sql 129 | {{ container_command }} exec -i guacdb /bin/bash -c "mysql < dbpass.sql" 130 | touch /opt/guacamole/one_time_done 131 | # schema 132 | {{ container_command }} exec -i guacamole /bin/bash -c 'cat /opt/guacamole/mysql/schema/*.sql' > /opt/guacamole/dbschema.sql 133 | {{ container_command }} cp /opt/guacamole/dbschema.sql guacdb:dbschema.sql 134 | {{ container_command }} exec -i guacdb /bin/bash -c "mysql guacamole_db < dbschema.sql" 135 | when: guacdb_one_time_done.stat.exists|bool == False 136 | --------------------------------------------------------------------------------