Skip to content

Latest commit

 

History

History
179 lines (131 loc) · 5.4 KB

File metadata and controls

179 lines (131 loc) · 5.4 KB

Overview

This repository provides tools to set up and manage temporary development boxes on AWS. The main purpose is to allow us to persist a development environment across different runs. So a developer can log into a DevBox "project", make changes, terminate the instance, and then the changes will be retained the next time the developer logs in.

DevBox Lifecycle

A DevBox follows a specific lifecycle that automatically preserves your development environment:

  1. Launch: The CLI launches an EC2 instance from either a base AMI (for new projects) or a previously saved project AMI (for existing projects)
  2. Development: You SSH into the instance and work on your code, install packages, modify files, etc.
  3. Termination: When you're done, the instance is terminated (either manually through the AWS console or via CLI)
  4. Automatic Snapshot Process: Upon termination, a series of Lambda functions are triggered by CloudWatch events:
    • All EBS volumes attached to the instance are automatically snapshot
    • Snapshot metadata is tracked in DynamoDB tables
    • Once all snapshots complete, a new AMI is created from the snapshots
    • The old AMI and its associated snapshots are cleaned up
    • Detached volumes are automatically deleted
  5. Ready State: The project is marked as "READY" and available for the next launch
  6. Next Launch: When you launch the project again, it uses the newly created AMI containing all your previous work

This process ensures that your development environment persists across instance launches while minimizing storage costs by cleaning up intermediate resources.

flowchart LR
  %% Phases
  classDef devPhase fill:#BBDEFB,stroke:#1976D2,stroke-width:2px;
  classDef launchPhase fill:#C8E6C9,stroke:#388E3C,stroke-width:2px;
  classDef lambdaPhase fill:#FFECB3,stroke:#F57C00,stroke-width:2px;
  classDef readyPhase fill:#D1C4E9,stroke:#5E35B1,stroke-width:2px;
  classDef terminatePhase fill:#FDE2E4,stroke:#C62828,stroke-width:2px,color:#4A0F0F;

  %% Nodes
  A[🚀 Launch] --> B[💻 Hack Hack Hack]
  B --> C["💥 Terminate"]

  subgraph "Lambda Functions"
    D[💾 Snapshot] --> E[📦 Create AMI]
    E --> F[🧹 Cleanup]
    F --> G[✅ Mark Ready]
    D --> I["🗑️ Delete Volumes"]
  end

  C --> D
  G --> A


  %% Class assignments
  class A launchPhase;
  class B devPhase;
  class C terminatePhase;
  class D,E,F,G,I lambdaPhase;
  class H readyPhase;
Loading

Lambda Image Build Notes

The Lambda image is built with lambdas/Dockerfile, but the Docker build context must be the repository root (.). This is required because the image installs the package via pip install . and copies pyproject.toml and src/ from the root.

Manual equivalent:

docker build --platform linux/amd64 \
  -f lambdas/Dockerfile \
  -t snapshot-lambda \
  .

AWS Account Setup

This is a once-per-AWS-account process. Individual users will not need to do this.

Create main.tf with contents similar to the following:

provider "aws" {
  region = "us-east-1"
}

module "devbox" {
  source = "github.com/omsf-eco-infra/devbox"
  # options you can set; these are the defaults
  # prefix = "devbox"
  # vpc_cidr = "10.219.0.0/16"
  # ssh_cidr_blocks = ["0.0.0.0/0"]
}

Assuming you have OpenTofu (alternately, Terraform) installed and that you have AWS credentials, run:

Individual User Setup

Prerequisite: You must have an AWS account and the AWS CLI installed and configured.

Each user will have to complete these steps once, but this will be reused between different DevBox projects.

  1. Set up your SSH keys.
    • Generate a new SSH key pair if you don't have one. For example, use ssh-keygen.
    • Add the public key to your AWS account's EC2 key pairs. For example, you can do this with:
      aws ec2 import-key-pair \
       --region us-east-1 \
       --key-name devbox-key \
       --public-key-material fileb:///path/to/my/key.pub

If you already have a key pair, but don't know the name you gave it on AWS, you can get that from:

aws ec2 describe-key-pairs --query "KeyPairs[*].KeyName" --output text

Project Setup

This is for an individual DevBox project.

  1. Find the initial AMI

CLI Usage

Launch a project using the CLI:

devbox launch my-project \
  --instance-type t3.medium \
  --key-pair devbox-key \
  --base-ami ami-0123456789abcdef0

Optionally pass cloud-init user data (shell script or #cloud-config) with --userdata-file:

devbox launch my-project \
  --instance-type t3.medium \
  --key-pair devbox-key \
  --userdata-file ./userdata.sh

Troubleshooting

connect to host <ip> port 22: Connection refused

Sometimes you'll get this error if you try to SSH into a DevBox immediately after it starts running. This is because sometimes the networking is not fully set up yet. Wait a few seconds and try again.

ssh: Could not resolve hostname <project.example.com> nodename nor servname provided, or not known

This probably means that the DNS cache on your local machine has not updated yet with the new IP address for the DevBox (and should only happen if you are using DevBox with a DNS provider configured).

On macOS, you can flush the DNS cache with sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder. On Ubuntu-based systems you can use sudo resolvectl flush-caches.