»Vault as the Controller and Connect Inject Webhook Certificate Provider on Kubernetes
This topic describes how to configure the Consul Helm chart to use TLS certificates issued by Vault in the Consul controller and connect inject webhooks.
In a Consul Helm chart configuration that does not use Vault, webhook-cert-manager normally fulfills the role of ensuring that a valid certificate is updated to the mutatingwebhookconfiguration of either controller or connect inject to ensure that Kubernetes can communicate with each of these services.
When Vault is configured as the controller and connect inject Webhook Certificate Provider on Kubernetes:
controller and connect inject each get their webhook certificates from its own Vault PKI mount via the injected Vault Agent.
controller and connect inject each need to be configured with its own Vault Role that has necessary permissions to receive certificates from its respective PKI mount.
controller and connect inject each locally update its own mutatingwebhookconfiguration so that Kubernetes can relay events.
Vault manages certificate rotation and rotates certificates to each webhook.
To use Vault as the controller and connect inject Webhook Certificate Provider, we will need to modify the steps outlined in the Data Integration section:
»Bootstrapping the PKI Engine for Controller and Connect Inject Webhooks
The first step is to bootstrap the Vault cluster. Issue the following commands to enable and configure the PKI Secrets Engine to serve TLS certificates for the controller and connect inject webhooks:
You will need to preform the following steps for each datacenter that you would like to manage controller and connect inject webhook certificates in Vault. You will want to take care to create different names per datacenter for every pki mount, role, and policy.
»Create a Vault policy that authorizes the desired level of access to the secret
To use Vault to issue controller or connect inject webhook certificates, you will need to create the Vault policies that will allow either controller or connect inject to access its respective certificate-issuing URL.
»Create Vault Policies for the Controller and Connect Inject Webhook Certificates
Note: The PKI secret paths referenced by the Vault Policies below will be your global.secretsBackend.vault.controller.tlsCert.secretName and global.secretsBackend.vault.connectInject.tlsCert.secretName Helm values respectively.
The next step is to create a policy that allows ["create", "update"] access to the
certificate issuing URL so Consul controller and connect inject can fetch a new certificate/key pair and provide it to the Kubernetes mutatingwebhookconfiguration. Issue the following commands to create the policy:
Note: The PKI secret paths referenced by the Vault Policies below will be your global.secretsBackend.vault.controller.caCert.secretName and global.secretsBackend.vault.connectInject.caCert.secretName Helm values respectively.
Next, create a policy that allows ["read"] access to the CA URL. The policy is required so that Consul components can communicate with the Consul servers in order to fetch their auto-encryption certificates. Issue the following commands to create the policy:
To generate the <Allowed-domains-string> for each use the following script as a template:
#!/bin/sh#NAME is set to either the value from `global.name` from your Consul K8s value file, or your $HELM_RELEASE_NAME-consulexport NAME=consulk8s#NAMESPACE is where the Consul on Kubernetes is installedexport NAMESPACE=consul#DATACENTER is the value of `global.datacenter` from your Helm values config fileexport DATACENTER=dc1echo allowed_domains_controller=\"${NAME}-controller-webhook,${NAME}-controller-webhook.${NAMESPACE},${NAME}-controller-webhook.${NAMESPACE}.svc,${NAME}-controller-webhook.${NAMESPACE}.svc.cluster.local\""echo allowed_domains_connect_inject=\"${NAME}-connect-injector,${NAME}-connect-injector.${NAMESPACE},${NAME}-connect-injector.${NAMESPACE}.svc,${NAME}-connect-injector.${NAMESPACE}.svc.cluster.local\""
#!/bin/sh#NAME is set to either the value from `global.name` from your Consul K8s value file, or your $HELM_RELEASE_NAME-consulexport NAME=consulk8s#NAMESPACE is where the Consul on Kubernetes is installedexport NAMESPACE=consul#DATACENTER is the value of `global.datacenter` from your Helm values config fileexport DATACENTER=dc1echo allowed_domains_controller=\"${NAME}-controller-webhook,${NAME}-controller-webhook.${NAMESPACE},${NAME}-controller-webhook.${NAMESPACE}.svc,${NAME}-controller-webhook.${NAMESPACE}.svc.cluster.local\""echo allowed_domains_connect_inject=\"${NAME}-connect-injector,${NAME}-connect-injector.${NAMESPACE},${NAME}-connect-injector.${NAMESPACE}.svc,${NAME}-connect-injector.${NAMESPACE}.svc.cluster.local\""
»Create a Vault auth roles that link the policy to each Consul on Kubernetes service account that requires access
Note: The Vault auth roles below will be your global.secretsBackend.vault.controllerRole and global.secretsBackend.vault.connectInjectRole Helm values respectively.
Finally, Kubernetes auth roles need to be created for controller and connect inject webhooks.
The vaultCASecret is the Kubernetes secret that stores the CA Certificate that is used for Vault communication. To provide a CA, you first need to create a Kubernetes secret containing the CA. For example, you may create a secret with the Vault CA like so: