Automated DigitalOcean Workspace Setup


Every now and then I would like a desktop that is in the cloud for development. This can help for many reasons but one in particular that worked for me was development while not having good internet. More often then not I don’t have internet when at my in-law’s house and it bombs their internet when I need to download a Docker image or ova file. This setup will allow full internet while not hindering your local network.


In this post I use Ubuntu but you can change the terraform as you’d like to use any DigitalOcean image. This post describes how to automatically deploy a desktop environment on DigitalOcean. I wrote the code to do this here. After you clone the code, you need both terraform and ansible to run the makefile. You will be charged for what you use on DigitalOcean. I am not responsible for any charges you incurr. This project is more costly than my normal projects due to compute and droplet type. Please be careful and delete instances after use.

Customize Secrets

There are a few secrets in the defaults.yml that need to be updated. In the repo open the file ansible/playbooks/roles/desktop/defaults/main.yml. The variable user_pass. Make sure to update them to the values you need. If you need to use vault to encrypt the secrets try the following:

echo -n "yourvaluehere" | ansible-vault encrypt_string

Deploy Desktop

In the root of the code repo, run a make command to build/deploy the application.

[email protected]:~/git/digital-ocean-desktop$ make build
cd terraform && terraform init && terraform apply

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of digitalocean/digitalocean from the dependency lock file
- Using previously-installed digitalocean/digitalocean v2.21.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # digitalocean_droplet.martin_desktop01 will be created
  + resource "digitalocean_droplet" "martin_desktop01" {
      + backups              = false
      + created_at           = (known after apply)
      + disk                 = (known after apply)
      + graceful_shutdown    = false
      + id                   = (known after apply)
      + image                = "ubuntu-22-04-x64"
      + ipv4_address         = (known after apply)
      + ipv4_address_private = (known after apply)
      + ipv6                 = false
      + ipv6_address         = (known after apply)
      + locked               = (known after apply)
      + memory               = (known after apply)
      + monitoring           = false
      + name                 = "martin-desktop01"
      + price_hourly         = (known after apply)
      + price_monthly        = (known after apply)
      + private_networking   = (known after apply)
      + region               = "nyc3"
      + resize_disk          = true
      + size                 = "g-2vcpu-8gb"
      + ssh_keys             = [
          + "32690924",
          + "32843241",
      + status               = (known after apply)
      + urn                  = (known after apply)
      + vcpus                = (known after apply)
      + volume_ids           = (known after apply)
      + vpc_uuid             = (known after apply)

Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + dev_instance_ip_addr = (known after apply)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

digitalocean_droplet.martin_desktop01: Creating...
digitalocean_droplet.martin_desktop01: Still creating... [10s elapsed]
digitalocean_droplet.martin_desktop01: Still creating... [20s elapsed]
digitalocean_droplet.martin_desktop01: Still creating... [30s elapsed]
digitalocean_droplet.martin_desktop01: Creation complete after 31s [id=316540125]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.


dev_instance_ip_addr = ""
sleep 30
cd ansible && ansible-playbook -i ansible_hosts_automated playbooks/desktop.yml --ask-vault-password
Vault password: 

PLAY [desktop] *****************************************************************

TASK [Gathering Facts] *********************************************************
The authenticity of host ' (' can't be established.
ED25519 key fingerprint is SHA256:bmrIsniou9JsxZOc09W1AERwvVwT+vSCiroaoT4Ch0g.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
ok: []

TASK [desktop : install necessary packages for a desktop] **********************
changed: []

TASK [desktop : start/enable xrdp] *********************************************
changed: []

TASK [desktop : create user] ***************************************************
changed: []

TASK [desktop : template polkit for graphics] **********************************
changed: []

TASK [desktop : install packages used for dev] *********************************
changed: []

TASK [desktop : reboot server for changes] *************************************
changed: []

PLAY RECAP *********************************************************************             : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Now you can rdp into your new instance. Use the ip address from the ansible output.
The graphics can be a little slow, but this is mainly for development so it’s bearable.


In this post we created a desktop for you to have a workspace in the cloud for development. Remember to destroy it once you are finished to stop being charged.