Installation
This page covers installing the CAPTF provider into a management cluster
with clusterctl: what to have ready first, how to register the provider,
what the install creates, how the runner image is set, the optional
components, and how to confirm the install worked. It is for whoever
administers the management cluster, not for cluster tenants.
Before you begin
- A management cluster with Cluster API’s core, bootstrap and
control-plane providers already initialized, and a
kubectlcontext pointing at it. clusterctl, matching the version documented for the Cluster API release you run.cert-manager, with thecert-manager.io/v1API available.clusterctl initinstalls a compatiblecert-managerrelease itself when one is not already present, so a separate install step is only needed to pin a specificcert-managerversion or to install it ahead of time.- Cluster API installed at a release that implements the same contract
CAPTF does. CAPTF’s own
metadata.yamllists one release series so far, contractv1beta2; CAPTF is built and tested against Cluster API v1.14.2.
Register the provider
CAPTF is not one of clusterctl’s built-in providers, so clusterctl needs
a config file naming its release manifest. The config entry’s name is
terraform:
# clusterctl.yaml
providers:
- name: terraform
type: InfrastructureProvider
url: https://github.com/captf-io/cluster-api-provider-terraform/releases/latest/infrastructure-components.yaml
url can also name a specific tag instead of latest, or a file:// path
into a local repository built from a release’s assets; see Installing from
a local repository
for the local repository layout and for pinning a version.
CAPTF has not published a release yet, so the URL above does not resolve to anything: install from a local repository until one exists.
Install with clusterctl init
clusterctl init --config clusterctl.yaml --infrastructure terraform
clusterctl init --infrastructure terraform:vX.Y.Z pins a specific
released version instead of the newest one clusterctl can see.
If you plan to use the ClusterClass flavor, enable the ClusterTopology
feature gate before running init — it is alpha in Cluster API and off by
default:
CLUSTER_TOPOLOGY=true clusterctl init --config clusterctl.yaml --infrastructure terraform
What gets installed
Everything below lands in one namespace, captf-system; clusterctl init
also installs cert-manager itself when it is missing, in its own
namespace.
- CRDs for the seven kinds:
TerraformCluster,TerraformClusterTemplate,TerraformMachine,TerraformMachineTemplate,TerraformMachinePool,TerraformMachinePoolTemplateandTerraformClusterIdentity(the last is cluster-scoped; the rest are namespaced). See The Kinds for what each one does, and API Reference for every field. - The manager, a single-replica
Deploymentnamedcaptf-controller-manager, running as a non-root user, with aServiceAccountof the same name. It serves its webhooks on:9443, its metrics on:8443, and its health and readiness probes on:9440. - The admission webhook: a
ValidatingWebhookConfigurationnamedcaptf-validating-webhook-configuration, one rule per kind, backed by thecaptf-webhook-serviceService. Its serving certificate is acert-managerCertificate(captf-serving-cert, issued by the self-signedIssuercaptf-selfsigned-issuer), mounted into the manager pod and kept current bycert-manager’s CA injection. - RBAC for the manager itself: the
ClusterRolecaptf-manager-roleand itsClusterRoleBinding, plus a leader-electionRoleandRoleBindingscoped tocaptf-system. The manager also creates a runnerServiceAccountandRoleBindingin each tenant namespace at first use, from the staticClusterRolecaptf-runner. See RBAC for what each role grants and for the per-namespace runner setup.
None of this installs a TerraformClusterIdentity or any Terraform*
object: those come from templates you apply afterward, covered in
Identities and Credentials and Templates
and ClusterClass.
The manager image and the runner image
clusterctl init sets the manager container’s image to the release’s
image, ghcr.io/captf-io/cluster-api-provider-terraform:vX.Y.Z. The same
reference is also set as the CAPTF_MANAGER_IMAGE environment variable on
that container: it is the default of --runner-image, the image the
manager runs as the init container that injects the runner binary into
every Job it creates. Point --runner-image at a different reference
(for example a registry mirror the tenant namespaces’ Jobs can reach, or a
build carrying a patched runner binary) when the manager’s own image is
not the one you want Jobs to pull; see --runner-image
for the flag and Job Environment for how the
init container uses it. spec.source.image on a Terraform* object is
unrelated: it names the role image the Job actually runs, never the
runner.
Optional components
config/prometheus and config/network-policy are kustomize components:
neither is part of infrastructure-components.yaml, so clusterctl init
never installs them and clusterctl upgrade never touches them, and
neither is a release asset — get them from a checkout of the tag you
installed (see Register the provider), not from
the release URL. A kustomize Component builds standalone: point a bare
kustomization at one with no resources: of your own, and it emits only
that component’s own objects, carrying the captf-/captf-system names
config/default produces:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
components:
- <path-to-checkout>/config/prometheus
- Prometheus (
config/prometheus): a metricsService, aServiceMonitor, the alerting rules, and the RBAC Prometheus needs to scrape the manager’s authenticated metrics endpoint. See Enabling the Prometheus component for what it adds and how to wire it up, and how a later upgrade affects it. - Network policy (
config/network-policy): aNetworkPolicythat restricts the manager pod to webhook, metrics and health-probe traffic inbound, and DNS, the API server and container registries outbound. It only has an effect on a CNI that enforcesNetworkPolicy, and it covers only the manager pod, not runner Jobs;config/network-policy/job-egress-sample.yamlis a separate starting point to copy into each tenant namespace for its Job pods. See Network exposure for why the manager’s and a Job’s exposure differ.
Building both at once needs both under components: in the same
kustomization. Building either on top of a from-source install of
config/default (rather than the one clusterctl init already installed)
also works, but is unnecessary for these two components: each one’s
objects stand alone and never depend on config/default’s own resources
being built alongside them.
Verifying the install
kubectl -n captf-system rollout status deployment/captf-controller-manager
kubectl get crds -l cluster.x-k8s.io/provider=infrastructure-terraform
kubectl get validatingwebhookconfigurations captf-validating-webhook-configuration
kubectl -n captf-system get certificate captf-serving-cert
The rollout command returns once the manager pod is ready. The CRD list
should show all seven kinds. The webhook configuration and the certificate
must both exist and the certificate must report Ready=True, cert-manager
was able to issue the webhook’s serving certificate: without it, webhook
calls from the API server fail closed (failurePolicy: Fail) and every
Terraform* create or update is rejected.
clusterctl init itself prints the components it installed; clusterctl describe cluster (once you have created one) reports whether CAPTF’s
objects are ready.
See also
- Upgrades for upgrading an existing install.
- Configuration for the manager flags you set on top of this default install.
- RBAC for the manager’s and runner’s permissions in full.
- Security Model for the trust boundary a
Terraform*object’s Job operates inside.