Generally, we have faced several issues around development environments with a diverse team. These include:
- Different underlying hardware causing duplication of effort
- Different underlying hardware having unique issues with software packages (particularly around M1 chips)
- Substantial bloatware around desktop environments causing several "bugs" isolated to individual developers
- Contributor individual hardware performance bottle necks
Several solutions exist to resolve one or more of these issues such as:
- Dev containers to replicate environments across developers
- VM software like Vagrant for creating repeatable VMs
- VSCode extensions committed along side source control
However, these have failed to meet our requirements. Bloatware and different underlying hardware issues persist with individuals having to solve software bugs unique to their hardware. Additionally, performance bottle necks can not be overcome by any software solution.
Due to this, we have frequently used Cloud Servers on AWS with custom built development environment AMIs to solve this issue.
This Terraform module aims to modularize our solution so that it may be reused by the OS community where a similar use case may arise.
- Spot instance requests with allow for cost effective instances.
- SSH and RDP access limited to specific IP address ranges.
- Automated backups of EBS volumes to allow for recovery
This guide details how to create AMI images. We are currently developing some AMIs which will be backlogged however, these are not yet ready.
One image exists which launches Ubuntu 22.04 with Chrome RDP with KDE Plasma 5. This can be used as a base to get up and running and to begin installing custom software.
This was achieved by the following commands:
sudo apt update
sudo apt upgrade
sudo apt install --assume-yes wget tasksel
wget https://dl.google.com/linux/direct/chrome-remote-desktop_current_amd64.deb
sudo apt-get install --assume-yes ./chrome-remote-desktop_current_amd64.deb
sudo apt install tasksel
sudo apt install kde-plasma-desktop
// note the below line does not work and is done manually using nano at the moment.
sudo bash -c ‘echo “exec /etc/X11/Xsession /usr/bin/startplasma-x11” > /etc/chrome-remote-desktop-session
rm chrome-remote-desktop_current_amd64.deb
sudo reboot
This configuration uses an AMI which was created by running the script.sh on an instance.
However, the AMI created uses an encrypted volume. So this can not be used for the module which uses a public AMI.
To set up Chrome RDP, go to the Chrome RDP Website and click on Set up via SSH
.
From here click Begin
, Next
and Authorise
.
Currently you must SSH into the instance to apply the command but we will provide a remote exec in a future release.
- Creates a new independent VPC with a public subnet to remove dependency on pre-existing VPCs.
- Spot instance security group only allows SSH, VNC and RDP inbound access from IP addresses specified by the user.
- A key pair is created using a public key provided by the user to allow authentication when accessing the instance using port 22(SSH).
- An elastic IP address is provisioned to preserve the public IP address of the instance between stops and starts. Note: The elastic IP address does not incur charges while the instance is running but will incur charges when stopped.
- A Data Lifecycle Manager lifecycle policy is created which backups the instance daily before midnight and snapshots are retained for 1 week. In the event of catastrophic failure or loss of data, these snapshots can be used to restore EC2 instances. Instances to be managed by this policy are identified by the following tag: {AutomatedEbsBackups = true}.
- Snapshots are taken by the Data Lifecycle Manager.
Ubuntu Blog on Ubuntu Desktop on GCP
Guide to install KDE Plasma 5
Guide to generate SSH keys
module "ubuntu_desktop" {
source = "../terraform_aws_ubuntu_desktop_vm"
user_ip_address = "XXX"
instance_ami = "XXX"
tags = {
Terraform = "true"
Environment = "dev"
}
}
Name | Version |
---|---|
aws | ~>4.38.0 |
Name | Version |
---|---|
aws | 4.38.0 |
Name | Source | Version |
---|---|---|
vpc | terraform-aws-modules/vpc/aws | ~>3.18.1 |
Name | Type |
---|---|
aws_dlm_lifecycle_policy.instance_backup | resource |
aws_eip.instance_ip | resource |
aws_eip_association.instance_eip_assoc | resource |
aws_iam_role.dlm_lifecycle_role | resource |
aws_iam_role_policy.dlm_lifecycle | resource |
aws_key_pair.instance_ssh_key | resource |
aws_security_group.instance_sg | resource |
aws_spot_instance_request.instance | resource |
aws_region.current | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
allowed_ingress_cidr_blocks | List of IP addresses allowed access to instance | list(string) |
n/a | yes |
associate_public_ip_address | Whether to associate a public IP address with an instance in a VPC | bool |
true |
no |
environment | String to affix to any resource names and add to tags | string |
"dev" |
no |
instance_ami | AMI to use for the instance | string |
n/a | yes |
instance_block_duration_minutes | The required duration for the Spot instances, in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, or 360). The duration period starts as soon as your Spot instance receives its instance ID. At the end of the duration period, Amazon EC2 marks the Spot instance for termination and provides a Spot instance termination notice, which gives the instance a two-minute warning before it terminates. Note that you can't specify an Availability Zone group or a launch group if you specify a duration. | number |
0 |
no |
instance_interruption_behavior | Indicates Spot instance behavior when it is interrupted | string |
"stop" |
no |
instance_monitoring | Whether detailed monitoring is enabled for EC2 instance | bool |
true |
no |
instance_spot_price | The maximum price to request on the spot market | string |
null |
no |
instance_type | Instance type to use for the instance. | string |
"t3.xlarge" |
no |
prefix | string to prefix to resource names to make them easier to identify within the console | string |
"" |
no |
public_key | The public key material | string |
n/a | yes |
public_subnet_cidr_block | The IPv4 CIDR block of the public subnet | string |
"10.0.0.0/28" |
no |
region | The region where the infrastructure will be deployed | string |
"us-east-1" |
no |
root_block_device_delete_on_termination | Whether the volume should be destroyed on instance termination | bool |
true |
no |
root_block_device_encryption | Whether to enable volume encryption | bool |
true |
no |
root_block_device_size | Size of the volume in gibibytes | number |
32 |
no |
root_block_device_throughput | Throughput to provision for a volume in mebibytes per second (MiB/s) | number |
125 |
no |
root_block_device_type | The type of volume | string |
"gp3" |
no |
tags | Tags to add to all created resources | map(any) |
{} |
no |
vpc_cidr_block | The IPv4 CIDR block of the VPC | string |
"10.0.0.0/26" |
no |
Name | Description |
---|---|
elastic_ip_id | The ID of the elastic IP |
instance_arn | The arn of the instance |
instance_id | The ID of the instance |
instance_private_ip | The private ip address of the instance |
instance_public_ip | The public ip address of the instance |
instance_sg_arn | The arn of the instance security group |
instance_sg_id | The ID of the instance security group |
instance_ssh_key_arn | The arn of the instance ssh key pair |
instance_ssh_key_id | The ID of the instance ssh key pair |
lifecycle_policy_arn | The arn of the lifecycle policy |
lifecycle_policy_id | The arn of the lifecycle policy |
public_subnet_arn | The public subnet arn |
public_subnet_cidr_block | The public subnet CIDR block |
public_subnet_id | The public subnet ID |
vpc_arn | The arn of the VPC |
vpc_id | The ID of the VPC |
Please use the issue tracker to report any bugs or file feature requests.
Name | Role |
---|---|
Muhammad Hasan | Lead Developer |
Faizan Raza | Developer |
Throughout the module, the naming convention used is as follows:
- For Terraform resource names, the names consist of lowercase characters and _ to represent spaces in the name.
- For AWS resource names, the names consist of lowercase characters and - to represent spaces in the name, with the prefix variable attached to the beginning of the name and the environment.
Terraform Docs used for generating documentation.