sigs.k8s.io/cluster-api@v1.6.3/docs/proposals/20200511-clusterctl-extensible-template-processing.md (about)

     1  ---
     2  title: Extensible Templating Processing for clusterctl
     3  authors:
     4  * "@wfernandes"
     5  reviewers:
     6  * "@timothysc"
     7  * "@ncdc"
     8  * "@fabriziopandini"
     9  * "@vincepri"
    10  
    11  
    12  creation-date: 2020-04-27
    13  last-updated:  2020-05-27
    14  status: implementable
    15  see-also:
    16  * https://github.com/kubernetes-sigs/cluster-api/issues/2339
    17  replaces:
    18  * N/A
    19  superseded-by:
    20  * N/A
    21  ---
    22  
    23  
    24  # Extensible Template Processing for clusterctl
    25  
    26  
    27  ## Table of Contents
    28  
    29  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
    30  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
    31  
    32  - [Glossary](#glossary)
    33  - [Summary](#summary)
    34  - [Motivation](#motivation)
    35    - [Goals](#goals)
    36    - [Non-Goals](#non-goals)
    37    - [Future Work](#future-work)
    38  - [Proposal](#proposal)
    39    - [User Stories](#user-stories)
    40    - [Implementation Details/Notes/Constraints](#implementation-detailsnotesconstraints)
    41      - [UX for using Extensible Templating Tools](#ux-for-using-extensible-templating-tools)
    42      - [Interface and Library Changes](#interface-and-library-changes)
    43      - [Notes](#notes)
    44    - [Risks and Mitigations](#risks-and-mitigations)
    45    - [Constraints](#constraints)
    46  - [Alternatives](#alternatives)
    47  - [Upgrade Strategy](#upgrade-strategy)
    48  - [Additional Details](#additional-details)
    49  - [Implementation History](#implementation-history)
    50  
    51  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
    52  
    53  ## Glossary
    54  
    55  Refer to the [Cluster API Book Glossary](https://cluster-api.sigs.k8s.io/reference/glossary.html).
    56  
    57  SimpleYamlProcessor - This is the processor that will handle the existing
    58  variable substitution method of templating. This will be the default mode of
    59  operation.
    60  
    61  Some templating tools that can be used to manage your templates.
    62  
    63  * Ytt - Yaml Templating Tool.
    64    * Source https://github.com/k14s/ytt
    65  * Cue - Cue Data Constraint Language.
    66    * Source: https://github.com/cuelang/cue
    67  * Dhall - Dhall Programming Configuration Language.
    68    * Source: https://github.com/dhall-lang/dhall-lang
    69    * Golang Library: https://github.com/philandstuff/dhall-golang
    70    * Kubernetes Library: https://github.com/dhall-lang/dhall-kubernetes
    71  * Helm Template
    72    * Doc: https://helm.sh/docs/helm/helm_template/
    73    * Code: https://github.com/helm/helm/blob/main/cmd/helm/template.go
    74  
    75  
    76  ## Summary
    77  
    78  Clusterctl handles the lifecycle of Cluster API management and workload
    79  clusters. It automates fetching the YAML files defining provider components
    80  and the cluster templates used to define workload clusters. However, as more
    81  providers contribute to CAPI and the variety of workload cluster templates
    82  increase, it becomes harder for operators to manage all the cluster template
    83  flavor permutations. Operators and providers are now leaning towards yaml
    84  templating tools to properly manage the variety of cluster templates, and to
    85  simplify the end user experience by limiting the amount of boilerplate YAML
    86  that operators need to supply.
    87  
    88  This proposal outlines the need to create an extensible templating mechanism
    89  within clusterctl so that it can be used effectively with other templating
    90  tools and continue to provide a seamless user experience.
    91  
    92  ## Motivation
    93  
    94  To support a Cluster API that is cloud agnostic, operators need to deploy
    95  workloads in a multi-cloud environment. Operators and providers may need to
    96  create and _manage_ multiple cluster templates across a matrix of options and
    97  configurations. To manage the explosion of yaml manifests, operators may want
    98  to explore templating tools to minimize duplication and assert type
    99  correctness.
   100  
   101  Users looking to deploy workload clusters may be overwhelmed by the number of
   102  variables needed to configure a workload cluster. Some of these options may be
   103  circumvented via defaults provided by the operators as part of the templating
   104  tool.
   105  
   106  This proposal aims to extend clusterctl’s current templating mechanism of
   107  simple variable substitution to support other templating formats natively,
   108  thus benefiting the operators to deploy workload clusters with minimal
   109  configuration.
   110  
   111  ### Goals
   112  
   113  - Clusterctl will not be changing the way it gets values for yaml variables.
   114    That is, it will get values from environment variables and the config file.
   115  - To provide an interface such that other templating solutions may be
   116    supported.
   117  
   118  ### Non-Goals
   119  
   120  - To disrupt upstream templating solutions such as kustomize.
   121  - To replace Clusterctl default mode of processing templates, aka
   122    `SimpleYamlProcessor`.
   123  
   124  ### Future Work
   125  
   126  - To automatically detect template files for the appropriate template engine.
   127  - To use the configuration file to determine which provider should use
   128    preferred templating mechanisms.
   129  
   130  ## Proposal
   131  
   132  This section outlines the high level work that needs to be done in order to
   133  accomplish the task of supporting other templating tools.
   134  
   135  ### User Stories
   136  
   137  - As a clusterctl user, I would like to preserve the current behavior of using
   138    existing workload cluster templates with simple variable substitution from
   139    the clusterctl config and environment variables.
   140  - As an infrastructure provider, I would like to provide templated yaml with
   141    defaults and have that be consumed by `clusterctl config cluster` to
   142    generate cluster manifests.
   143  - As a developer, I would like to easily provide a way to extend clusterctl
   144    with my preferred templating solution.
   145  
   146  ### Implementation Details/Notes/Constraints
   147  
   148  Currently the clusterctl command fetches yaml for the provider components
   149  (yaml defining the management cluster components) and the workload cluster
   150  templates.
   151  
   152  #### UX for using Extensible Templating Tools
   153  
   154  For the first iteration, we won't be making any user facing changes to the
   155  clusterctl CLI. Therefore all the clusterctl commands will hold true with the
   156  current expected behavior. The changes will be exposed via the clusterctl library.
   157  
   158  #### Interface and Library Changes
   159  
   160  ![Figure 1](./images/clusterctl-extensible-templates/pkgCalls.png)
   161  
   162  <div align="center">Package Method Calls for `clusterctl config cluster`</div>
   163  
   164  
   165  The `TemplateClient` will contain a field adhering to the interface - `YamlProcessor`.
   166  
   167  ![Figure 2](./images/clusterctl-extensible-templates/templateClient.png)
   168  
   169  ![Figure 3](./images/clusterctl-extensible-templates/yamlProcessor.png)
   170  
   171  The `YamlProcessor` will provide three behaviors.
   172  
   173  1. `ArtifactName` will return the name of the template artifacts that need to be retrieved from the source.
   174  
   175     - For the default `SimpleYamlProcessor`, it will be `cluster-template.yaml`. If the
   176       flavor option is provided, it will be `cluster-template-<flavor>.yaml`.
   177     - For other `YamlProcessor`s, it could be something that follows a separate
   178       convention such as
   179       `cluster-template-<template-engine-type>.<compression-format>`. This
   180       should include all the artifacts required by the template processor to
   181       produce the final YAML template.
   182  
   183     Once we retrieve the artifact blob of bytes we can then perform the required
   184     two functions.
   185  
   186  2. `GetVariables` is responsible for parsing the template artifact blob of bytes and
   187     providing a list of variables that the template requires.
   188  
   189  3. `Process` is responsible for parsing the artifact blob of bytes and will
   190     return the final manifest with values retrieved from the `VariablesGetter`.
   191  
   192  The yaml specific processor can be passed in via the clusterctl library.
   193  
   194  
   195  #### Notes
   196  
   197  - Another method of defining a yaml processor instead of using its library
   198    would be to shell out to the templating engine binary/executable.
   199    The advantage of this is that the templating engine is not a dependency within
   200    the clusterctl codebase.
   201    The disadvantage is that the user needs to ensure the binary is installed
   202    separately which disrupts the UX of clusterctl. If each infrastructure
   203    provider provides different template styles, the user would need to install
   204    multiple templating tool binaries.
   205  
   206  ### Risks and Mitigations
   207  
   208  - Support path for supporting extended templating tools within clusterctl.
   209    That is, if there are templating issues, who owns them and how do we address
   210    them. This is for each templating engine that is included in clusterctl.
   211    However since if we decide to put extended templating
   212    libraries within a **contrib** folder, it will be the responsibility of the
   213    contributor and not the project maintainers to support the templating
   214  libraries so the issue of support should be solved with this contract.
   215  
   216  - Each provider may want to implement their own templating standard. This
   217    could affect the UX of clusterctl when automatically pulling workload
   218    cluster templates from various providers.
   219  
   220  - Define a format or convention for retrieving multiple template files.
   221    Currently, clusterctl supports template retrieval from a ConfigMap in a
   222    cluster, URL, Github release artifacts and local file system. We default to
   223    retrieving provider cluster templates from github release assets. In order to
   224    avoid running into github quota limits on retrieving asset files we can pull a
   225    compressed file with all the template contents.
   226  
   227    As mentioned above in the *Constraints* and *Implementation* section a suggestion
   228    for convention would be
   229    `cluster-template-<template-engine-type>.<compression-format>`. Compression
   230    format could be tar, gzip, zip, etc.
   231  
   232    We will be leaning towards `tar.gz` compression format unless any objections.
   233  
   234  ### Constraints
   235  
   236  - Currently, clusterctl relies on the conformance of file name conventions
   237    such as `infrastructure-components.yaml` and
   238    `cluster-template-<flavor>.yaml`. Other templating tools might require other
   239    conventions to be defined and followed to allow the same "day 1" experience.
   240  - Some templating tools will require multiple files to be defined rather than
   241    a single yaml file. These artifacts will need to be "grouped" together to
   242    support current retrieval mechanisms. Currently, `clusterctl config cluster`
   243    retrieves templates from multiple sources such as ConfigMaps within a
   244    cluster, URL, Github Repository, Local Repository and even the overrides
   245    directory. To ensure compatibility, we’ll need to establish a compression
   246    format like tar.gz
   247  
   248  ## Alternatives
   249  
   250  - An alternative to allowing clusterctl handle templates would be to just use
   251    another tool upstream to generate the various templates with variables
   252    defined. Then use clusterctl to consume that template and use the
   253    `SimpleYamlProcessor` to produce the template.
   254  
   255  
   256  ## Upgrade Strategy
   257  
   258  Any individual template engine libraries would be upgraded via go modules
   259  preferably using semver standards.
   260  
   261  
   262  ## Additional Details
   263  
   264  Currently, cluster-api-provider-azure is using kustomize to author their
   265  cluster template flavors. See [issue 540] for more details. Maybe we can
   266  collect input from them to understand their strategy if they need to
   267  manage their template variations.
   268  
   269  
   270  ## Implementation History
   271  
   272  - 04/22/2020: Proposed idea in an issue or [community meeting]
   273  - 04/27/2020: Compile a [CAEP Google Doc] following the CAEP template
   274  - 05/06/2020: First round of feedback from community
   275  - 05/11/2020: Open proposal PR
   276  - 05/13/2020: Present proposal at a [community meeting]
   277  
   278  
   279  
   280  
   281  <!-- Links -->
   282  [community meeting]: https://docs.google.com/document/d/1fQNlqsDkvEggWFi51GVxOglL2P1Bvo2JhZlMhm2d-Co/edit#heading=h.3wfmgc28aou3
   283  [CAEP Google Doc]: https://docs.google.com/document/d/1GByR9Dm0igw7FaDDwIM7OldhB5TMuixHswq7TAO1bQg/edit?usp=sharing
   284  [issue 540]: https://github.com/kubernetes-sigs/cluster-api-provider-azure/pull/540