• Home
  • Manage
  • Configuration as Code
  • Manage configurations
  • Project folder

Manage Configuration as Code project

A project is a folder containing specially named sub-folders representing APIs. The API folders contain another layer of folders defining configurations. The configuration folders contain YAML files specifying what gets deployed.

APIs

To list all supported APIs and folder names, see Configuration types and token permissions.

Configurations

A configuration consists of two parts:

  • YAML file defining parameters, dependencies, name, and template
  • JSON template file

Configuration YAML file

The configuration YAML file contains basic information about the configuration to deploy. This includes the name of the configuration, the location of the template file, and the parameters usable in the template file. Parameters can be overwritten based on what group or environment is currently deployed.

For details on configuration syntax, see YAML configuration.

JSON template file

The JSON template contains the payload that will be uploaded to the Dynatrace API endpoints. It allows you to reference all defined parameters of the configuration via {{ .[PARAMETER_NAME] }} syntax. For example:

json
{ "name": "{{ .name }}", "type": "{{ .type }}" }

config.yaml

yaml
configs: - id: sample config: name: "Sample" parameters: type: "simple"

As you can see, it's also possible to reference the name of a configuration.

Note: The Dynatrace Configuration as Code CLI uses GO templates, which, in theory, allow you to define more complex templates, but we highly recommend that you keep templates as simple as possible. Referencing variables via {{ .[PARAMETER_NAME] }} should be sufficient.

For details on GO templates, see the GO template documentation.

Important additional information

The json files that can be uploaded with this tool are the JSON objects that the respective Dynatrace APIs accept/return. Adding a new configuration is generally done via the Dynatrace web UI unless you know the configuration JSON structures well enough to prefer writing them. Configurations can then be downloaded via the respective GET endpoint defined in the Dynatrace Configuration API, and should be cleaned up for auto-deployment.

A checked-in configuration should not include:

  • The entity's id but only its name. The entity can be created or updated if one of the same name exists. The name must be defined as a variable.
  • Hardcoded values for environment information such as references to other auto-deployed entities, tags, and management zones. These should all be referenced as variables as described below.
  • Empty/null values that are optional for the creation of an object. Most API GET endpoints return more data than is needed to create an object. Many of those fields are empty or null and can be omitted (for example, tileFilters on dashboards).

Dashboard JSON

When you create a dashboard in the Dynatrace web UI, it's private by default. All the dashboards defined via Configuration as Code need to be shared publicly with other users; otherwise, only the owner of the API token used to deploy can view them. You can change this in the dashboard settings or by just changing your checked-in json file. We recommend the following values for the dashboardMetadata:

json
"dashboardMetadata": { "name": "{{ .name }}", "shared": true, "sharingDetails": { "linkShared": true, "published": true }, "dashboardFilter": { "timeframe": "", "managementZone": { "id": "{{ .managementZoneId }}", "name": "{{ .managementZoneName }}" } } }

This configuration does the following:

  • References the name of the dashboard as a variable
  • Shares the dashboard with other users
  • Sets a management zone filter on the entire dashboard, again as a variable, most likely referenced from another config
    • Filtering the whole dashboard by management zone ensures that only data that is meant to be displayed is picked up by dashboard tiles, and it eliminates the possible need to define filters for individual tiles.

Note:

  • Dynatrace version 1.208+ A dashboard configuration must have a property owner. The property owner in dashboardMetadata is mandatory and must contain a non-null value.
  • Dynatrace version 1.208+ The property sharingDetails in dashboardMetadata is no longer present.

Calculated log metrics JSON

There is a known drawback to Dynatrace Configuration as Code's workaround to the slightly off-standard API for Calculated Log Metrics, which requires you to follow specific naming conventions for your configuration: when you create custom log metrics, your configuration's name must be the metricKey of the log metric.

Additionally, a configuration upload might fail when a metric configuration is newly created, and an additional configuration depends on the new log metric. To work around this, set both metricKey and displayName to the same value.

You will thus need to reference at least the metricKey of the log metric as {{ .name }} in the JSON file, as you can see below:

yaml
... some-log-metric-config: - name: "cal.log:this-is-some-metric"

And in the corresponding JSON:

json
{ "metricKey": "{{ .name }}", "active": true, "displayName": "{{ .name }}", ... }

Conditional naming JSON

Because there is no name parameter in the Dynatrace Conditional naming API, you should map {{ .name }} to displayName. For example:

json
{ "type": "PROCESS_GROUP", "nameFormat": "Test naming PG for {Host:DetectedName}", "displayName": "{{ .name }}", ... }

This also applies to the HOST type:

json
{ "type": "HOST", "nameFormat": "Test - {Host:DetectedName}", "displayName": "{{ .name }}", ... }

And it applies to the SERVICE type:

json
{ "type": "SERVICE", "nameFormat": "{ProcessGroup:KubernetesNamespace} - {Service:DetectedName}", "displayName": "{{ .name }}", ... }

Settings JSON

Because the payload of the Settings API contains several properties that do not directly relate to the schema and may need to be set by Dynatrace Configuration as Code, the JSON templates for settings should only include the actual configuration value.

For example, while the API response for auto-tagging (builtin:tags.auto-tagging) is:

json
{ "items": [ { "objectId": "vu9U3hXafawfawfawABnRlbmFudAAkZmY0ZTQxZDUtYmM2Yi0zMmFlLThhYmMtNDg3NTFiNWRkMWVhvu9U3hXa3q0", "value": { "name": "Application Tag", "rules": [ { "enabled": true, "valueNormalization": "Leave text as-is", "type": "ME", "attributeRule": { "entityType": "APPLICATION", "conditions": [ { "key": "WEB_APPLICATION_NAME", "operator": "CONTAINS", "stringValue": "My App Name", "caseSensitive": true } ] } } ] } } ], "totalCount": 1, "pageSize": 100 }

Your Configuration as Code template should be limited to the content of value:

json
{ "name": "Application Tag", "rules": [ { "enabled": true, "valueNormalization": "Leave text as-is", "type": "ME", "attributeRule": { "entityType": "APPLICATION", "conditions": [ { "key": "WEB_APPLICATION_NAME", "operator": "CONTAINS", "stringValue": "My App Name", "caseSensitive": true } ] } } ] }

When using the download command, this happens automatically.