Centralized credentials with OpenStackClusterIdentity
This guide explains how to centralize OpenStack credentials using a cluster-scoped OpenStackClusterIdentity and reference it from clusters and machines.
Overview
- OpenStackClusterIdentity (cluster-scoped): stores a reference to a Secret that contains 
clouds.yaml(and optionalcacert), and optionally restricts which namespaces may use it vianamespaceSelector. - OpenStackIdentityReference (on OpenStackCluster/OpenStackMachine/OpenStackServer): carries 
type,name, andcloudName.type: Secret(default):nameis the Secret name in the same namespace.type: ClusterIdentity:nameis the OpenStackClusterIdentity name; Secret location is taken from the identity.- For both types, 
cloudNameis required and selects the entry inclouds.yaml. 
 
Prerequisites
- A Secret containing OpenStack credentials in 
clouds.yaml: 
apiVersion: v1
kind: Secret
metadata:
  name: openstack-credentials
  namespace: capo-system
stringData:
  clouds.yaml: |
    clouds:
      openstack:
        auth:
          auth_url: https://keystone.example.com/
          application_credential_id: <id>
          application_credential_secret: <secret>
        region_name: RegionOne
        interface: public
        identity_api_version: 3
        auth_type: v3applicationcredential
  # Optional CA certificate
  # cacert: |
  #   -----BEGIN CERTIFICATE-----
  #   ...
  #   -----END CERTIFICATE-----
Create an OpenStackClusterIdentity
- Optionally restrict which namespaces can use it with 
namespaceSelector. 
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: OpenStackClusterIdentity
metadata:
  name: production-openstack
spec:
  secretRef:
    name: openstack-credentials
    namespace: capo-system
  namespaceSelector:
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: In
      values: [team-a, team-b]
Reference the identity from OpenStackCluster
- Use 
type: ClusterIdentity, specify the identityname, and thecloudNameto select the clouds.yaml entry. 
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: OpenStackCluster
metadata:
  name: cluster-a
  namespace: team-a
spec:
  identityRef:
    type: ClusterIdentity
    name: production-openstack
    cloudName: openstack
Using a Secret directly (default)
- If you don’t need cross-namespace identities, use a Secret in the same namespace.
 
spec:
  identityRef:
    # type defaults to Secret
    name: my-secret
    cloudName: openstack
Access control behavior
- If 
namespaceSelectoris not set: all namespaces may use the identity. - If set: only namespaces matching the selector may use the identity.
 - If access is denied, the controller returns an error and reconciliation fails. A Warning event can be emitted by the controller with a reason such as 
IdentityAccessDenied. 
RBAC requirements
Ensure the controller has permissions to read: (included in role.yaml by default)
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get"]
- apiGroups: ["infrastructure.cluster.x-k8s.io"]
  resources: ["openstackclusteridentities"]
  verbs: ["get","list","watch"]
Notes
cloudNameis required onidentityReffor bothtype: Secretandtype: ClusterIdentity.- The Secret must contain a 
clouds.yamlkey, and may optionally containcacert.