What Is The TAP Namespace Provisioner
Namespace Provisioner provides a secure, automated way for platform operators to provision namespaces with the resources and namespace-level privileges required for their workloads to function as intended. It enables operators to add additional customized namespace-scoped resources using GitOps to meet their organization’s requirements and provides continuous reconciliation using the kapp-controller to maintain the actual desired state of the namespace-scoped resources.
Why Is This Needed
For anyone that dealt with TAP before TAP 1.4, they know the experience of "Preparing a developer namespace". As TAP is a fully kubernetes based solution, almost all configuration is done via kubernetes YAML manifests. TAP is such a powerful system, covering so many areas in the development lifecycle and the path to production, which is amazing however, this also means that lots of resources, credentials, templates, etc. must be created in a namespace in order to provide the developer with the needed permissions to deploy their applications.
The "wall of YAML" that was needed to prepare a namespace manually was not a great experience, and was often a true burden on the platform team, and caused for difficulties and delays in the onboarding of new applications to the platform.
What was available in TAP 1.4
In TAP 1.4, with the initial release of the namespace provisioner, the UX was greatly improved. One could simply create a namespace and add a label to it which is by default "apps.tanzu.vmware.com/tap-ns" with any value, and this would trigger the namespace provisioner to generate all the needed resources for the developer to be able to start deploying workloads.
Based on your TAP installation profile, the set of resources created was pre defined by the namespace provisioner, and it truly made the on-barding process much better.
With that being said, not everything you needed in all cases was covered OOTB. If you for example were using the testing and scanning supply chain, you still needed to create a Tekton Pipeline and a Scan Policy resource for every namespace. While these resources were not handled OOTB, there was an extension point.
The namespace provisioner allows configuring references to paths within git repositories that you want to use to template out additional resources per cluster.
These files you defined in Git, are in essence a YTT library, and can be completely templated with you needed business logic, and conditional fields, and they were templated alongside the default resources, with access to data values built up from the TAP Values file used at installation, and the namespace name being provisioned.
While this mechanism in it of itself was a huge improvement, and offers tremendous value, in TAP 1.5 this was greatly enhanced to make the story so much better!
Whats new in TAP 1.5
In TAP 1.5, many new changes and features have been made. They key additions in my mind are:
- Private Git Repo support with Git Authentication for additional sources
- Automated creation of Limit Ranges in Run profile clusters
- parameter prefixes
- default parameters
- overlay secrets
- End to End GitOps configuration option
Lets take a quick look at each of these features and what they bring to the picture.
Private Repo Support
This is a big feature that is important to many customers. While this is not a glamorous feature by any means, this is a requirement for many organizations, that do not allow public repos for system configurations such as namespace provisioner extensions, and supporting private repos is a very big step towards adoption of this component especially in regulated environments.
Both SSH Key and Username Password based authentication is supported, and to make it work, one simply needs to add a secret in the "tap-namespace-provisioning" namespace with the git credentials and then reference that secret in the namespace_provisioner section of the TAP values for any of the additional sources that require authentication.
OOTB Limit Range Creation
While a best practice in kubernetes is to always define limits and requests for our applications, not everyone always follows these practices. Limit Ranges are a mechanism in core kubernetes that allows us to define at a per namespace level, what default values to apply as requests and limits for any pod that does not define them.
This is basically a safety guard for the cases where developers do not follow the best practices and dont define the requests and limits for there applications.
With TAP 1.5, the namespace provisioner will automatically create a limit range resource in every TAP namespace, in run profile clusters.
While by default this is only enabled currently in run profile clusters, you can also configure the namespace provisioner to create limit ranges in build, iterate and full profile clusters, however one must be careful as test pods and build pods for example will also be effected by this limit range, which may cause tests or builds to fail if they reach an OOM for example.
Managing resource limits and requests correctly in kubernetes is not easy, but this mechanism helps us greatly ensure that we don’t have a workload that can destroy our cluster when it has a memory leak by simply taking up all of the resources of the cluster.
As mentioned, already in TAP 1.4, when we use additional sources stored in a git repo, we are defining a YTT template and we have access to a set of data values from the TAP values used at installation, as well as the namespace name.
While this is great, we many times may need additional information and values that are namespace specific and not just the namespace name.
Now in TAP 1.5, we can configure namespace provisioner to watch for a set of prefixes which when found in an annotation or label on a namespace that is managed by the namespace provisioner, anything after the prefix + its value is added as a data value which can be used for templating.
A good example of this being useful, is for example if i decide that the label prefix I want to watch for is tap.vrabbi.cloud, and I want to automatically create a tekton pipeline in every namespace based on the language of choice for developers working in that namespace. I can simply add a label to my namespace tap.vrabbi.cloud/language with the value being the language of choice, and in my git repo with the additional sources i can have a bunch of tekton pipelines that based on the values of that label will either be installed or not.
This offers huge potential for custom configurations, and is easily adaptable to whatever customizations you may need in your environment.
While label based, and per namespace parameters are amazing and have huge value, many times we also want to set default values for all namespaces to be used in our templating logic.
The default_parameters stanza in the namespace provisioner section of your TAP values allows you to define any default values you want made available as data values for all namespaces, which can be utilized during templating.
Through this mechanism one could override for example the default limit range values defined by TAP. one could also set defaults which can then be overridden by label values on a per namespace level, allowing for example to say that the default scanner we want to use is trivy (newly added as a scanner in 1.5!!!), but we allow the user to via a label select to use grype instead if they want, via an annotation like tap.vrabbi.cloud/scanner=grype.
This is another great feature, especially for simple use cases, where the additional sources, and setting up a git repo may be overkill. This mechanism allows us to define YTT overlays in a secret that will be used in the templating phase for the resources of every namespace, and reference that secret in our namespace provisioner config.
While typically using a Git repo is the path i would recommend, having the option to have things within the cluster can be extremely beneficial in 2 main cases:
- A git repo is overkill, as only 1 or 2 tiny things need changing
- your overlay contains sensitive values you cant have stored in a git repository
End to End GitOps configuration option
Another great advancement made in this release is the end to end support for a GitOps flow for namespace configuration.
In this flow, we disable the namespace provisioner controller, and manage all namespace configuration, in a declarative manner within a Git repository.
This flow, enables both the option to create the namespaces themselves via defining them in a file within a git repository, or to simply manage the resources within the pre-existing namespaces.
While this approach is a bit more involved, and is not as great for small POC environments, the GitOps model, is a very smart approach to strongly consider when dealing with a production setup.
The fact that TAP supports both models for the namespace provisioner is truly great, as it allows you to gain the benefits of t
As you can see, the namespace provisioner has been receiving a lot of love lately, and the new features truly enhance the usability and versatility of this component of the platform, allowing us to customize our environments in almost any way imaginable, making the management of namespaces, and there resources a very simple and easy task, greatly lowering the barrier and burden of the onboarding process to the platform.