Solution Variables
Variables allow solutions to have environment-specific configuration without modifying the underlying actions or sequences.
What Are Variables?
Section titled βWhat Are Variables?βVariables are placeholders in your solution that can have different values per environment:
| Variable | Development | Staging | Production |
|---|---|---|---|
database_host | dev-db.local | staging-db.company.com | prod-db.company.com |
log_level | debug | info | warn |
replica_count | 1 | 2 | 5 |
How a Variable Is Stored
Section titled βHow a Variable Is StoredβThere is no Variables tab or template editor on the solution page. A variable is a
row authored in the Variable Sets UI (or through the variables API); the set is then
linked to a solution with POST /api/v1/solutions/{solution_id}/variable-sets.
scope_solution_id is a read-only column that no request accepts. These are its
properties:
| Property | Column | Required |
|---|---|---|
| Name | name | Yes |
| Description | description | No |
| Type | variable_type | Yes |
| Value | value / value_encrypted | No |
| Prompted | is_prompted | Yes |
| Prompt label | prompt_label | No |
| Prompt description | prompt_description | No |
| Prompt control type | prompt_control_type (defaults text) | No |
| Prompt required | prompt_required | Yes |
| Select options | prompt_select_options | No |
variable_type is one of string, sensitive, certificate or execution_pool.
Prompt Control Types
Section titled βPrompt Control Typesβprompt_control_type sets how a prompt is presented where Lens asks for its answer: the
deployment wizardβs Config step and the schedule form. The database constrains it to the
five values below (chk_prompt_control), and it defaults to text.
Single-line text input:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Database Hostname ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β db.example.com β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ Enter the primary database server address ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββUse for: Hostnames, URLs, paths, simple values
Multiline
Section titled βMultilineβMulti-line text area:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Configuration JSON ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β { β ββ β "feature_flags": { β ββ β "new_checkout": true β ββ β } β ββ β } β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ JSON configuration for the application ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββUse for: JSON, YAML, configuration files, scripts
Dropdown selection:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Log Level ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β info βΌ β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β’ debug ββ β’ info ββ β’ warn ββ β’ error ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββUse for: Predefined options, log levels, regions
Checkbox
Section titled βCheckboxβBoolean toggle:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Enable Debug Mode ββ βββββ ββ β β β Enable ββ βββββ ββ Turn on detailed logging for troubleshooting ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββUse for: Feature flags, on/off settings
Sensitive
Section titled βSensitiveβMasked input for secrets:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ API Key ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ API key for external service integration ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββUse for: Passwords, API keys, tokens, secrets
Answering Prompts
Section titled βAnswering PromptsβEvery path that deploys a solution answers its prompted variables. One that leaves a required prompt unanswered is refused before anything runs or is recorded.
| Path | Where the answers come from |
|---|---|
| Create deployment | The requestβs prompted_values |
| Redeploy | The requestβs prompted_values, else the answers the source deployment recorded |
| Promotion | The answers the source deployment recorded |
| Schedule | The scheduleβs deployment_config.variables, checked on save and again each run |
| Failure handler | None, so a solution with required prompts cannot be a failure handler |
Every deployment records the answers it ran with, which is what a redeploy or promotion of it carries: never a value its plan resolved for the same name. A scheduleβs answers to sensitive prompts are sealed with its other sensitive overrides. A scheduled run that a changed prompt leaves unanswered is skipped, and the schedule stays due. A schedule applied from a config repository is checked when it runs.
Creating Variables
Section titled βCreating VariablesβWhere variables are authored
Section titled βWhere variables are authoredβAuthor variables in the Variable Sets UI (or via the variables API), then link the
set to the solution with POST /api/v1/solutions/{solution_id}/variable-sets β see
How a Variable Is Stored above.
Setting Environment Values
Section titled βSetting Environment ValuesβPer-Environment Configuration
Section titled βPer-Environment ConfigurationβPer-environment values are set on the variable itself, by giving it a
scope_environment_id (there is no βConfigure Variablesβ button on the
environment page). Create one variable per environment value, or use a
variable set scoped to both the solution and the environment.
Using Variables in Actions
Section titled βUsing Variables in ActionsβResolved variables reach an action in two ways during deployment:
#{...}templates in command arguments, the working directory, declared environment variable values, and a scriptβs file name and content.MANTIS_*environment variables injected into the executed process, for each non-sensitive variable. Each resolved variable is exposed as an uppercased,MANTIS_-prefixed environment variable (for example,database_hostbecomesMANTIS_DATABASE_HOST).
Template Syntax
Section titled βTemplate Syntaxβ| Form | Renders |
|---|---|
#{database_host} | The variableβs value |
#{log_level | ToUpper} | The value through a filter; filters chain with | |
#{if Live}...#{else}...#{/if} | One branch; Live is false when empty, false, 0 or null |
#{if Count == 5}...#{/if} | Comparisons: == != < <= > >=, not and or |
#{each host in Hosts}...#{/each} | The body once per item of Hosts, a JSON array or a comma-separated list; #{host}, #{hostIndex}, #{hostFirst} and #{hostLast} inside |
#{calc Replicas * 2} | Arithmetic: + - * / %, negation, parentheses |
#{ | NowDateUtc} | A filter with no subject |
#{Mantis.Environment.Name} | A system variable (below) |
A bare reference to a variable the deployment does not define is left in the output as
written β note that #{Typo} left standing at a word boundary is read by a shell as a #
comment, so a misspelled reference can silently truncate a command. An undefined variable in
a condition, a loop or a filtered reference fails the step,
as does a template that does not parse; the error names the field.
A sensitive variable is referenced bare, as #{DbPassword}: its value is filled in when
the command is delivered to the target, so it is never stored in plaintext with the queued
command, and only the actions that reference it receive it. It cannot take a filter or
appear in a condition, and a template that tries fails the step. Text that merely looks like
a reference β inside another variableβs value, for instance β is never filled in.
Write ##{ for a literal #{. The names if, else, each, in and calc are template
keywords and cannot be used as variable names.
Filters
Section titled βFiltersβFilter names are case-insensitive.
| Filter | Result |
|---|---|
ToLower, ToUpper, Trim | Case conversion; surrounding whitespace removed |
Truncate(10), Truncate(10, "...") | The first 10 characters, with the suffix if it was cut |
Substring(2), Substring(2, 5) | From position 2, optionally 5 characters long |
Replace("old", "new") | Every occurrence replaced |
PadLeft(8), PadRight(8, "0") | Padded to the width, with a space or the given character |
HtmlEscape, XmlEscape, JsonEscape, UrlEscape, MarkdownEscape | Escaped for that format |
ToBase64, FromBase64 | Base64 encoded or decoded |
Contains("x"), StartsWith("x"), EndsWith("x"), Match("regex") | true or false |
UriPart("host") | scheme, host, port, path, query or fragment of a URI |
VersionMajor, VersionMinor, VersionPatch, VersionPrerelease | That part of a semantic version |
FormatDate("%Y-%m-%d", "%d/%m/%Y") | A date re-formatted from the first format to the second |
NowDate, NowDateUtc, NowDateUtc("%Y-%m-%d") | The current local or UTC date and time |
System Variables
Section titled βSystem Variablesβ| Variable | Value |
|---|---|
Mantis.Deployment.Id | The deploymentβs id |
Mantis.Deployment.CreatedAt | When the deployment was planned, RFC 3339 |
Mantis.Environment.Id, Mantis.Environment.Name | The target environment, when the deployment names one |
Mantis.Tenant.Id, Mantis.Tenant.Name | The deploying tenant, for a tenant deployment |
Mantis.Solution.Id, Mantis.Solution.Name | The solution, for a solution deployment |
Mantis.Sequence.Id, Mantis.Sequence.Name | The sequence this step belongs to |
Mantis.Action.Id, Mantis.Action.Name | The action this step runs |
Mantis.Step.Number | The actionβs configured order within its sequence |
Mantis.Target.Id, Mantis.Target.Name | The target, for a step a target runs |
Mantis.Worker.Id | The Thorax instance, for a step that runs off-target |
A system variable that does not apply to a step is not defined for it.
In Command Payloads
Section titled βIn Command PayloadsβCommand payloads are structured (a binary plus ordered arguments), so reference variables inside individual arguments:
- Binary:
docker - Argument 1:
run - Argument 2:
--env - Argument 3:
DB_HOST=#{database_host} - Argument 4:
--env - Argument 5:
LOG_LEVEL=#{log_level | ToUpper} - Argument 6:
myapp
When using the DefaultShell executor (the default), arguments are passed
directly to the binary without any shell interpretation, so shell metacharacters
are treated as literal values. When using the Sh, Bash, Pwsh, or Zsh
executors, each argument is shell-quoted before the command line is composed β
POSIX single-quoting for Sh, Bash and Zsh, PowerShell single-quoting for Pwsh.
A metacharacter in a resolved variable is therefore made inert rather than
rejected, so a value containing ;, |, $ or a quote deploys as written and
still cannot chain, pipe or expand. Only the binary name is filtered for
metacharacters; an argument is refused for a null byte alone.
In Script Payloads
Section titled βIn Script PayloadsβA scriptβs content is a template like any other field, and its resolved variables are also
available as MANTIS_* environment variables:
#!/bin/bashecho "Connecting to $MANTIS_DATABASE_HOST"docker compose up -d --scale web="$MANTIS_REPLICA_COUNT"Variable Resolution
Section titled βVariable ResolutionβMantis resolves each variable by additive specificity: every variable with the key whose scopes all match the deployment context is a candidate, each scored by the sum of its scopesβ points, and the highest total wins. Solution scope is worth 40 points β well below tenant (200), environment (100) and target (500) β so a solution-level default is a low-priority fallback, not βlevel 1β.
| Scope | Points |
|---|---|
| Current action | 1000 |
| Current target | 500 |
| Tenant | 200 |
| Environment | 100 |
| Solution | 40 |
| Variable set | 20 |
| Global | 0 |
(The full 10-level table is in Tenant Variables.)
A variable whose scope does not match the context is discarded outright. If no candidate matches a required variable, the deployment errors; otherwise the highest-scoring match wins β when only a global or solution-scoped variable exists, that fallback value is what deploys.
Best Practices
Section titled βBest Practicesβ1. Use Descriptive Names
Section titled β1. Use Descriptive NamesβGood: database_primary_host, api_gateway_urlBad: db, host1, var12. Add Help Text
Section titled β2. Add Help TextβHelp operators understand what values to provide:
Variable: connection_stringHelp: PostgreSQL connection string in format: postgres://user:pass@host:5432/dbname3. Set Sensible Defaults
Section titled β3. Set Sensible DefaultsβProvide defaults for development/testing:
Variable: log_levelDefault: info(Production can override to "warn")4. Mark Secrets as Sensitive
Section titled β4. Mark Secrets as SensitiveβEncryption and log masking key off the variableβs type (variable_type = sensitive), not the control type. Set the variableβs type to sensitive
for:
- Passwords
- API keys
- Tokens
- Certificates
- Connection strings with credentials
5. Validate Early
Section titled β5. Validate EarlyβSet variables as required when they must have values:
Variable: database_hostRequired: true(Deployment fails if not set)Common Variable Patterns
Section titled βCommon Variable PatternsβDatabase Configuration
Section titled βDatabase Configurationβ| Variable | Control type | Example |
|---|---|---|
database_host | text | db.example.com |
database_port | text | 5432 |
database_name | text | myapp_production |
database_user | text | app_user |
database_password | sensitive | β’β’β’β’β’β’β’ |
Feature Flags
Section titled βFeature Flagsβ| Variable | Control type | Example |
|---|---|---|
feature_new_ui | checkbox | true |
feature_beta_api | checkbox | false |
feature_analytics | checkbox | true |
Scaling
Section titled βScalingβ| Variable | Control type | Example |
|---|---|---|
web_replicas | text | 3 |
worker_replicas | text | 2 |
max_connections | text | 100 |
Troubleshooting
Section titled βTroubleshootingβVariable Not Substituted
Section titled βVariable Not SubstitutedβSymptom: Seeing #{variable_name} in output
Solutions:
- Check variable is defined on solution
- Check environment has a value set
- Verify spelling matches exactly
Deployment Fails: Missing Required Variable
Section titled βDeployment Fails: Missing Required VariableβSymptom: Deployment fails with βMissing required prompted variables:
Solution: Answer the prompt where that path takes its answers (see Answering Prompts). A promotion takes the source deploymentβs answers, so redeploy the source with the answer first.
Sensitive Value Exposed in Logs
Section titled βSensitive Value Exposed in LogsβSymptom: Secret appears in deployment logs
Solution: Set the variableβs type to sensitive (variable_type = sensitive). Masking and encryption read variable_type, never the free-text
control type β setting the control type to βsensitiveβ does not mask or
encrypt the value.
Next Steps
Section titled βNext Stepsβ- Creating Solutions - Create new solutions
- Versioning - Version management
- Promotion Lifecycle - Environment progression
- Overview - Return to solutions overview
