Search documentation
karat

+

K

Create, edit, and delete a Module

This page outlines how to:

Create a Module

Prerequisites

You should download and configure the Apollo CLI before creating a Module.

To use this feature, you may need to update the Apollo CLI by re-downloading it.

This guide will walk through creating a new Module that contains Products related to an application control plane.

Create the Module YAML file

To create a new Module, create a YAML file that contains configuration for the Module. The name of the file should be the same as the value in the name field. In this example, the file name would be control-plane-module.yaml.

Name and description

Copied!
1 2 3 name: "control-plane-module" displayName: "Control Plane Module" description: "Entities required for the application control plane."

Variables

You can define any variables for the Module in the variables block of Module YAML file. For each variable, you should define the following configuration items:

  • Name: The name for the variable, for example releaseChannel.
  • type: The type of value a user should enter when installing a Module. Currently, string is the only supported type.
  • defaultValue (optional): Default value for the variable when installing a Module. If no default value is present, then you must enter a value when installing the Module.
  • description: A description for the variable, which will provide guidance to you when you are installing the Module.

Below is an example variable definition:

Copied!
1 2 3 4 5 6 variables: releaseChannel: type: string, string: defaultValue: "STABLE_2", description: "Default Release Channel for all Entities"

You can only reference a variable using the curly brace syntax ({{ moduleVariable.releaseChannel }}) if it is defined in the variables block of the Module YAML file. You cannot delete a variable from the variables block of an existing Module if it is still referenced elsewhere in the Module definition.

Entities

You can define specific configuration for each Entity of the Module in the entities block in the Module YAML file.

Note that when you refer to a variable, the value should be surrounded by double curly brackets and should include the moduleVariable prefix before the variable name. For example, you can refer to the releaseChannel variable by writing {{ moduleVariable.releaseChannel }}. For each Entity, you should define the following configuration items:

  • type: The Product type of the Entity. Currently, only Helm charts are supported.
  • productId: The Product ID of the Entity, which is the groupId:artifactId of the Product's Maven coordinate.
  • entityName (optional): An identifier for the Entity. Defaults to the artifactId from the Entity's ProductId.
  • releaseChannel (optional): The Release Channel that the Entity should follow. Defaults to the Environment's Release Channel.
  • k8sNamespace: The Kubernetes namespace that the Entity should be installed in.
  • ignoredDependencies: Apollo will ignore any Product dependency constraints for the Products you list in the ignored dependencies. If there are none, you should enter an empty list like the below example.
  • downtimeMaintenanceWindowId (optional): You can specify all-time, or use a variable to specify a maintenance window at Module installation. Defaults to the Environment's default downtime maintenance window.
  • noDowntimeMaintenanceWindowId (optional): You can specify all-time, or use a variable to specify a maintenance window at Module installation. Defaults to the Environment's default no-downtime maintenance window.
  • configOverrides (optional): You can define Entity config overrides in the Module YAML file.
  • syncConfigOverrides (optional): Determines whether Apollo should overwrite existing config overrides for an Entity or not when installing a Module or updating an existing Module installation. When set to ENABLED, Apollo will overwrite existing config overrides for the Entity. When set to DISABLED, Apollo will not overwrite existing config overrides for the Entity. With both options, when adding a new Entity, Apollo will add the config overrides specified in the definition regardless. Defaults to ENABLED.
  • markedForUninstallation (optional): If this field is present, Apollo will mark the Entity for uninstallation when the Module is installed. If the Entity does not exist in the Environment, Apollo will ignore this Entity during Module installation.
    • minVersion (optional): The minimum version of the Entity that should be uninstalled. If not present, Apollo will uninstall all versions of the Entity.
    • unmanageAfterUninstall (optional): If set to AUTOMATIC, Apollo will unmanage the Entity after uninstalling it. If set to MANUAL, Apollo will leave the Entity managed after uninstalling it. Defaults to AUTOMATIC.
  • secretRequirements (optional): You can specify a list of secret names and list of associated secret keys that must exist before the Module is installed or upgraded. The Module installation interface will guide users through setting up the correct secrets for the Entities that have this field set. See the full example below for the syntax of secret requirements.

All non-optional fields must be present for each Entity in the Module YAML file. If you do not know a particular value when creating a Module, you can use a variable to define the value at Module installation.

Below is an example Entity definition:

