IaC Bazaar
DigitalOceanStatic-verified

DigitalOcean Droplet Stack

Hardened droplet(s) with VPC, firewall, volume, reserved IP, and cloud-init bootstrap.

terraformAlt & Specialty Clouds#digitalocean

Compare Virtual Machines across clouds →

do-droplet-stackterraform v1.7

Verification

Static-verified

Passed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan clean (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-06-28 · how we verify

Documentation

do-droplet-stack

Hardened droplet(s) with VPC, firewall, volume, reserved IP, and cloud-init bootstrap. One module call gives you N identical droplets in a dedicated VPC behind a deny-by-default cloud firewall, with optional per-droplet block-storage data volumes and a reserved (static) IP that survives droplet rebuilds. Works with Terraform and OpenTofu (>= 1.6), DigitalOcean provider >= 2.0, < 3.0.

Secure defaults:

  • Deny-by-default cloud firewall — no inbound port is open (including SSH) until you allowlist sources
  • SSH-key-only access (ssh_key_ids is required; no password logins)
  • Dedicated VPC per stack (private traffic never shares the region default VPC)
  • Monitoring agent on by default; public IPv6 off by default

Usage

module "stack" {
  source = "./do-droplet-stack"

  name          = "web"
  region        = "fra1"
  droplet_count = 2
  ssh_key_ids   = ["12345678"]

  ssh_source_addresses = ["203.0.113.0/24"] # bastion / office CIDR

  inbound_rules = [
    { protocol = "tcp", port_range = "443", source_addresses = ["0.0.0.0/0", "::/0"] },
  ]

  volume_size_gb     = 50
  enable_reserved_ip = true
  tags               = ["env:prod"]
}

Inputs

NameTypeDefaultDescription
namestringBase name for all resources (required)
regionstringDigitalOcean region slug, e.g. fra1 (required)
ssh_key_idslist(string)SSH key IDs/fingerprints for root access (required, non-empty)
droplet_countnumber1Number of identical droplets (1–20)
sizestrings-1vcpu-2gbDroplet size slug
imagestringubuntu-24-04-x64Image slug or custom image ID
user_datastringnullCloud-init bootstrap (changing replaces droplets)
monitoringbooltrueInstall the DO monitoring agent
backupsboolfalseAutomated droplet backups (+20% cost)
ipv6boolfalsePublic IPv6 on droplets
droplet_agentbooltrueAgent for web-console access
create_vpcbooltrueCreate a dedicated VPC for the stack
vpc_uuidstringnullExisting VPC UUID (when create_vpc = false)
vpc_ip_rangestringnullCIDR for the created VPC (null = auto)
ssh_source_addresseslist(string)[]CIDRs allowed to reach SSH; empty = SSH closed
inbound_ruleslist(object)[]Extra inbound rules {protocol, port_range, source_addresses}
volume_size_gbnumber0Data volume per droplet in GiB; 0 = disabled
volume_filesystem_typestringext4ext4 or xfs
enable_reserved_ipboolfalseReserved (static) IP on the first droplet
tagslist(string)[]DO tags applied to all taggable resources

Outputs

droplet_ids, droplet_urns, droplet_public_ipv4, droplet_private_ipv4, droplet_ipv6, vpc_uuid, firewall_id, volume_ids, reserved_ip — all maps are keyed by droplet name.

Requirements

  • Terraform or OpenTofu >= 1.6
  • digitalocean/digitalocean provider >= 2.0, < 3.0

Verification

Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.

License

Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).