Using an unstructured repo

Using an unstructured repo lets you organize your repo arbitrarily. This flexibility lets you sync your existing Kubernetes configuration to your Config Sync repo. For example, if you want to sync a Helm chart to your cluster, you can run helm template and commit the rendered manifest to your repo. An unstructured repo also lets you create subfolders of resources.

Unstructured repos are recommended for most users. However, you can also create a hierarchical repo to separate configs into distinct categories. If you want to create hierarchical policies without adhering to the rules of the hierarchical repo, consider using Hierarchy Controller.


Unstructured repos have the following limitations:

Namespace-scoped objects

You can declare NamespaceSelectors in an unstructured repo. To declare a NamespaceSelector, add either the metadata.namespace or the NamespaceSelector annotation. Declaring both annotations is invalid. If namespace-scoped resources don't declare metadata.namespace or the NamespaceSelector annotation, then Config Sync uses the cluster's "default" namespace.

Unlike with an hierarchical repo, an unstructured repo does not have to declare all namespaces for the namespace-scoped objects in the repo. An object can define a metadata.namespace without having a matching namespace object in an unstructured repo. If the namespace already exists on the cluster, Config Sync creates the object within that namespace. If the namespace does not exist on the cluster yet, Config Sync creates the namespace implicitly.

In an unstructured repo, Objects that declare the NamespaceSelector annotation are applied to all namespaces that satisfy the NamespaceSelector's conditions. Before you create an unstructured repo with Objects that were previously used in a hierarchical repo, verify that your NamespaceSelectors do not apply to additional resources.

When you remove namespace-scoped objects from an unstructured repo, Config Sync deletes those objects, but it does not remove any namespaces that might have been created implicitly for those objects. This behavior happens because Config Sync can't infer when it's safe to delete a namespace that was created implicitly, so it's always left on the cluster.

Cluster-scoped objects

In an unstructured repo, ClusterSelectors function normally.

Configuring an unstructured repo

To configure an unstructured repo, set the value of spec.sourceFormat to unstructured in your RootSync object or ConfigManagement object.


The following RootSync object configures Config Sync to sync from an unstructured repo:

# root-sync.yaml
# If you are using a Config Sync version earlier than 1.7,
# use: apiVersion:
kind: RootSync
  name: root-sync
  namespace: config-management-system
  sourceFormat: unstructured
    branch: init
    dir: quickstart/multirepo/root
    auth: ssh
      name: SECRET_NAME

Replace SECRET_NAME with the name of the Secret.


The following ConfigManagement object sets up a continuous integration pipeline and specifies that the repository that it syncs to is unstructured:

# config-management.yaml

kind: ConfigManagement
  name: config-management
  # clusterName is required and must be unique among all managed clusters
  clusterName: CLUSTER_NAME
  sourceFormat: unstructured
    syncBranch: init
    secretType: ssh
    policyDir: ci-pipeline-unstructured

For a complete list of fields that you can add to the spec field, see ConfigManagement fields.

Converting a hierarchical repo to an unstructured repo

If you are using a hierarchical repo and want to convert it to an unstructured repo, follow these instructions to convert it:

  1. Remove Repo configs under the system/ directory from your Git repository. The Repo resource is not needed for the unstructured repository.

  2. Abstract namespace isn't supported in the unstructured repo. Therefore, check the resources under the namespaces/ directory and make sure that each resource has a namespace declared.

  3. Namespace inheritance isn't supported in unstructured repo. Therefore, check resources that are under the namespaces/ directory, but not under any namespaces/NAMESPACE/. In unstructured repo, these resources are no longer inherited by each namespace in namespaces/. You need to declare them in every /namespaces/NAMESPACE directory.

What's next