Copied!
1 2 3 4 5 6 7 8 9 10 entities: - type: helmChart helmChart: productId: com.palantir.example:backend-service releaseChannel: "{{ moduleVariable.releaseChannel }}" k8sNamespace: app-namespace configOverrides: | 2.0.0: overrides: num-threads: 100

If an Entity with the same name already exists, Apollo will overwrite the existing Entity's settings to match that in the Module definition.

Submodules

You can create a Composite Module by referencing other existing Modules under the submodules list. This enables you to manage complex configurations by breaking them down into smaller, reusable components.

Below is the structure for including a basic submodule in the Module YAML file:

Copied!
1 2 3 submodules: - name: "submodule-name" revision: 3

For each submodule, you should define the following configuration items:

  • name: The name of the Module to be used as a submodule. This must be a Module that already exists in Apollo.
  • revision: The version of the Module to be used as a submodule. The provided revision is immutable for a given revision of the parent Module; a new revision of the parent Module has to be created in order to update the included submodule.
  • key (optional): When the same Module is used as a submodule multiple times, a unique key is required to differentiate between them.
  • variableOverrides (optional): Allows for overriding any variables defined in the submodule. An override can either hardcode a value, or re-map the submodule's variable to a variable defined in the parent Module.
  • entityOverrides (optional): Allows for overriding configurations and secrets of Entities defined in the submodule. This can be used to customize the behavior of the submodule within the parent Module.

Below is an example definition of a composite Module:

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 name: control-plane-module displayName: Control Plane Module description: A module that includes 2 submodules. variables: parentReleaseChannel: type: string string: defaultValue: "RELEASE" description: "Default Release Channel for all Entities" submodules: - name: "backend-module" revision: 3 variableOverrides: releaseChannel: "{{ moduleVariable.parentReleaseChannel }}" - name: "frontend-module" revision: 2 variableOverrides: enableExperimentalFeature: "true"

In this example, control-plane-module includes two submodules: backend-module and frontend-module. The releaseChannel variable defined in backend-module is overridden to instead use the value provided for the parentReleaseChannel variable defined in the parent Module. The enableExperimentalFeature variable defined in frontend-module is hardcoded to true. A value for it will not be required to be provided at install time.

For more in depth information on submodules, see Module composition.

Full example

Below is an example of a complete Module YAML file. You can add more variables and Entities using a comma separated list of entries.

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 name: control-plane-module displayName: Control Plane Module description: Entities required for the application control plane. variables: releaseChannel: type: string string: defaultValue: STABLE_2 description: Default Release Channel for all Entities entities: - type: helmChart helmChart: productId: com.palantir.example:backend-service releaseChannel: "{{ moduleVariable.releaseChannel }}" k8sNamespace: app-namespace configOverrides: | 2.0.0: overrides: num-threads: 100 - type: helmChart helmChart: productId: com.palantir.example:frontend-application releaseChannel: "{{ moduleVariable.releaseChannel }}" k8sNamespace: app-namespace downtimeMaintenanceWindowId: all-time noDowntimeMaintenanceWindowId: all-time secretRequirements: my-secret: type: multikey multikey: description: API key for communicating between services keys: - api-key - type: helmChart helmChart: productId: com.palantir.example:deprecated-application k8sNamespace: app-namespace markedForUninstallation: minVersion: 1.0.0 unmanageAfterUninstall: MANUAL

Publish the Module to Apollo

Run the following command in your terminal to publish your Module to Apollo.

Copied!
1 apollo-cli module create --module-definition-file /path/to/yaml/file.yml

Learn more about the apollo-cli create-module command.

Module revisions

Once created, each Module will be automatically assigned a revision. Revisions starts at 0 and are incremented each time you update your Module. Revisions are immutable, and once created cannot be edited or deleted.

View your Module

You can confirm that your Module was published in the Modules tab of the Software Catalog.

The Modules tab of the Software Catalog.

Edit a Module

You can edit a Module by publishing a new version of the Module YAML file. To download the Module YAML file, navigate to the Module overview page and select Edit module from the Actions dropdown.

The Actions dropdown is expanded and the Edit module option is highlighted.

This will open a dialog where you can select Download module definition.

The Edit module definition dialog.

You can edit the Module YAML file and publish it to Apollo using the Apollo CLI.

Once the new version of the Module is published you can view it in the version selector next to the Module name.

The Module version selector is expanded.

You can also view the version of each Module installation in the Module installations table.

The Module installations table.

Note that Module versions are immutable. In addition, when a new version of a Module is published, Apollo will attempt to update existing Module installations to the latest version of the Module by proposing a change request.

