Create build configuration templates for DRY build configs, package build steps as reusable meta-runners, and store all TeamCity project configuration as Kotlin DSL in VCS
A build configuration template is a reusable "blueprint" for build configurations. When 10 microservices all need the same Maven build steps, failure conditions, and notification rules, define them once in a template — changes propagate automatically to all 10 configs.
| Without templates | With templates |
|---|---|
| Copy config A to make B, C, D… | Create template T; apply to A, B, C, D |
| Change failure condition → update 10 configs | Change failure condition in template → all 10 updated automatically |
| New service needs build → copy + manually update | New service → apply template + fill in service-specific parameters |
| Risk of configs drifting apart | Core settings locked in template; drift is explicit overrides |
Templates can define: build steps, triggers, failure conditions, artifact paths, agent requirements, build features, and parameters. Build configurations that use the template inherit all of these, with the option to override or extend each section.
Maven Java Microservice CI).%param.name% for values that will vary per service (e.g., service name, Maven module path).Template parameters are placeholders that each build config fills in differently. Define them in the template with either a default value or a required-without-default specification.
# Template parameters (defined in the template itself):
service.name = (empty, required — each config must provide this)
maven.module.path = . (default: root; override for multi-module)
maven.test.profile = unit (default: can override per config)
deploy.environment = staging (default: override for prod configs)
# In template build steps:
# Maven Goals:
# -pl %maven.module.path% clean verify -P%maven.test.profile%
# Artifact paths:
# %maven.module.path%/target/%service.name%-*.jar
If a template parameter has no default value, each build config that uses the template must provide it. In the TeamCity UI, the build config's Parameters page shows a red warning for missing required template parameters. Builds cannot be started until all required parameters are set.
| Section | Override behaviour |
|---|---|
| Build steps | Config can add steps before/after template steps. Cannot modify/remove template steps (they're locked unless "allow override" is checked per step). |
| Parameters | Config can override any template parameter value. Template parameter values are the default; config values win. |
| Triggers | Config can add additional triggers. Cannot remove template triggers unless template explicitly allows it. |
| Failure conditions | Config can add additional failure conditions. Template conditions cannot be removed. |
| Artifact paths | Config can add to the template's artifact paths (appended). |
| Agent requirements | Config can add additional requirements. Template requirements cannot be removed. |
Build steps inherited from a template appear greyed out in the build config's steps list. You cannot edit them from the config. To allow a specific step to be overridden, open the step in the template and check "Allow override in build configuration." Then the config can provide different settings for that step while still receiving template updates for locked steps.
To remove a build config from a template: Administration → <Config> → General Settings → Based on template → (none). The config retains a copy of all template settings at the time of detachment, but future template changes no longer propagate to it.
Use detach when: a service has diverged significantly from the standard build, or you're migrating away from an old template to a new one.
A meta-runner packages one or more build steps as a reusable custom runner type. Once created, it appears in the runner type dropdown alongside Maven, Gradle, etc. It's the best way to encapsulate a complex multi-command deploy procedure so teams can add it with two clicks.
Deploy to Kubernetes) and give it an ID.<Data Dir>/config/projects/<ProjectId>/pluginData/metaRunners/.In any build config in the same project (or subproject): Add build step → select your custom runner from the list → fill in the exposed parameters.
Meta-runners are stored as XML files in the project's data directory. They can be version-controlled (committed to your config repo) and shared across TeamCity instances by copying the XML files.
Versioned settings synchronise all TeamCity project configuration (projects, build configs, templates, parameters, VCS roots) to/from a Git repository. Configuration is stored as Kotlin DSL — type-safe, IDE-friendly, and reviewable in GitHub pull requests.
// .teamcity/settings.kts
import jetbrains.buildServer.configs.kotlin.v2019_2.*
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.maven
project {
buildType(Build)
buildType(Test)
}
object Build : BuildType({
name = "Build"
vcs { root(MyRepo) }
steps {
maven {
goals = "clean package -DskipTests"
mavenVersion = defaultProvidedVersion()
}
}
triggers {
vcs { branchFilter = "+:refs/heads/*" }
}
artifactRules = "target/*.jar => artifacts"
})
Once Versioned Settings is enabled, TeamCity applies config changes from VCS commits. If you also make changes via the UI, they may be overwritten on the next VCS sync. Decide on ONE source of truth: either UI (with versioned settings as a read-only backup) or Kotlin DSL (UI becomes read-only for synced settings). TeamCity warns when UI changes conflict with VCS changes.