Using an unstructured repo lets you organize your repo in the way that is most
convenient to you. 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
template and commit the
rendered manifest to your repo. For more information on how you can do this,
see the Using Config Sync with Helm
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:
You cannot use the
HierarchyConfigKubernetes objects in an unstructured repo.
Abstract namespaces are not supported in unstructured repos.
If you are using the
nomos vetcommand, add the
--source-format=unstructuredflag. For example:
nomos vet --source-format=unstructured
You can declare NamespaceSelectors in an unstructured repo. To declare a
NamespaceSelector, add either the
metadata.namespace or the
annotation. Declaring both annotations is invalid. If namespace-scoped
resources don't declare
metadata.namespace or the
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
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
In an unstructured repo, Objects that declare the
are applied to all namespaces that satisfy the
Before you create an unstructured repo with Objects that were previously used in
a hierarchical repo, verify that your
NamespaceSelectors do not apply to
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.
In an unstructured repo,
ClusterSelectors function normally.
Configuring an unstructured repo
To configure an unstructured repo, set the value of
unstructured in your RootSync object or ConfigManagement object.
The following RootSync object configures Anthos Config Management to sync from an unstructured repo:
# root-sync.yaml # If you are using a Config Sync version earlier than 1.7, # use: apiVersion: configsync.gke.io/v1alpha1 apiVersion: configsync.gke.io/v1beta1 kind: RootSync metadata: name: root-sync namespace: config-management-system spec: sourceFormat: unstructured git: repo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples branch: main dir: quickstart/multirepo/root auth: ssh secretRef: name: SECRET_NAME
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 apiVersion: configmanagement.gke.io/v1 kind: ConfigManagement metadata: name: config-management spec: # clusterName is required and must be unique among all managed clusters clusterName: CLUSTER_NAME sourceFormat: unstructured git: syncRepo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples syncBranch: main secretType: ssh policyDir: ci-pipeline-unstructured
For a complete list of fields that you can add to the
spec field, see
Converting a hierarchical repo to an unstructured repo
nomos hydrate [/path/to/directory]
This creates a
compiled/ directory in the current working directory. Within
that directory, a subdirectory is created for each enrolled cluster, with the
fully-resolved configs, and each subdirectory can be used in an unstructured
For more details, see
If you prefer doing it manually, follow these instructions to convert it:
Repoconfigs under the
system/directory from your Git repository. The
Reporesource is not needed for the unstructured repository.
The abstract namespace directory isn't supported in the unstructured repo. Therefore, you must declare the namespace of all resources originally under the
namespaces/directory and its sub-directories.
Namespace inheritance isn't supported in the unstructured repo. Therefore, you must declare all resources that are originally inherited in descendant namespaces, namely the ones originally under the
- Create cluster-scoped objects
- Create namespace-scoped objects
- Take the Creating policies for a multi-tenant cluster tutorial, which uses an unstructured repository.