create-config-field
DataDog/datadog-agent/.agents/skills/create-config-field/SKILL.md
Add a new configuration field to the Datadog Agent (datadog.yaml) by declaring it in the config schema
Skill3.8k starsChanged 2 days ago
What's in it
- Where settings live
- Instructions
- Step 1: Gather information from the user
- Step 2: Check the setting does not already exist
- Step 3: Add the node to the schema
- Step 4: Lint and preview
- Keyword quick reference
- Tags
- Reading the setting from Go
- Related
- Usage
Tools it asks for
- Bash
- Read
- Write
- Edit
- Glob
- Grep
- AskUserQuestion
---
name: create-config-field
description: Add a new configuration field to the Datadog Agent (datadog.yaml) by declaring it in the config schema
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
argument-hint: "[config.key.name]"
model: sonnet
---
Add a new configuration setting to a Datadog Agent config file by declaring it in
the **configuration schema**.
The schema is the single source of truth for every Agent setting: its type,
default, documentation, environment variables, validation rules and visibility
all live in one YAML node. Do **not** add `BindEnvAndSetDefault` calls by hand —
the `pkg/config/setup/*_settings.go` files are generated from the schema, and so
are `datadog.yaml.example` / `system-probe.yaml.example`, the JSON Schema
published to SchemaStore, and the runtime config validation.
Consult these references only when the instructions below do not provide enough detail for the current task:
- For guidance on adding, documenting, or publishing settings, read the [settings how-to](../../../doc/how-to/agent-schema/settings.md).
- For unfamiliar keywords or validation rules, read the [keyword reference](../../../doc/reference/agent-schema/keywords.md).
- For complex nested settings or the distinction between sections and object values, read the [annotated examples](../../../doc/architecture/agent-schema/examples.md).
- For command arguments, read the [CLI reference](../../../doc/reference/agent-schema/cli.md).
- For schema terminology and design rationale, read the [schema overview](../../../doc/architecture/agent-schema/index.md).
## Where settings live
One schema per config file, all under `pkg/config/schema/yaml/`:
| Config file | Schema | `--schema` value |
|---|---|---|
| `datadog.yaml` | `pkg/config/schema/yaml/core_schema.yaml` | `core` (default) |
| `system-probe.yaml` | `pkg/config/schema/yaml/system-probe_schema.yaml` | `system-probe` |
Large top-level sections are **split into sibling files** referenced via `$ref`,
so the node for `apm_config.enabled` lives in `apm_config.yaml`, not in
`core_schema.yaml`.
Never grep for the file by hand — `dda inv -- schema.locate` resolves the `$ref`
for you (see Step 2).
## Instructions
### Step 1: Gather information from the user
Use `AskUserQuestion` to collect the following. If `$ARGUMENTS` provides the
setting path, skip that question.
1. **Target schema**: `datadog.yaml` (core) or `system-probe.yaml`?
2. **Setting path** (dot-separated, e.g. `my_feature.enabled`).
3. **Type**: `boolean`, `string`, `number`, `integer`, `array`, or `object`. For `array`, also the element type
(`items.type` is mandatory).
4. **Default**: a single `default`, or per-platform `platform_default`.
5. **Visibility**: `public` (appears in the generated `*.yaml.example` and public docs) or undocumented (the default —
internal, no keyword emitted).
6. **Description**: mandatory for `public`, strongly encouraged otherwise. Written for **users**, not Agent developers.
This should explain what the settings does and how to use it.
7. **Description for each ancestor section**: if a setting is public, each parent section must be public too with their
own description. Ask for a **description per section newly made public**, separately from the setting's. Never reuse
or copy the setting's description into its parent section — a section describes what the group of settings is *for*,
a setting describes its own value.
8. **Comment**: an optional description aimed at developers.
### Step 2: Check the setting does not already exist
```bash
dda inv -- schema.locate my_feature.enabled # exact path
dda inv -- schema.locate '.*my_feature' # pattern (regex/glob)
```
This also tells you which file to edit. See the `locate-config-setting` skill for
the full flag set.
### Step 3: Add the node to the schema
Preferred — the interactive wizard, which routes split sections to the right
sub-file, preserves the file's hand-curated ordering, makes ancestor sections
public when needed, and lints at the end:
```bash
dda inv schema.add-setting # core schema
dda inv schema.add-setting --schema=system-probe # system-probe schema
```
The wizard is interactive (it reads from stdin), so when you cannot drive a TTY,
edit the YAML directly instead. Read a neighbouring node first and match its
style:
```yaml
my_feature:
node_type: section
type: object
visibility: public
description: Configuration for my feature.
properties:
enabled:
node_type: setting
type: boolean
default: false
description: Enables my feature.
visibility: public
```
Rules that the linter enforces:
- Every node needs `node_type: section` or `node_type: setting`.
- Every setting and section name must be snake_case (lowercase letters and
digits, in words separated by single underscores).
- Every setting needs a `type` and exactly one of `default` / `platform_default`.
- `platform_default` must cover every platform — list `linux`, `windows`,
`darwin`, `aix` explicitly, or add an `other` catch-all. `container` /
`fargate` are optional and fall back to `linux` then `other`.
- An `array` setting must declare `items.type`.
- A `public` node needs a non-empty `description`, **and every ancestor section
must also be `public` with a description** — its own description, gathered in
Step 1, not a copy of the child setting's.
- A section needs at least one child; a public section needs at least one direct
public child.
- Set `node_type: setting` — not `section` — when the value *is* an object
(e.g. `docker_labels_as_tags`: `type: object`, `default: {}`). A section is only
for grouping child settings.
**Placement matters**: the generated config examples follow schema order, so
insert the node where it belongs logically, not at the end of the file.
### Step 4: Lint and preview
```bash
dda inv schema.lint
```
If the change requires generated Go code or a configuration-example preview, consult the relevant workflow for [regenerating Go code](../../../doc/how-to/agent-schema/workflows.md#validate-changes-and-regenerate-go-code) or [generating configuration examples](../../../doc/how-to/agent-schema/workflows.md#generate-configuration-examples).
## Keyword quick reference
Full up-to-date details in `doc/reference/agent-schema/keywords.md`.
| Keyword | Where | Notes |
|---|---|---|
| `node_type` | all | `section` or `setting`. Mandatory. |
| `type` | setting | `boolean`, `number`, `integer`, `string`, `array`, `object`. |
| `default` | setting | Must match `type`. Mutually exclusive with `platform_default`. |
| `platform_default` | setting | Keys: `linux`, `windows`, `darwin`, `aix`, `container`, `fargate`, `other`. |
| `description` | all | Mandatory when `public`. Use the `\|` block scalar for multi-line. |
| `visibility` | all | `public` or `undocumented` (default). |
| `env_vars` | setting | Overrides the derived `DD_*` name; first match wins. |
| `env_parser` | setting | `comma_separated`, `space_separated`, `json`. Needed for complex types. |
| `sensitive` | setting | Scrubs the value from logs, flare and Fleet Automation. |
| `items` | setting | Mandatory for `array`. |
| `properties` | section / object setting | Child settings on a section; value sub-schema on an object setting. |
| `title` | section | Banner heading in the generated example. |
| `comment` | all | Developer-only note; never rendered to users. |
| `example` | setting | Overrides the value shown on the rendered example line. |
| `tags` | all | See below. |
**Relative defaults**: use `${conf_path}`, `${install_path}`, `${log_path}`,
`${run_path}` with `/` separators rather than hardcoding per-OS paths — e.g.
`default: "${conf_path}/conf.d"`. Valid in `default` and `platform_default`.
### Tags
Three are usable for new settings:
- `template_section:<name>` — selects which config-example flavors include the
setting. Omit it and the setting renders in every build type.
- `platform_only:<os>[,<os>]` — restricts the setting to the listed OSes
(`windows`, `linux`, `darwin`); it is dropped from the examples generated for
any other `--os-target`.
- `generate_const:<Name>` — emits a Go constant `<Name>` in `pkg/config/setup`
holding this setting's default. Use it instead of hardcoding a default (port,
timeout, path) in Go code, so the two can never drift.
`golang_type:*`, `no-env` and the legacy `env_parser` values
(`comma_and_space_separated`, `traces_span`, `csv_comma_separated`,
`comma_then_space_separated`, `json_list_or_*`) exist only to support existing
settings — do not use them for new ones.
## Reading the setting from Go
```go
pkgconfigsetup.Datadog().GetBool("my_feature.enabled")
pkgconfigsetup.SystemProbe().GetInt("system_probe_config.max_conns")
```
In components, prefer the injected `config.Component` over the global accessor.
## Related
- `locate-config-setting` — find where an existing setting is defined.
- `create-release-note` — a user-visible new setting needs a reno note.
## Usage
- `/create-config-field` — interactive: prompts for all details
- `/create-config-field my_feature.enabled` — pre-fills the setting path
More agent context in DataDog/datadog-agent
42 other files this repository gives its agents.
CLAUDE.md
Cursor rule
Skill
- agent-supply-chain-newsletter.agents/skills/agent-supply-chain-newsletter/SKILL.md
- allium.agents/skills/allium/SKILL.md
- auto-jira.agents/skills/auto-jira/SKILL.md
- create-component.agents/skills/create-component/SKILL.md
- create-core-check.agents/skills/create-core-check/SKILL.md
- create-epic-recap.agents/skills/create-epic-recap/SKILL.md
- create-go-module.agents/skills/create-go-module/SKILL.md
- create-invoke-task.agents/skills/create-invoke-task/SKILL.md
- create-pr.agents/skills/create-pr/SKILL.md
- create-release-note.agents/skills/create-release-note/SKILL.md
- create-runtime-setting.agents/skills/create-runtime-setting/SKILL.md
- create-status-provider.agents/skills/create-status-provider/SKILL.md
- create-subcommand.agents/skills/create-subcommand/SKILL.md
- cws-btfhub-sync.agents/skills/cws-btfhub-sync/SKILL.md
- cws-iouring-coverage.agents/skills/cws-iouring-coverage/SKILL.md
- e2e-audit.agents/skills/e2e-audit/SKILL.md
- explain-lading-config.agents/skills/explain-lading-config/SKILL.md
- follow-pr.agents/skills/follow-pr/SKILL.md
- gpu-live-metric-validation.agents/skills/gpu-live-metric-validation/SKILL.md
- handle-pr-ci-failure.agents/skills/handle-pr-ci-failure/SKILL.md
- injector-dev.agents/skills/injector-dev/SKILL.md
- locate-config-setting.agents/skills/locate-config-setting/SKILL.md
- quality-gate-size-analysis.agents/skills/quality-gate-size-analysis/SKILL.md
- review-pr-comments.agents/skills/review-pr-comments/SKILL.md
- run-e2e.agents/skills/run-e2e/SKILL.md
- run-jira.agents/skills/run-jira/SKILL.md
- run-windows-e2e.agents/skills/run-windows-e2e/SKILL.md
- triage-ci-failure.agents/skills/triage-ci-failure/SKILL.md
- update-3rd-party-libs.agents/skills/update-3rd-party-libs/SKILL.md
- update-otel-deps.agents/skills/update-otel-deps/SKILL.md
- write-e2e.agents/skills/write-e2e/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

