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.
-
Google Cloud
Proxy Network Load Balancer, firewall rules and service accounts; Shielded VMs and managed instance groups.
-
Azure
Standard load balancer, network security groups and a resource group; VMs and scale sets.
-
OCI
Network security groups, a network load balancer and a dynamic group; compute instances and instance pools.
-
OpenStack
Octavia load balancer, security groups and a server group; Nova servers. No machinepool role.
-
No-op
Real plans, state and outputs with nothing provisioned: try CAPTF or test a management cluster without a cloud.
-
Shared Behavior
What all five sets have in common: endpoint, traffic, identities, bootstrap data, health, tags and destroy.
| 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
Machineand 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
NotReadyand 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
TerraformClusterIdentitywhose Secret holds the cloud credentials the provider reads; each cloud page shows the keys. See Identities and Credentials.
Using the modules¶
- Read the cloud page for the prerequisites and the identity Secret.
- Create the identity Secret and the
TerraformClusterIdentity. - Generate a cluster from the repository’s
examples/cluster-kubeadm.yamlwithclusterctl generate yaml --from, filling in the network ids and the node image. - 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.