The Out of the Box Supply Chain, Delivery Basic, and Templates Supply Chain Choreographer packages give you Kubernetes objects that cover a reference path to production. Because VMware recognizes that you have your own needs, these objects are customizable, including individual templates for each resource, whole supply chains, or delivery objects.
Depending on how you installed Tanzu Application Platform, there are different ways to customize the Out of the Box Supply Chains. The following sections describe the ways supply chains and templates are authored within the context of profile-based Tanzu Application Platform installations.
To create a new supply chain and make it available for workloads, ensure that the supply chain does not conflict with those installed on the cluster, because those objects are cluster-scoped.
If this is your first time creating a supply chain, follow the tutorials from the Cartographer documentation.
Any supply chain installed in a Tanzu Application Platform cluster might encounter two possible cases of collisions:
object name:
Supply chains are cluster scoped, such as any Cartographer resource prefixed with Cluster
. So the name of the custom supply chain must be different from the ones provided by the Out of the Box packages.
Either create a supply chain whose name is different, or remove the installation of the corresponding ootb-supply-chain-*
from the Tanzu Application Platform.
workload selection:
A workload is reconciled against a particular supply chain based on a set of selection rules as defined by the supply chains. If the rules for the supply chain to match a workload are ambiguous, the workload does not make any progress.
Either create a supply chain whose selection rules are different from the ones the Out of the Box Supply Chain packages use, or remove the installation of the corresponding ootb-supply-chain-*
from Tanzu Application Platform.
See Selectors.
For Tanzu Application Platform v1.2, the following selection rules are in place for the supply chains of the corresponding packages:
ootb-supply-chain-basic
apps.tanzu.vmware.com/workload-type: web
workload.spec.image
text box setapps.tanzu.vmware.com/workload-type: web
apps.tanzu.vmware.com/workload-type: server
apps.tanzu.vmware.com/carvel-package-workflow: true
apps.tanzu.vmware.com/workload-type: server
apps.tanzu.vmware.com/carvel-package-workflow: true
ootb-supply-chain-testing
apps.tanzu.vmware.com/workload-type: web
workload.spec.image
text box setapps.tanzu.vmware.com/workload-type: web
apps.tanzu.vmware.com/has-test: true
ootb-supply-chain-testing-scanning
apps.tanzu.vmware.com/workload-type: web
workload.spec.image
text box setapps.tanzu.vmware.com/workload-type: web
apps.tanzu.vmware.com/has-test: true
For details about how to edit an existing supply chain, see the Modifying an Out of the Box Supply Chain section.
You can exclude a supply chain package from the installation to prevent the conflicts mentioned earlier, by using the excluded_packages
property in tap-values.yaml
. For example:
# add to exclued_packages ootb-* packages you DON'T want to install
# excluded_packages:
- ootb-supply-chain-basic.apps.tanzu.vmware.com
- ootb-supply-chain-testing.apps.tanzu.vmware.com
- ootb-supply-chain-testing-scanning.apps.tanzu.vmware.com
# comment out remove the supply_chain property
#
# supply_chain: ""
Similar to supply chains, Cartographer templates (Cluster*Template
resources) are cluster-scoped, so you must ensure that the new templates submitted to the cluster do not conflict with those installed by the ootb-templates
package.
The following set of objects are provided by ootb-templates
:
Before submitting your own, either ensure that the name and resource has no conflicts with those installed by ootb-templates
, or exclude from the installation the template you want to override by using the excluded_templates
property of ootb-templates
.
For example, perhaps you want to override the ClusterConfigTemplate
named config-template
to provide your own with the same name, so that you don’t need to edit the supply chain. In tap-values.yaml
, you can exclude template provided by Tanzu Application Platform:
ootb_templates:
excluded_templates:
- 'config-writer'
For details about how to edit an existing template, see the Modifying an Out of the Box Supply template section.
To change the shape of a supply chain or the template that it points to:
In this example, you have a new ClusterImageTemplate
object named foo
that you want use for building container images instead of the out of the box object that makes use of Kpack. The supply chain that you want to apply the modification to is source-to-url
provided by the ootb-supply-chain-basic
package.
Find the image that contains the supply chain definition:
kubectl get app ootb-supply-chain-basic \
-n tap-install \
-o jsonpath={.spec.fetch[0].imgpkgBundle.image}
For example:
tanzu.packages.broadcom.com/tanzu-application-platform/tap-packages@sha256:f2ad401bb3e850940...
Pull the contents of the bundle into a directory named ootb-supply-chain-basic
:
imgpkg pull \
-b tanzu.packages.broadcom.com/tanzu-application-platform/tap-packages@sha256:f2ad401bb3e850940... \
-o ootb-supply-chain-basic
For example:
Pulling bundle 'tanzu.packages.broadcom.com/tanzu-...
Extracting layer 'sha256:542f2bb8eb946fe9d2c8a...
Locating image lock file images...
The bundle repo (tanzu.packages.broadcom.com/tanzu...
Succeeded
Inspect the files obtained:
tree ./ootb-supply-chain-basic/
For example:
./ootb-supply-chain-basic/
├── config
│ ├── supply-chain-image.yaml
│ └── supply-chain.yaml
└── values.yaml
Edit the supply chain that you want to exchange the template with another:
--- a/supply-chain.yaml
+++ b/supply-chain.yaml
@@ -52,7 +52,7 @@ spec:
- name: image-builder
templateRef:
kind: ClusterImageTemplate
- name: kpack-template
+ name: foo
params:
- name: serviceAccount
value: #@ data.values.service_account
Submit the supply chain to Kubernetes:
The supply chain definition found in the bundle expects the values you provided by using tap-values.yaml
to be interpolated by using YTT before they are submitted to Kubernetes. So, before applying the modified supply chain to the cluster, use YTT to interpolate those values. After that, run:
ytt \
--ignore-unknown-comments \
--file ./ootb-supply-chain-basic/config \
--data-value registry.server=REGISTRY-SERVER \
--data-value registry.repository=REGISTRY-REPOSITORY |
kubectl apply -f-
ImportantThe modified supply chain does not outlive the destruction of the cluster. VMware recommends that you save it somewhere, such as in a Git repository, so that you can install it on every cluster where you expect the supply chain to exist.
The Out of the Box Templates package (ootb-templates
) includes all of the templates and shared Tekton tasks used by the supply chains shipped by using ootb-supply-chain-*
packages. Any template that you want to edit, for example, to change details about the resources that are created based on them, is part of this package.
The workflow for updating a template is as follows:
ootb-templates
.ootb-templates
. For more information, see excluded_templates
in the Providing your own templates section.NoteYou don’t need to change anything related to supply chains, because you’re preserving the name of the object referenced by the supply chain.
In this example, you want to update the ClusterImageTemplate
object called kpack-template
, which provides a template for creating kpack/Image
s to hardcode an environment variable.
Exclude the kpack-template
from the set of templates that ootb-templates
installs by updating tap-values.yaml
:
ootb_templates:
excluded_templates: ['kpack-template']
Find the image that contains the templates:
kubectl get app ootb-templates \
-n tap-install \
-o jsonpath={.spec.fetch[0].imgpkgBundle.image}
For example:
tanzu.packages.broadcom.com/tanzu-application-platform/tap-packages@sha256:a5e177f38d7287f2ca7ee2afd67ff178645d8f1b1e47af4f192a5ddd6404825e
Pull the contents of the bundle into a directory named ootb-templates
:
imgpkg pull \
-b tanzu.packages.broadcom.com/tanzu-application-platform/tap-packages@sha256:a5e177f38d7.. \
-o ootb-templates
For example:
Pulling bundle 'tanzu.packages.broadcom.com/tanzu-...
Extracting layer 'sha256:a5e177f38d7...
Locating image lock file images...
The bundle repo (tanzu.packages.broadcom.com/tanzu...
Succeeded
Confirm that you downloaded all the templates:
tree ./ootb-templates
Example output:
./ootb-templates
├── config
│ ├── cluster-roles.yaml
│ ├── config-template.yaml
│ ├── kpack-template.yaml # ! the one we want to modify
...
│ └── testing-pipeline.yaml
└── values.yaml
Change the property you want to change:
--- a/config/kpack-template.yaml
+++ b/config/kpack-template.yaml
@@ -65,6 +65,8 @@ spec:
subPath: #@ data.values.workload.spec.source.subPath
build:
env:
+ - name: FOO
+ value: BAR
- name: BP_OCI_SOURCE
value: #@ data.values.source.revision
#@ if/end param("live-update"):
Submit the template.
The name of the template is preserved but the contents are changed. So after the template is submitted, the supply chains are all embedded to the build of the application container images that have FOO
environment variable.
Preceding sections covered how to update supply chains or templates installed in a cluster. This section shows how you can experiment by making small changes in a live setup with kubectl edit
.
When you install Tanzu Application Platform by using profiles, a PackageInstall
object is created. This in turn creates a set of children PackageInstall
objects for installing the individual components that make up the platform.
PackageInstall/tap
└─App/tap
├─ PackageInstall/cert-manager
├─ PackageInstall/cartographer
├─ ...
└─ PackageInstall/tekton-pipelines
Because the installation is based on Kubernetes primitives, PackageInstall
tries to achieve the state where all packages are installed.
This is okay, but presents challenges for modifying the contents of some of the objects that the installation submits to the cluster. Namely, such modifications cause the original definition persisting instead of the changes.
For this reason, before you perform any customization to the Out of the Box packages, you must pause the top-level PackageInstall/tap
object by running:
kubectl edit -n tap-install packageinstall tap
Example YAML:
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
name: tap
namespace: tap-install
spec:
paused: true # ! set this field to `paused: true`.
packageRef:
refName: tap.tanzu.vmware.com
versionSelection:
# ...
With the installation of Tanzu Application Platform paused, all of the installed components are still there, but changes to those children PackageInstall
objects are not overwritten.
Now you can pause the PackageInstall
objects that relate to the templates or supply chains you want to edit.
For example:
To edit templates, run:
kubectl edit -n tap-install packageinstall ootb-templates
To edit the basic supply chains, run:
kubectl edit -n tap-install packageinstall ootb-supply-chain-basic
setting packageinstall.spec.paused:
as true
.
With the installations paused, further live changes to templates or supply chains are persisted until you revert the PackageInstall
s to not being paused. To persist the changes, follow the steps outlined in the earlier sections.
Most behaviors in supply chains are supplied by Kubernetes controllers. For example, Cloud Native Buildpacks are created by the kpack controller when a kpack Image object is created. Sometimes there is need for behavior and no controller for it exists. In these instances, you might want to write a script that uses a CLI tool, or interact with an external API. To do this, you can bring the behavior to the supply chain by using Tekton.
You can look at the kaniko image-building as an example. You create a Tekton Task kaniko-build
with instructions for how to build a Docker image using kaniko given a set of parameters. The Task has a set of steps. Each step refers to a container image and a set of instructions to run on the image. For example, it can be a Linux image against which a set of bash instructions are run. The Task is installed on the cluster in the tap-tasks
namespace.
You create the ClusterImageTemplate kaniko-template
to create Tekton TaskRuns. TaskRuns are immutable, so you add the lifecycle: tekton
field to the template’s specifications. This ensures two things:
To learn more about the lifecycle: tekton
field, see the Cartographer tutorial Lifecycle: Templating Objects That Cannot Update. To learn more about Tekton, see the Tekton documentation.
Kubernetes administrators can enable the Pod Security Admission controller to restrict the behavior of pods in a clear consistent fashion.For more information, see the Kubernetes documentation.
If this is the case on a cluster, the Tekton Tasks must be altered to adhere to the security context.
The task specification must include a stepTemplate
field with the following properties defined:
stepTemplate:
securityContext:
allowPrivilegeEscalation: false
runAsUser: 1000
capabilities:
drop:
- ALL
seccompProfile:
type: "RuntimeDefault"
runAsNonRoot: true
For more information about stepTemplate
, see the Tekton documentation.
To be PSA-compliant, stepTemplate
enforces that it is run as a non-root user. Task authors must ensure that there is no attempt to write to protected directories.
For example, a user might want to run a Go test and for their Task to use the Golang image.
In that image, the default value for the HOME
environment variable is /root
. This means that when running a command such as go test
, binaries are created in a subdirectory of the root directory. However, the user does not have permission to create binaries in a subdirectory of the root directory.
To address this example, the task author can include a step env
to override the default value:
steps:
- image: golang
name: test
env:
- name: HOME
value: /go
Knowing which directories are safe depends on the image you use. In this example, the /go
directory exists and is not protected on the golang
image, but the directory does not exist on an alpine image.