Use an unstructured repository

Using an unstructured repository lets you organize your repository in the way that is most convenient to you. This flexibility lets you sync your existing Kubernetes configuration to your Config Sync repository. For example, if you want to sync a Helm chart to your cluster, you can run the helm template command and commit the rendered manifest to your repository. For more information, see the Using Config Sync with Helm tutorial.

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

Limitations

Unstructured repositories have the following limitations:

  • You cannot use the Repo or HierarchyConfig Kubernetes objects in an unstructured repository.

  • Abstract namespaces are not supported in unstructured repositories.

  • If you are using the nomos vet command, add the --source-format=unstructured flag. For example:

    nomos vet --source-format=unstructured
    

Namespace-scoped objects

You can declare NamespaceSelectors in an unstructured repository. 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 "default" namespace of the cluster. To learn more, see Limit which namespaces a config affects.

Cluster-scoped objects

In an unstructured repository, ClusterSelectors function normally.

Configure an unstructured repository

To configure an unstructured repository, set the value of spec.sourceFormat to unstructured in your RootSync object:

  # root-sync.yaml
  apiVersion: configsync.gke.io/v1beta1
  kind: RootSync
  metadata:
    name: ROOT_SYNC_NAME
    namespace: config-management-system
  spec:
    sourceFormat: unstructured
    git:
      repo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples
      branch: main
      dir: config-sync-quickstart/multirepo/root
      auth: ssh
      secretRef:
        name: SECRET_NAME

Replace the following:

  • ROOT_SYNC_NAME: add the name of your RootSync object. The name should be unique in the cluster and have no more than 26 characters.
  • SECRET_NAME with the name of the Secret.

Convert a hierarchical repository to an unstructured repository

If you're using a hierarchical repository and want to convert it to an unstructured repository, in your repository, run:

nomos hydrate PATH

Replace PATH with the path to your directory.

This command 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 repository.

For more details, see nomos commands.

If you prefer converting your repository manually, complete the following instructions:

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

  2. The abstract namespace directory isn't supported in an unstructured repository. Therefore, you must declare the namespace of all resources originally included in the namespaces/ directory and its subdirectories.

  3. Namespace inheritance isn't supported in the unstructured repository. Therefore, you must declare all resources that are originally inherited in descendant namespaces, namely the ones originally under the namespaces/ directory.

Example format for an unstructured repository

The following example demonstrates how you might organize your configs (including Google Cloud resources) in an unstructured repository:

├── manifests
│   ├── access-control
│   │   ├── ...
│   ├── change-control
│   │   ├── ...
│   ├── git-ops
│   │   └── ...
│   ├── logging-monitoring
│   │   └── ...
│   ├── networking
│   │   └── ...
│   ├── project-factory
│   │   └── ...
│   └── resource-hierarchy
│   │   └── ...
├── raw-configs
│   ├── access-control
│   │   └── ...
│   ├── change-control
│   │   └── ...
│   ├── git-ops
│   │   └── ...
│   ├── logging-monitoring
│   │   └── ...
│   ├── networking
│   │   └── ...
│   ├── project-factory
│   │   └── ...
│   └── resource-hierarchy
│   │   └── ...
└── scripts
    └── render.sh

In this example, the raw configs are in a raw-configs directory. You could then use a script or an automated pipeline to render the raw configs and store the output in the manifests directory. When you configure Config Sync, you'd configure it to sync from your manifests directory.

What's next