4.2 KiB
terraform-rancher
Terraform configuration for managing Rancher (rancher.k8s.syd1.au.unkin.net)
authentication via the rancher2
provider. Mirrors the terraform-authentik pattern.
Managed Resources
- Keycloak(OIDC) auth config — Authentik OIDC login for Rancher.
- Global role bindings — Authentik group → Rancher global role.
- Users — Rancher-local users and their global roles.
- Global roles — custom Rancher global roles.
- Tokens — API tokens for the identity Terraform authenticates as.
- Settings — Rancher settings such as
server-url.
Configuration
Every kind is discovered from YAML by config/config.hcl: the file name is the
object's key/name and the file body holds its attributes. Adding a file is the
only step needed to manage a new object; an empty directory means an empty map.
config/keycloakoidc.yaml defines the auth provider. The OAuth client secret is
read from Vault (kv-v2) — the same secret Authentik sets on its rancher
provider — and is never committed.
access_mode: unrestricted lets any authenticated Authentik user log in; Rancher
roles are granted to users/groups separately. This avoids locking the admin out
when the provider is first enabled.
config/global_role_bindings/<group>.yaml
global_role_id: admin
config/users/<username>.yaml
name: Some Person # optional display name, defaults to the file name
enabled: true # optional, default true
must_change_password: false # optional, default false
password_vault: # required — rancher2_user requires a password
mount: kv
path: service/rancher/users/someperson
key: password # optional, default "password"
global_role_bindings: # optional
- user
The password is read from Vault at plan time, so seed the kv-v2 secret before adding the file, or the plan fails.
The file name (the username) and every entry in global_role_bindings must be
an RFC 1123 label — ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$, i.e. lowercase
alphanumerics and -, starting and ending alphanumeric. No ., _, @ or
uppercase. Rancher names each binding akuser-<username>-<role> and rejects
anything else, so non-compliant values fail the plan with an explicit error
instead of the apply. Names that are individually valid but collapse to the same
binding name (e.g. foo-bar + baz and foo + bar-baz) are rejected at plan
time too.
config/roles/<name>.yaml
description: Read-only across all clusters
new_user_default: false # optional, default false
inherited_cluster_roles: # optional
- view
rules: # optional
- api_groups: ["management.cattle.io"]
resources: ["clusters"]
verbs: ["get", "list", "watch"]
# non_resource_urls and resource_names are also supported
config/tokens/<name>.yaml
description: CI token # optional, defaults to the file name
ttl: 7776000 # optional, seconds
renew: true # optional
cluster_id: c-m-abcdefgh # optional, scopes the token to one cluster
Caveat:
rancher2_tokenhas no user selector —user_idis computed by the provider (14.1.1), not settable. Tokens declared here are minted for the identity the rancher2 provider authenticates as (the admin token Terraform runs with), not for users inconfig/users/. A token for another user has to be created by that user. Token values land in Terraform state.
config/settings/<name>.yaml
value: https://rancher.k8s.syd1.au.unkin.net
Rancher ships defaults for its settings, so an entry takes over an existing setting rather than creating a new one.
Usage
make plan # init + plan
make apply # init + plan + apply
make format # fmt tofu + terragrunt hcl
Authentication
The rancher2 provider needs a Rancher API token, minted on demand by the Vault
Rancher secrets engine at rancher/creds/ci. The token is ephemeral (1h lease)
and Vault revokes it in Rancher when the lease expires, so nothing needs
rotating.
Set VAULT_ROLEID for local AppRole auth, or VAULT_AUTH_METHOD=kubernetes
for CI (Woodpecker).