Development Environments

Architecture

Provision on-demand development environments for engineering teams:

  • Pre-configured AMIs with development tools installed
  • Spot instances for significant cost savings
  • User data scripts for personalized configuration
  • EBS snapshots for quick environment restoration
  • IAM roles with development-appropriate permissions
┌─────────────────────────────────────────────────────────────┐
│                    Developer Workstation                     │
└─────────────────────────────────────────────────────────────┘
                              │ SSH / VS Code Remote
┌─────────────────────────────────────────────────────────────┐
│                    Development VPC                           │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              Developer EC2 Instance                   │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐     │   │
│  │  │  Git    │ │ Docker  │ │ Node.js │ │ Python  │     │   │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘     │   │
│  │  ┌─────────────────────────────────────────────────┐ │   │
│  │  │           Mounted EBS Volume                     │ │   │
│  │  │           (Persistent Workspace)                 │ │   │
│  │  └─────────────────────────────────────────────────┘ │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

When to Use

EC2 development environments are ideal when:

  • Local machines lack resources for development workloads
  • Consistent environments are needed across the team
  • GPU access is required for ML/AI development
  • Testing AWS integrations requires realistic network access
  • Security policies require code to stay within AWS
  • Large datasets need to be processed near storage

Example Configuration

variable "developer_name" {
  type        = string
  description = "Name of the developer for resource naming"
}

module "dev_environment" {
  source  = "registry.patterneddesigns.ca/patterneddesigns/ec2-instance/aws"
  version = "1.5.0"

  instance_name      = "dev-${var.developer_name}"
  instance_type      = "t3.large"
  ami_id             = data.aws_ami.dev_tools.id
  subnet_id          = module.vpc.private_subnets[0]
  security_group_ids = [aws_security_group.dev.id]
  key_name           = aws_key_pair.developer[var.developer_name].key_name

  iam_instance_profile = aws_iam_instance_profile.developer.name

  # Use spot for cost savings (60-90% discount)
  spot_price = "0.05"
  spot_type  = "persistent"

  root_block_device = {
    volume_size = 100
    volume_type = "gp3"
    encrypted   = true
  }

  user_data = templatefile("${path.module}/scripts/dev-setup.sh", {
    developer_name = var.developer_name
    git_email      = "${var.developer_name}@example.com"
  })

  tags = {
    Environment = "development"
    Owner       = var.developer_name
    AutoStop    = "true"  # For scheduled shutdown
  }
}

# Lookup the latest dev tools AMI
data "aws_ami" "dev_tools" {
  most_recent = true
  owners      = ["self"]

  filter {
    name   = "name"
    values = ["dev-tools-*"]
  }
}

# Security group allowing SSH and VS Code Remote
resource "aws_security_group" "dev" {
  name        = "dev-environment-sg"
  description = "Security group for development environments"
  vpc_id      = module.vpc.vpc_id

  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.office_cidr]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Cost Optimization

# Scheduled start/stop using EventBridge
resource "aws_cloudwatch_event_rule" "stop_dev_instances" {
  name                = "stop-dev-instances"
  description         = "Stop dev instances at end of work day"
  schedule_expression = "cron(0 18 ? * MON-FRI *)"  # 6 PM weekdays
}

resource "aws_cloudwatch_event_target" "stop_dev_instances" {
  rule      = aws_cloudwatch_event_rule.stop_dev_instances.name
  target_id = "StopDevInstances"
  arn       = "arn:aws:ssm:${data.aws_region.current.name}::automation-document/AWS-StopEC2Instance"
  role_arn  = aws_iam_role.eventbridge.arn

  input = jsonencode({
    InstanceId = [module.dev_environment.instance_id]
  })
}

Considerations

AspectConsideration
CostUse spot instances, scheduled stop/start
AMI ManagementBuild and maintain golden AMIs with Packer
Data PersistenceUse separate EBS volumes for workspace data
AccessUse Systems Manager or bastion for SSH
MonitoringTrack usage for capacity planning

Alternatives

Consider these alternatives based on needs:

  • AWS Cloud9 - Browser-based IDE with EC2 backend
  • CodeSpaces/Gitpod - Cloud development environments
  • ECS Dev Environments - Container-based development
  • AWS Workspaces - Virtual desktop infrastructure