Building Apache Guacamole with AWS Fargate and Aurora Serverless


f:id:cloudfish:20200417102427p:plain:w200
Gucamole is very useful tool as Windows Bastion host.I'd like to introduce to build Apache Guacamole with AWS Fargate.
I can build Gucamole with docker-compose, but I considered scale out If there are more increase RDP connections.So, I have choosen building with AWS Fargate because it's easy to scale out.
In the first place ,Can the Guacamole scale out ?I didn't find it at the official documentation.I found that somebody ask it in mailing list, the answer was yes because of using proper transactions. I believe this answer, I decided to build with AWS Fargate for scaling.
AWS Fargate is a serverless compute engine for containers without need to manage Fargate Hosts.
Unlike EKS, we don't need to pay for control plane. you only pay amount of using fargate container.We can focus building application.
And the reason of choosing Aurora Serverless is cheap of the cost, because it will stop if you don't access by constantly. Also it's scaled out if neccesarry. Currently, the number of users is low, don't need high performance. threfore, the first access is acceptable even if it is late.
So let's get started!

Prerequisite

Overview

The point of this configuration.

  • Host guacd and gucamole on Fargate
  • Host mysql on Aurora Serverless
  • Manage user info on SimpleAD

Note that the recording function is not used this time.

Diagram

f:id:cloudfish:20200425085325p:plain

1. SImpleAD

Create SimpleAD as follows

DirectoryType small
Domain any name

You can add users from the Workspaces service without launching Workspaces.

2.Aurora Serverless

2.1 Create Database instance

Create it with the following settings. Here are the main settings

Engine options Amazon Aurora
Edition Amazon Aurora with MySQL compatibility
Version latest
Database Location Regional
Database features Serverless
DB cluster identifie any name
Minimum Aurora capacity unitInfo 1
Maximum Aurora capacity unitInfo 1
Additional scaling configuration check 'Pause compute capacity after consecutive minutes of inactivity'
Web Service Data API check 'Data API'

When you're done creating,you memo RDS Endpoint.

2.2 Save the mysql password to Parameter Store

Setting parameter store for mysql password.
This is referenced from fargate container.

Name /guacamole/mysql_password
Tier Standard
Type SecureString
Value {YOUE_MYSQL_PASSWORD}
2.3 Initialize DB

Executing the following command for creating initialize SQL.

docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql

Open the Query Editor in AWS Console.
Paste and execute the contents of initdb.sql.
f:id:cloudfish:20200425113621p:plain

3. Application Load Balancer

3.1 Create Target Group

Create target group as follows

Target Type IP
Protocol HTTP
Port 8080

HealthCheck

Protocol HTTP
Path /guacamole
Stickiness Enable
Stickiness duration 3600
3.2 Create Application Load Balancer
Load Balancer Type Application Load Balancer
Scheme internet-facing

Listener

HTTPS 443 Created TG by 1.1
HTTP 8080 Created TG by 1.1

4. Create Fargate Cluster

4.1 Create Security Group

Create new SecurityGroup as follows for fargate task.

Protocol Port Source
TCP 8080 SecurityGroup of ALB

When it complete, you modify SecurityGroup of RDS.
Add the following setting.

Protocol Port Source
TCP 3306 SecurityGroup of Fargate task
4.2 Create Fargate Cluster.

Execute the following command for creating cluster.

ecs-cli configure \
--region ${YOUR_REGION_CODE} \
--cluster ${CLUSTER_NAME} \
--default-launch-type FARGATE \

ecs-cli up \
--cluster-config $CLUSTER_NAME \
--vpc ${VPI_ID} \
--subnets ${SUBNET_ID_1},${SUBNET_ID_2}
4.3 Run the Guacamole Service

ecs-params.yml
create ecs-params.yml file as follows.
Set the variables according to your environment.

version: 1
task_definition:
  task_role_arn: ${TASK_ROLE_ARN}
  task_execution_role: ${TASK_EXECUTION_ROLE}
  ecs_network_mode: awsvpc
  task_size:
    mem_limit: 0.5GB
    cpu_limit: 256
  services:
    guacamole:
      secrets:
        - value_from: /guacamole/mysql_password
          name: MYSQL_PASSWORD

run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
        - ${SUBNET_ID_1}
        - ${SUBNET_ID_2}
      security_groups:
        - ${SECURITY_GROUP_ID_FOR_TASK}

docker-compose.yml
create docker-compose.yml file as follows.
Also set the variables according to your environment.

version: "3"

services:
  guacd:
    image: guacamole/guacd:latest
    expose:
    - "4822"
    ports:
    - "4822:4822"
    logging:
      driver: awslogs
      options:
        awslogs-group: guacamole
        awslogs-region: ap-northeast-1
        awslogs-stream-prefix: guacd
    environment:
    - GUACD_LOG_LEVEL=debug
  guacamole:
    image: cloudfish/guacamole:latest
    ports:
    - "8080:8080"
    logging:
      driver: awslogs
      options:
        awslogs-group: guacamole
        awslogs-region: ap-northeast-1
        awslogs-stream-prefix: guacamole
    environment:
    - GUACD_HOSTNAME=localhost
    - LDAP_HOSTNAME=${SIMPLE_AD_IP}
    - LDAP_PORT=389
    - LDAP_ENCRYPTION_METHOD=none
    - LDAP_USER_BASE_DN=CN=Users,DC=guacamoleDC=local
    - LDAP_USERNAME_ATTRIBUTE=CN
    - LDAP_CONFIG_BASE_DN=CN=Users,DC=guacamole,DC=local
    - TOTP_ENABLED=false  # If you want to use MFA, set true
    - MYSQL_HOSTNAME=${RDS_ENDPOINT}
    - MYSQL_DATABASE=guacamole
    - MYSQL_USER=guacamole

Launching the Service
Execute the following command and start Gucamole service.

ecs-cli compose \
--file docker-compose.yml \
--ecs-params ecs-params.yml \
--project-name  guacamole-service \
service up \
--force-deployment \
--target-group-arn ${TARGET_GROUP_ARN} \
--container-name guacamole \
--container-port 8080

When If it's running properly, you can see the screen as follows on ECS Task screen. If it's not running, you check cloudwatch logs.
f:id:cloudfish:20200425143921p:plain

Login
Now, Let's get access to login screen.Access the following URL.If Aurora Serverless is stopped,It's going to take some time.
https://YOUR_DOMAIN/guacamole
You can see the this screen.
f:id:cloudfish:20200425213044p:plain:w300

You can logged in by the following ID/PASS.
USER:guacadmin
PASSWORD:guacadmin

f:id:cloudfish:20200425214230p:plain

Register target device you want to connect, you try to connect with RDP. But I won't go into how to connect it in detail.

In this configuration, the recording function is not available, because this architecture don't have storage.But Fargate can be available EFS in platform 1.4. therefore, I'm sure you can use the EFS to record.