ytt

repository·develop·Indexed 23 days ago

https://github.com/carvel-dev/ytt

A YAML-aware templating tool that uses the Starlark programming language for structured, programmable, and reusable configuration management. It supports YAML overlays for modifying or removing elements, data value validation (inline, function, and bulk approaches), and integration as a Helm post-renderer to modify rendered templates without forking charts.

Tokens
9.2K
Snippets
27
Records
62
Agent score
79%

What's inside ytt

  1. What is ytt?

    develop

    ytt (pronounced spelled out) is a YAML-aware templating tool designed to manage complex software configurations through reusable templates and user-provided values. Unlike text-based templating engines, ytt understands the underlying YAML structure, preventing common issues like incorrect indentation or quoting errors.

    Key features include:

    • Structural Templating: Operates on YAML nodes rather than raw text.
    • Starlark Integration: Uses the Starlark programming language (a Python-like dialect) for logic within templates.
    • Reusable Configuration: Supports environment-specific values to reuse templates across different contexts.
    • Custom Validations: Enables fast, deterministic feedback loops for template testing.
    • Overlays: Allows advanced customization of complex software configurations.
    • Sandboxing: Ensures a secure and deterministic execution environment.
  2. Understand ytt source code structure

    develop

    If you are extending or contributing to ytt, the following packages contain the core logic:

    • pkg/cmd/template/cmd.go: The top-level call site for the template command.
    • pkg/files: Handles reading files from the filesystem.
    • pkg/workspace: Maintains read files from the filesystem in memory for later access. The load(...) directive uses TemplateLoader to load files.
    • pkg/yamlmeta: Parses YAML and tracks YAML node annotations (metas).
    • pkg/yamltemplate: Generates Starlark templates based on yamlmeta structures.
    • pkg/texttemplate: Parses text templates and generates Starlark templates.
    • pkg/template: Provides the core templating engine. InstructionSet provides generic template instructions, and CompiledTemplate uses the Starlark Go library for evaluation.
    • pkg/yttlibrary: The bundled @ytt standard library.
  3. Understand ytt library terminology

    develop

    When working with libraries in ytt, distinguish between these three concepts:

    • library path: A string describing the location of a library under _ytt_lib in the format @lib1@nested-lib2. Used in library.get("@...") and load("@...").
    • library alias: A string used to reference a library instance instead of its full path. Assigned via the alias kwarg to library.get(...). For example, an instance returned by library.get("/github.com/folder/my-lib", alias=my-lib) can be addressed in @library/ref annotations using just my-lib.
    • library ref: A string describing a reference to a library under _ytt_lib. It can be either the library path or the library alias. Example: @lib1@~foo. Used in:
      • library/ref annotations: #@library/ref "@lib1@~foo"
      • Data value flags: -v @~foo:key=value
  4. Choose an integration strategy for ytt

    develop

    There are two primary ways to integrate ytt into your workflow:

    Invoke the ytt binary as a separate process. This is the preferred method for most use cases because it:

    • Decouples your tool's versioning from ytt, allowing easier upgrades.
    • Provides well-defined integration interfaces for easier troubleshooting.
    • Includes safety checks to ensure inputs are well-formed.
    • Allows your tooling to be written in any language that can execute shell commands.

    2. As a Go Module

    Construct and execute ytt command objects in-process. This is appropriate only when:

    • Your use case is very narrow and doesn't benefit from standard ytt features.
    • Your tool must be distributed as a single binary and cannot rely on an external ytt installation.

    Note on Performance: Performance is typically not a deciding factor between these two methods; ytt can evaluate complex libraries in less than a second on standard hardware.

  5. Configure library data values directly

    develop

    As of ytt v0.28.0+, you can directly configure data values belonging to a library using the @library/ref syntax in the command line or via a data values file. This allows you to override or set values inside a library without needing to expose them in your top-level schema.

    To override a library value via the CLI, use the -v flag with the @library_name:key=value syntax.

    $ ytt -f . -v image.username=bob -v @app1:other=new-config
  6. Overlay specific Kubernetes objects using overlay.subset()

    develop

    When performing overlays on multiple objects of the same kind (e.g., multiple Ingress objects), use overlay.subset() to target a specific instance. You can filter by kind and then refine the selection using metadata.name to ensure you are patching the correct resource.

    In this example pattern, the overlay targets an Ingress by matching its kind and then filtering for a specific name within the subset.

  7. Use ytt as a Helm post-renderer

    develop

    Helm 3.1+ supports a pluggable interface to modify rendered templates before installation. You can use ytt as a post-renderer by providing a script that reads the rendered Helm templates from stdin and outputs the modified YAML to stdout.

    In this pattern, ytt is typically used to apply overlays (to add labels, annotations, or change values) or to inject additional resources into the Helm chart output.

  8. Wrap upstream templates to expose simplified data values

    develop

    You can wrap an upstream set of templates (a library) to provide a simplified interface for configuration. Instead of requiring users to provide complex, nested data values required by the internal templates, you can expose a subset of those values in your own schema.

    In this pattern:

    1. An upstream library (e.g., _ytt_lib/app1) defines its own complex schema (e.g., image.url).
    2. Your top-level schema.yml defines a simplified schema (e.g., image.username).
    3. Your templates use logic to combine the simplified values into the complex ones required by the library.
    4. Your config.yml includes the library and provides the augmented data.
  9. Remove Kubernetes resources conditionally using @overlay/match with when=

    develop
    When performing overlays on Kubernetes resources, you may want to remove specific declarations (like initContainers) only if they exist. Instead of using expects=, which requires the target to exist, use the when= kwarg in the @overlay/match directive. This allows you to conditionally target and remove parts of a YAML document based on a predicate, making the overlay safer for resources that might not always contain the specific field you are targeting.
  10. Guidelines for contributing to the ytt standard library

    develop

    When adding new modules to pkg/yttlibrary, follow these design principles:

    API Design

    • Start with the API: Solidify the Starlark API before implementation. Use acceptance tests in pkg/yamltemplate/filetests/ytt-library/... to codify the API.
    • Naming Conventions:
      • Modules: Be concrete and avoid redundancy (e.g., ip.parse_addr() instead of ip.parse_ip_addr()).
      • Functions: Use verb/verb phrases. For built-ins, use the format ${module}.[${type_name}.]${function_name} (e.g., ip.addr.is_ipv4). In Go, use snakeCase for the implementation.
      • Types: Use the format @ytt:${module}.${type} (e.g., @ytt:ip.addr).
    • Immutability: Return modified copies rather than mutating the receiver.
    • Error Handling: Fail fast. Users prefer an error over a "guess" or "fix".
    • String Conversion: Offer string() rather than assuming a specific encoding. Implement UnconvertableStarlarkValue and suggest users use string() in conversion hints.

    Implementation Details

    • Design Philosophy: Be inspired by Python (Starlark is a dialect) and Go (for simplicity). Adapt to the context of hermetic, deterministic YAML configuration.
    • Starlark Values: Built-in functions must return a valid starlark.Value. Note that nil is not a valid starlark.Value; use starlark.None instead.
    • Automated Tests: Always include tests to verify functionality and catch breaking changes in dependencies. Tests should live in pkg/yamltemplate/filetests/ytt-library.
  11. Use @ytt:library to programmatically template custom libraries

    develop

    You can use the @ytt:library module to define and reuse custom library logic across your templates. This allows you to programmatically template components by referencing a library (e.g., app) located within a specific directory structure (e.g., _ytt_lib/app).

    In this pattern, the library is treated as a module that can be imported and invoked within your YAML templates, enabling complex logic to be encapsulated and reused.