Skip to content

Cloud Modules

The CAPTF project maintains reference modules for five clouds: AWS, Google Cloud, Azure, Oracle Cloud Infrastructure (OCI) and OpenStack. Each set lives in its own repository, implements the v1alpha1 module contract, and ships as module images you reference from a TerraformCluster, TerraformMachineTemplate or TerraformMachinePool. They are meant to be used as they are, and to be forked as the starting point for your own modules.

A sixth set, No-op, provisions nothing: it runs real plans and keeps real state with no cloud and no credentials, for trying CAPTF and testing a management cluster.

Status: pre-release

The five cloud sets pass static analysis, mocked unit tests on Terraform and OpenTofu, and image smoke tests, but none has yet been applied to a real cloud. Each repository’s DESIGN.md lists the facts the first real apply must confirm. Read it before you rely on a module, and pin a release tag.

The modules

  • AWS


    Network Load Balancer, security groups, IAM roles and an S3 bootstrap bucket; EC2 instances and Auto Scaling groups.

    AWS

  • Google Cloud


    Proxy Network Load Balancer, firewall rules and service accounts; Shielded VMs and managed instance groups.

    Google Cloud

  • Azure


    Standard load balancer, network security groups and a resource group; VMs and scale sets.

    Azure

  • OCI


    Network security groups, a network load balancer and a dynamic group; compute instances and instance pools.

    OCI

  • OpenStack


    Octavia load balancer, security groups and a server group; Nova servers. No machinepool role.

    OpenStack

  • No-op


    Real plans, state and outputs with nothing provisioned: try CAPTF or test a management cluster without a cloud.

    No-op

  • Shared Behavior


    What all five sets have in common: endpoint, traffic, identities, bootstrap data, health, tags and destroy.

    Shared Behavior

Cloud Repository Roles Provider
AWS captf-io/aws-modules cluster, machine, machinepool hashicorp/aws 6.67.0
Google Cloud captf-io/gcp-modules cluster, machine, machinepool hashicorp/google 8.5.0
Azure captf-io/azure-modules cluster, machine, machinepool hashicorp/azurerm 5.7.0
OCI captf-io/oci-modules cluster, machine, machinepool oracle/oci 9.8.0
OpenStack captf-io/openstack-modules cluster, machine terraform-provider-openstack/openstack 3.4.0
No-op captf-io/noop-modules cluster, machine, machinepool None: terraform_data is built in

OpenStack has no machinepool role: it has no native scaling group, and a MachineDeployment of individual machines covers the same need.

Each role is a separate image:

  • cluster creates what one workload cluster needs around its nodes: the security rules, the API server load balancer and, except on OpenStack, the node identities. It publishes the API endpoint, the failure domains and the ids the other roles need (its exports).
  • machine creates one instance for one Machine and registers control-plane instances with the API load balancer.
  • machinepool creates one native scaling group (an Auto Scaling group, a managed instance group, a scale set or an instance pool) for one MachinePool.

The no-op roles create none of this: each records its inputs in its state and returns placeholder outputs.

None of them creates a network. You bring the network, the subnets and the egress path, and the modules make nodes in them.

Images and tags

Every role is published as ghcr.io/captf-io/<cloud>-<role>, for example ghcr.io/captf-io/aws-machine, for linux/amd64 and linux/arm64, in two flavours: one on the Terraform base image and one on the OpenTofu base image. Each image carries a mirror of the providers its role needs, so a Job never downloads a provider at run time.

Tag Meaning
vX.Y.Z-opentofu, vX.Y.Z-terraform Release vX.Y.Z on that runtime; never moves
opentofu, terraform The newest release on that runtime
edge-opentofu, edge-terraform The newest build of main

Pin a release tag, or a digest, in anything you keep. The examples in each cloud repository pin v0.1.0-opentofu.

What you bring

The no-op set needs only the identity. Every cloud set needs all of these:

  • A network. The VPC, VNet, VCN or network, its subnets, and an egress path (NAT gateway, Cloud NAT, router) exist before the cluster. Each cloud page lists what the subnets need.
  • Node images. Images built for Cluster API, such as the image-builder images, with cloud-init and a kubelet that runs with --cloud-provider=external.
  • A cloud controller manager and a CNI in the workload cluster: the nodes stay NotReady and tainted until both run. The modules set up what the cloud controller manager needs (node identities, tags, provider IDs) but do not install it; on Azure they also write its configuration file on each node. On OpenStack you also supply its credentials.
  • An identity. A TerraformClusterIdentity whose Secret holds the cloud credentials the provider reads; each cloud page shows the keys. See Identities and Credentials.

Using the modules

  1. Read the cloud page for the prerequisites and the identity Secret.
  2. Create the identity Secret and the TerraformClusterIdentity.
  3. Generate a cluster from the repository’s examples/cluster-kubeadm.yaml with clusterctl generate yaml --from, filling in the network ids and the node image.
  4. Install the CNI and the cloud controller manager in the workload cluster once its API server answers.

The no-op set skips all of this: see its quick start.

Module settings beyond the contract inputs are ordinary module variables, set with spec.variables or spec.variablesFrom; see Module Variables. Each role page lists them.

Forking a module

Each repository is built to be forked. Its CONVENTIONS.md is the rule book the five repositories share; make verify checks most of it: the file layout, tags on every resource, terraform validate and tofu validate (including the oldest supported runtimes), the unit tests, tflint, tfcapi-lint, shellcheck and a trivy scan. To make a fork your own, change the registry and image names in the Makefile and the workflow, run make lock, then make verify.

The no-op modules are the smallest modules that meet the contract, and the starting point of Your First Module.

Shared Behavior describes what all five sets have in common.