IaC Bazaar
UpCloudPlan-validated

UpCloud Server Stack

Servers on SDN private network with storage, router, and firewall rules.

terraformAlt & Specialty Clouds#upcloud

Compare Virtual Machines across clouds →

upcloud-server-stackterraform v1.7

Verification

Plan-validated

Passed: module logic verified on a mocked plan — inputs, validation rules, conditional creation and outputs resolve (no real provider, no cloud).

Conformance

  • Static validation (fmt · validate · tflint)
  • No applicable security policies for this provider
  • 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

upcloud-server-stack

N identical UpCloud cloud servers on a dedicated SDN private network (with router), encrypted boot + data storage, SSH-key-only login, and a deny-by-default per-server firewall. One module call gives you a private east-west plane your servers share, with public exposure strictly opt-in. Works with Terraform and OpenTofu (>= 1.6), UpCloud provider >= 5.0, < 6.0. EU/Nordic-sovereign infrastructure, MIT-licensed provider.

Status: static-validated, live-test pending. Validated with tofu validate + tflint + checkov against the UpCloudLtd/upcloud provider. Not yet applied against a live UpCloud account (no cloud sandbox yet), so it ships under live-test quarantine.

Design & secure defaults

  • Private by default. Every server gets an SDN private NIC; the public IPv4 interface is opt-in (public_interface = false). Private-only servers are reached through a bastion or load balancer.
  • Deny-by-default firewall. The per-server firewall (firewall = true) carries explicit allow rules first, then a catch-all drop for all remaining inbound IPv4 and IPv6. SSH (22/tcp) opens only to the CIDRs in ssh_source_ranges — empty means SSH is closed.
  • Encryption at rest on (encrypt_storage = true) for the boot disk and any data disks.
  • SSH-key-only login. ssh_keys is required; create_password = false, so no password logins are provisioned.
  • Source IP filtering on every interface (anti-spoofing).
  • Dedicated router + SDN network per stack, with the DHCP default route left off so private-only servers do not silently gain an unexpected egress path.
  • plan xor cpu+mem is enforced by a precondition; a custom-sized server requires both cpu and mem.

Usage

module "server_stack" {
  source = "./upcloud-server-stack"

  name         = "web"
  zone         = "de-fra1"
  server_count = 2
  plan         = "2xCPU-4GB"

  ssh_keys = ["ssh-ed25519 AAAA... user@host"]

  public_interface  = true
  ssh_source_ranges = ["203.0.113.0/24"] # bastion / office CIDR

  inbound_rules = [
    {
      protocol             = "tcp"
      port_start           = "443"
      port_end             = "443"
      source_address_start = "0.0.0.0"
      source_address_end   = "255.255.255.255"
      comment              = "HTTPS"
    },
  ]

  data_disk_size_gb = 50
  labels            = { environment = "prod" }
}

Inputs

NameTypeDefaultDescription
namestringBase name for all resources (required)
zonestringUpCloud zone slug, e.g. de-fra1 (required)
ssh_keyslist(string)SSH public keys for the login user (required, non-empty)
server_countnumber1Number of identical servers (1–20)
planstring1xCPU-2GBServer plan slug; set null to use cpu+mem
cpunumbernullvCPUs for a custom-sized server (when plan = null)
memnumbernullMemory in MB for a custom-sized server (when plan = null)
templatestringUbuntu Server 24.04 LTS (Noble Numbat)OS template UUID or public template name
os_disk_size_gbnumber25Boot disk size in GiB (10–4096)
encrypt_storagebooltrueEncrypt boot + data storage at rest
login_userstringdeployUsername created on first boot, granted the SSH keys
user_datastringnullCloud-init bootstrap (body or URL)
metadatabooltrueEnable the UpCloud metadata service
create_networkbooltrueCreate a dedicated SDN network + router
private_network_uuidstringnullExisting SDN network UUID (when create_network = false)
private_network_cidrstring10.10.0.0/24CIDR for the created SDN network
public_interfaceboolfalseAttach a public IPv4 interface to each server
ssh_source_rangeslist(string)[]CIDRs allowed to reach SSH; empty = SSH closed
inbound_ruleslist(object)[]Extra inbound allow rules on the public interface
data_disk_size_gbnumber0Data disk per server in GiB; 0 = disabled
simple_backupobjectnullManaged backup schedule {plan, time}
labelsmap(string){}Labels on servers, storage, and the network
tagslist(string)[]Access-control tags on the servers

Outputs

NameDescription
server_idsMap of server name => server UUID
server_titlesMap of server name => hostname
public_ipv4Map of server name => public IPv4 (empty when private-only)
private_ipv4Map of server name => SDN private IPv4
private_network_uuidUUID of the SDN network (created or passed in)
router_idRouter UUID (null when create_network = false)
data_disk_idsMap of server name => data-disk UUID
firewall_rule_set_idsMap of server name => firewall ruleset ID

Requirements

RequirementVersion
Terraform / OpenTofu>= 1.6
UpCloudLtd/upcloud>= 5.0, < 6.0

License

Commercial — LicenseRef-IaCBazaar-Commercial. See the IaC Bazaar terms.