When creating a new version of a Module, you should consider how the changes will impact existing installations of the Module. The following sections outline best practices for evolving Modules.

Evolving a Module: adding a new variable

If you introduce a new Module variable, you should provide a defaultValue so that all existing installations of your Module can be seamlessly updated to the new version.

If you do not supply a defaultValue, the Module update will be blocked until users enter a value for this variable.

View the reason that a Module update is blocked and resolve the blocked update.

Evolving a Module: deleting a variable

To delete a variable, you must ensure it is not used anywhere in the definition of the Module. In the example below, the enableFeatureFlag variable cannot be deleted because it is still referenced in config overrides.

Copied!
1 2 3 2.0.0: overrides: my-feature-flag: {{ moduleVariable.enableFeatureFlag }}

One way you can eliminate the reference is by replacing it with a hard-coded value, such as true. When existing installations are updated to the new version of your Module, whatever value had previously been chosen for the enableFeatureFlag variable will be overwritten to true.

Copied!
1 2 3 2.0.0: overrides: my-feature-flag: true

Another way to eliminate this reference is to delete the reference entirely:

Copied!
1 2 2.0.0: overrides: {}

Finally, you can replace it by referencing a different variable - as long as this other variable is defined in the Module definition.

Copied!
1 2 3 2.0.0: overrides: my-feature-flag: {{ moduleVariable.enableNewFeatures }}

After you remove all references to the variable, you can delete the variable itself from the Module definition.

Evolving a Module: renaming a variable

There is no way to rename a variable while preserving all the values that were chosen by existing Module installations. This is because Apollo cannot differentiate between a change intended to rename one variable in a Module definition from a change intended to delete one variable and create a new one.

Evolving a Module: uninstalling an Entity

If you want Apollo to uninstall a specific Entity from every installation of your Module, you must explicitly signal this to Apollo using the markedForUninstallation field (see example below).

Copied!
1 2 3 4 5 6 7 8 9 name: control-plane-module displayName: Control Plane Module description: Entities required for the application control plane. entities: - type: helmChart helmChart: productId: com.palantir.example:deprecated-application k8sNamespace: app-namespace markedForUninstallation: {}

Once Module installations are updated to this version of your Module, Apollo will uninstall the Entity (subject to dependency constraints).

You can choose to uninstall a Product only after it has upgraded to some version, for example, when it has finished a migration or offloaded some responsibility to another service. To do this, you can specify a minVersion at which the Entity will become eligible for uninstallation.

Copied!
1 2 3 4 5 6 7 8 9 10 name: control-plane-module displayName: Control Plane Module description: Entities required for the application control plane. entities: - type: helmChart helmChart: productId: com.palantir.example:deprecated-application k8sNamespace: app-namespace markedForUninstallation: minVersion: 1.45.0

If you remove an Entity from a Module definition without specifying the markedForUninstallation field then existing installations of the Entity will remain installed but will no longer be managed by this Module. This can be useful if you want to seamlessly transfer the responsibility for managing a particular Entity from one Module to another. The original Module can stop managing the Entity, allowing the new Module to take over and start managing the Entity.

Managing config overrides with Modules

Modules provide a way to manage config overrides for Entities in Apollo across multiple Environments. When you define an Entity in a Module, you can specify config overrides for the Entity in the configOverrides field. You can use variables to add flexibility to the config overrides of an Entity. The example below shows the config overrides for an Entity in a Module that defines a variable enableFeatureFlag:

Copied!
1 2 3 2.0.0: overrides: my-feature-flag: {{ moduleVariable.enableFeatureFlag }}

When installing the Module, you will be prompted to provide a value for the variable. You can also decide to use the default if specified in the Module definition.

By default, Apollo will overwrite existing config overrides for an Entity when installing or updating a Module installation. This allows you to reduce config overrides divergence across Environments where the Module is installed. You should use variables to handle cases where specific values in the config overrides are expected to be different across Environments.

You can opt out of this default behaviour for a specific Entity by disabling config overrides syncing by setting syncConfigOverrides to DISABLED in the Module definition. In this case, Apollo will still add the config overrides specified in the definition when adding a new Entity, but will respect existing config overrides when updating an Entity.

Delete a Module

You can only delete a Module if there are no remaining installations of the Module. You must unlink the Module from all installations before you can delete it.

To delete a Module, you can navigate to the Module page and select Delete module from the Actions dropdown.

The delete Module selection.

This will remove the Module from the Software Catalog.