vcf-services

VCF Service Filesystem Layout

A VCF Service is built from a bundle directory - the source tree you maintain in version control - and published as distribution artifacts. This document describes the bundle directory structure.

Bundle Directory Structure

The bundle is a Carvel-compatible directory. The VCF Service framework adds a small set of conventions on top of standard Carvel.

<service-name>/                    # Root of the bundle source tree
  package.yml                      # PackageMetadata + Package CRs
  config/                          # ytt templates rendering CRs
    values.yml                     # ytt data values schema (#@data/values)
    vcf-service.yml                # Main entry point template
    *.lib.yml                      # (optional) ytt library files
    *.star                         # (optional) Starlark helper functions
  .imgpkg/
    images.yml                     # ImagesLock: content-addressed OCI image refs
  .values/
    render.yml                     # Concrete example values (used to render images.yml at build time)
    transpiler.yml                 # (optional) ytt transform: Inventory → service values
  .install/                        # (optional) Install-time UI plugin dependencies
    dependencies.yml

Component Descriptions

Path Purpose Required
package.yml Declares PackageMetadata (display name, icon, description) and Package (fetch/template/deploy pipeline, OpenAPI v3 values schema). Must be present for offline upload Yes
config/values.yml The ytt data values schema (#@data/values). Defines what inputs the service accepts, with defaults. Used by ytt at runtime. Yes
config/*.yml / config/*.star ytt templates that render the service’s services.vcfa.broadcom.com/v2 CRs. May include library files (.lib.yml) and Starlark helpers (.star) Yes
.imgpkg/images.yml An ImagesLock document generated by kbld during the build; maps symbolic image names to content-addressed digests Yes
.values/render.yml Concrete representative values used during build-time rendering so that kbld can resolve every image reference, including optional ones. Not part of the ytt runtime schema. Yes
.values/transpiler.yml A ytt template that transforms the Service Manager Inventory object into the values expected by the service’s OpenAPI schema. Required only when the inventory structure differs from the service’s input schema Conditional
.install/dependencies.yml Install-time UI plugin image references, used by the Service Manager to pre-load plugins. Required only for services with UI plugins that install independently of the main bundle Conditional

Self-Contained Bundle Requirement

Every bundle must include ./package.yml at its root. This enables:

Config Template Conventions

Templates under config/ must only produce Custom Resources from the services.vcfa.broadcom.com/v2 API group, plus Kubernetes Secret resources for configuration. No other resource kinds are allowed.

The recommended layout for config/:

config/
  values.yml              # Data values schema (#@data/values)
  vcf-service.yml         # Main entry point (loads libs, renders all CRs)
  server.lib.yml          # Library: CRs installed on the host Supervisor
  client.lib.yml          # Library: CRs installed on client Supervisors
  lib.star                # Starlark helper functions

config/values.yml Example

#@data/values
#@overlay/match-child-defaults missing_ok=True
---
regions: []

config/vcf-service.yml Entry Point Example

#@ load("@ytt:data", "data")
#@ load("@ytt:template", "template")

#@ load("lib.star", "documents")
#@ load("server.lib.yml", "server", "singleton")
#@ load("client.lib.yml", "clients")

#@ template.replace(documents(data, server, clients, singleton))

.values/render.yml Example

render.yml provides concrete values used during the build. kbld renders all templates with these values to discover every image reference - including those inside optional configuration branches - before writing .imgpkg/images.yml. These values are not shipped inside the bundle or used at runtime.

regions:
  - name: us-west-1
    hostSupervisor:
      name: us-west-1a
      configuration:
        hostname: my-service.example.com
        adminPassword: ExamplePass1!
        persistence:
          persistentVolumeClaim:
            storageClass: vks-content-library
    clientSupervisors:
      - us-west-1a

.values/transpiler.yml Example

#@ load("@ytt:data", "data")

#! Transform Service Manager Inventory to service values
---
#@ def merge_regions():
#@   result = []
#@   for region in data.values.regions:
#@     result.append({
#@       "name": region.name,
#@       "hostSupervisor": {
#@         "name": region.supervisors[0].name,
#@         "configuration": {
#@           "persistence": {
#@             "persistentVolumeClaim": {
#@               "storageClass": region.supervisors[0].defaultStorageClass,
#@               "size": "10Gi"
#@             }
#@           }
#@         }
#@       },
#@       "clientSupervisors": [s.name for s in region.supervisors]
#@     })
#@   end
#@   return result
#@ end

---
regions: #@ merge_regions()

Distribution Artifacts

The build produces two distribution artifacts from the dist/ directory:

dist/
  <name>-<version_tag>.tar    # Self-contained imgpkg bundle tarball

Bundle Tarball (<name>-<version_tag>.tar)

The tarball is the output of imgpkg copy --bundle ... --to-tar. It is an offline, self-contained archive that embeds the full imgpkg bundle together with all referenced OCI images (Supervisor Service bundle images, UI plugin images, etc.).

This is the artifact registered with VCF Automation via the upload API.

Build-time Injection: config/.vcf/dependencies.yml

When a service includes a SupervisorService, the build process copies the Supervisor Service imgpkg bundle to the build registry and injects the resolved Package and PackageMetadata CRs into config/.vcf/dependencies.yml before the bundle is packaged. This file is a ytt data values document created at build time and included inside the built bundle.

#@data/values
---
__system:
  supervisorService:
    package:
      apiVersion: packaging.carvel.dev/v1alpha1
      kind: Package
      metadata:
        name: my-supervisor-svc.example.com.1.2.3
      spec:
        refName: my-supervisor-svc.example.com
        version: 1.2.3
        template:
          spec:
            fetch:
            - imgpkgBundle:
                image: arcturus.corp.home.svc/vcf/my-supervisor-svc/1.2.3/my-supervisor-svc:1.2.3
    packageMetadata:
      apiVersion: data.packaging.carvel.dev/v1alpha1
      kind: PackageMetadata
      metadata:
        name: my-supervisor-svc.example.com
      spec:
        displayName: My Supervisor Service
        shortDescription: Deploys my-svc onto the Supervisor

The ytt templates in config/ read from data.values.__system.supervisorService to construct the SupervisorService CR at runtime. Additional system values for UI plugins and RDE bundles are injected under .__system.<key> following the same pattern.

This keeps all Supervisor Service package identity information out of the source tree - it is resolved at build time from the actual bundled artifact, not hard-coded by the service author.