Running Ubuntu Desktop 20.04 on Amazon EC2 using S3 for storing your files

This tutorial will guide you to deploy Ubuntu Desktop 20.04 on an Amazon EC2 instance, with the following extras:

  • Deploying the instance in a completely automated way
  • Using an S3 bucket for saving your documents, so you can destroy and re-create the EC2 instance “on demand”.

The tutorial assumes little AWS knowledge to let everyone try and play easily. If you are well versed on AWS, just read the titles and go for step 4 directly.

Since the aim is to create an instance that automatically installs, configure and launch a remote desktop while mounting an S3 bucket as a user folder, there are several steps needed before launching the instance for the first time. These are the steps 1 to 3, which, therefore, are needed only once.

After having all set up, you can launch new instances going straight to step 4


  • Basic understanding of key AWS concepts: IAM Roles, Security Groups, S3 Buckets, VPCs and EC2
  • Being able to create an EC2 instance on a subnet with public access (IGW + Route)

What you’ll learn:

  • Install and configure Ubuntu Desktop environment on an Amazon EC2 through user data.
  • Mount an S3 bucket as a user folder
  • Configuring roles for “password-less” access from EC2 to S3


Step 1. Create the bucket

Duration: 3:00

Go to AWS console, search for S3 service and hit Create bucket button.
You should see the following screen:

Enter a name for your bucket, pick an AWS Region (choose the nearest to you, as you will run the instance in the same region for getting better latency).

Leaving all the defaults will work fine. Just be sure that you are not opening the bucket to the world.

Since you will be accessing through an IAM Role, you don’t need to configure any special permission.

Step 2. Create the role in IAM (EC2 with access to S3)

Duration: 3:00

We want our EC2 instance to be able to access an S3 bucket, without having to configure and store credentials somewhere. IAM Roles are here to help, since they will manage all that transparently to us. Any instance launched with this IAM Role attached, will inherit the same access to your S3 bucket.

To create a role, go to your AWS console, and search for IAM (or under Security, Identity, & Compliance menu), click on Roles and hit Create role& button.

You should see the following screen:

Since we want to grant EC2 access to S3, click on EC2 in the Common use cases shown in the screen.

The second screen will allow you to attach a policy. Here we are configuring the actual permission. The first screen was who is getting access, while this screen is to what.

Search for S3 policies.

Attach the AmazonS3FullAccess.

:warning: While is not advised to give an instance access to all your S3 buckets, this is shown for simplicity of this tutorial. The right way should be to create a policy granting access specifically only to the bucket that you are going to use for this purpose.

Step 3. Create a security group with SSH access from internet

Duration: 3:00

One last step until launch.

The security group will allow you to configure access to your machine. For this tutorial, we will only open access from outside to your instance through SSH port. Similarly to the IAM Role, any EC2 instance launched with this security group attached, will inherit automatically the same security configuration.

Again, having permissions too broad is not advised. You should seek other measures to restrict access. Some examples are: narrowing the allowed IP range, changing SSH port, among others that are outside the scope of this tutorial.

To create Security Groups, you can either open EC2 and scroll down to Security Groups on the left menu or under Networking & Content Delivery > VPC. Once on the Security Group screen, hit Create security group. You should get the following screen:

Enter a name, a description and the VPC where it is going to be deployed (we are using the default VPC, which has a public subnet already configured)

Hit the Inbound rules button to add a new rule. You need to enter the port (or service), which is SSH for our case, and the source of the connection: means “anywhere from internet”

Save it and that’s it. You have everything needed from cloud side to launch any EC2 instance.

Step 4. Launching the instance

Duration: 10:00

Open the EC2 page and select Launch instances button. Search for Ubuntu Server 20.04 LTS. Since the minimum requirements for Ubuntu Desktop is 4GB of RAM, choose an instance size accordingly (I used T2.medium for this exercise).

After selecting the instance type, you will get into the instance configuration screen. This is where the magic happens.

