ZSoftly Cloud Platform
Back to blog

Open-Sourcing Our Apache CloudStack Terraform Modules

We packaged the Terraform we write for Apache CloudStack into reusable modules, scrubbed the internal specifics, and released them under MIT. Eight modules cover networking, compute, storage, Kubernetes, and more. Validate them with no credentials.

Ditah Kumbong (Founder & CTO)
3 min read

ZCP is built on Apache CloudStack. Provisioning it means the same Terraform every time: virtual private clouds and their tiers, access rules and firewalls, instances, volumes, clusters. We packaged this work into modules, removed the parts tied to our own zones, and released it. The zpcp repository is open source under MIT today, at v1.0.0.

module "networking" {
  source = "git::https://github.com/zsoftly/zpcp.git//modules/networking?ref=v1.0.0"

  name         = "demo-vpc"
  cidr         = "10.0.0.0/16"
  zone         = "your-zone-name"
  vpc_offering = "your-vpc-offering"
  project      = "demo"

  networks = {
    app = { gateway = "10.0.1.1", netmask = "255.255.255.0" }
  }
}

The modules wrap the community cloudstack/cloudstack provider and run on Terraform 1.5 or later, so OpenTofu works too.

The provider is not the whole job

The Apache CloudStack provider hands you resources one for one with the platform. You still wire them together yourself. A single network with tiers, access rules, a gateway, and a load balancer is dozens of resources holding fragile references to each other’s identifiers.

The networking module takes a name, an address range, and a map of tiers. It returns the network identifiers you feed straight into compute and load balancing. The references live inside the module, tested once, instead of copied across every root you write.

Eight modules ready

Each module ships with its own versions.tf, variables.tf, main.tf, outputs.tf, and README.

  • networking: virtual private clouds, tiers, address ranges, access rules
  • compute: instances, SSH keys, affinity groups, data disks
  • storage: volumes and snapshot policies
  • accounts and projects: domains, accounts, users, roles, projects, quotas
  • load balancing and security: public addresses, firewalls, gateways, load balancing
  • kubernetes: CloudStack Kubernetes clusters and node sizing
  • private networking: site-to-site tunnels and connections
  • images and templates: template registration, versioning, and sharing

A ninth module, stacks, renders cloud-init userdata for preconfigured app stacks. It is in progress.

Validate with no credentials

You check every example without a CloudStack account. make validate runs terraform init -backend=false and terraform validate against each example root, so your build pipeline catches schema errors on every pull request.

make validate

Plans need a live API, since the provider resolves offering names and zone IDs at plan time. The demo-stack example commits its provider lock file, so local and pipeline dry runs pin the same version and checksums.

Generic on purpose

We stripped our zone names, offering names, and account identifiers out of the defaults. Variables fall back to placeholders like your-zone-name or to null. Secrets carry sensitive = true. Constrained inputs carry validation blocks. Complex object variables use optional() with sane defaults instead of forcing every field. You adopt a module without inheriting our environment.

Try it

Clone the repository, read the module READMEs, and reference a module by its git source with a version tag. Issues and contributions are welcome.

These modules target operators running Apache CloudStack directly. If you want the managed path on ZCP instead, the zsoftly/zcp provider gives you the same infrastructure as code against our platform, on both registries.