First, make sure you are deploying into the right VPC and subnet. The default VPC should be good enough as it has public subnets (i.e. you can reach the instances inside from the internet).

Second, enter the role created during step 2 as the image below:

At the bottom of the page, under Advanced details, you will find a text box for adding “user data”. This is where you put the script that will be executed on boot, so it should install everything you need.

Note: Please read it carefully to understand the steps needed for configuring and enabling VNC server. You only need to:

  • Change the password to your needs (up to 8 chars)
  • Change the bucket name according to step 1

:warning: Note that the script will be saved inside the instance with no encryption, therefore, the password will be visible there for everyone who has access to the instance.

The script will handle the installation of the software, configuration of the desktop and configuration of the VNC server.

Copy and paste the following under user data

apt update
apt upgrade -y
apt install -y ubuntu-desktop
apt install -y gnome-panel gnome-settings-daemon gnome-terminal
apt install -y tightvncserver
apt install -y s3fs

# Password setting
su ubuntu -c 'mkdir /home/ubuntu/.vnc'
su ubuntu -c 'vncpasswd -f <<<"MY_PASS" >"/home/ubuntu/.vnc/passwd"'
chmod 600 /home/ubuntu/.vnc/passwd

# VNC Desktop settings
echo "#!/bin/sh
xsetroot -solid grey
export XDG_CURRENT_DESKTOP=\"GNOME-Flashback:Unity\"
export XDG_MENU_PREFIX=\"gnome-flashback-\"
gnome-session --session=gnome-flashback-metacity --disable-acceleration-check &
" >  /home/ubuntu/.vnc/xstartup
chmod +x /home/ubuntu/.vnc/xstartup
chown ubuntu:ubuntu /home/ubuntu/.vnc/xstartup

# Starting vncserver
su ubuntu -c 'vncserver :1'

# Mounting the bucket
su ubuntu -c 'mkdir /home/ubuntu/Documents'
su ubuntu -c 's3fs YOUR_BUCKET: /home/ubuntu/Documents/ -o iam_role="auto"'

Finally, don’t launch the instance yet. You need to go to the last configuration step regarding the Security group. By default the launch wizard will suggest to create an ad-hoc security group. Select the second option for choosing your security group (created during Step 3)

And that’s it! Wait for a few minutes (between 5 to 10) to get your instance running. Copy the public IP and go for the last step.

Step 5. Create the tunnel

Duration: 2:00

Direct connections to VNC without encryption are not recommended. A better way to do so is creating an SSH tunnel and connecting through it. Run the following command in your terminal (the client).

Please note to use the right filename for your KeyPair file and the instance’s public IP.

ssh -L 5901:localhost:5901 -i yourKeyPair.pem ubuntu@INSTANCE_IP

Step 6. Enjoy

Duration: 1:00

Open your VNC Client of preference, connect to localhost on port 5901

Note: Some VNC clients for linux, such as Remmina, can create the tunnel, saving one step.

Note 2: For connecting from windows, you need to create the tunnel using PuTTY. Just a Google search for putty for ssh tunnel will give you enough results to get it done.

Note 3: Remember to shut down or destroy the instance to avoid charges while the instance is not being used! You can go directly to step 4 now that you have all the configuration done.

PRO TIP: Launching it from AWS CLI. This will give you a faster mechanism to get your virtual desktop up and running.

aws ec2 run-instances --image-id ami-019212a8baeffb0fa --count 1 \
--instance-type t2.medium --key-name yourKeyPair.pem \
--security-group-ids YOUR_SECURITY_GROUP \
--subnet-id PUBLIC_SUBNET_ID  --user-data file://USER_DATA_FILE.txt  \
--iam-instance-profile Name=NAME_OF_YOUR_S3_ACCESS_ROLE

And that’s it! I hope you have enjoyed this tutorial.

Next steps

  • Automation of this entire tutorial by using Cloud formation templates.

Additional documentation