Environments
Your flows and load tests need a base URL and usually a credential. This page explains where those values live, how a secret gets from your CI platform into a run, and why the pipeline is not allowed to guess which environment you meant.
Two different things are called an environment
This word is overloaded, and mixing the two up is the single most common source of confusion when wiring atra into a pipeline. They are separate systems and neither knows about the other.
An Atrahasis environment
A named set of variables that belongs to a flow group or spec group, stored in environments.json next to the flows. You create it in the app and select it at run time with -e. This is what fills in {{base_url}} in a request.
A CI platform environment
Your platform's own feature for scoping secrets and approvals: GitHub Environments, a Jenkins credential scope, a GitLab environment. It decides which secrets a job can read. It has no idea that atra exists.
staging does not make atra pick the Atrahasis environment named staging. Nothing is inferred from the branch, the job name or the platform either. If you do not pass -e, no environment is loaded at all.What an environment holds
You build environments in Atrahasis, not in a text editor. The app saves them into the group folder as environments.json, you commit that folder, and atra reads it back on the runner. There is nothing to hand-write and nothing to keep in sync.
Environments are scoped to their group. Each flow group and each spec group carries its own set, so a flow group's dev is unrelated to a spec group's dev.
What you set on a variable
Four settings decide where a value comes from at run time. Only the last two matter for CI, and they are the ones people miss.
| Setting | What it does |
|---|---|
| Key | The placeholder name. A key of base_url replaces {{base_url}} in URLs, headers, bodies, query and path parameters, and auth config. |
| Enabled | Turn a variable off and it is skipped entirely, as though it were not there. |
| Secret | Keeps the value out of the committed folder. On its own it does nothing; it is the pair with Source that sends atra looking outside the repository. |
| Source | Where the value comes from. Manual keeps it with the variable, OS reads it from an environment variable, Vault fetches it from HashiCorp Vault. |
The bridge: getting a CI secret into a run
One rule, and it is the whole thing
When a variable is marked as a secret with its source set to OS, atra reads it from an operating system environment variable whose name is exactly the key. A key of base_url looks for an environment variable called base_url. Nothing is uppercased, prefixed or otherwise transformed.
os, then commit. The real value never enters the repository.-e. It resolves the variable from the environment it was handed.The same bridge on each platform
The secret store differs, the requirement does not: an environment variable named base_url has to exist when atra runs.
GitHub Actions
env:
base_url: ${{ secrets.BASE_URL }}Jenkins
environment {
base_url = credentials('atrahasis-base-url')
}A plain shell, and therefore anywhere else
export base_url="https://api.example.com"
base_url is not satisfied by an environment variable called BASE_URL. Copy the key from the app exactly as it appears.What happens when a secret is missing
atra checks for every secret it will need before it sends a single request, and lists all of them at once. You get one clear failure instead of a confusing 401 halfway through a flow, and you can fix every missing variable in one go rather than re-running after each one.
Environment 'dev' has secret variables that are not set in your shell: export base_url=<value> export api_key=<value> Set them before running the command.
The hint is printed in the syntax of the machine it ran on, so a Windows agent shows $env:base_url = "<value>" instead. Seeing this in a build log almost always means step 3 above was skipped, or the name does not match the key.
And when you forget -e entirely
Without -e no environment is loaded, so nothing fills the placeholders. Rather than firing requests at a URL containing a literal {{base_url}}, atra stops and names what it could not resolve.
Unresolved variable(s) '{{base_url}}' in flow 'logout'
Hint: Use --env (-e) to select an environment from environments.jsonSelecting an environment
Pass the environment name with -e or --env. Matching is case-insensitive, so -e Dev finds dev.
# A flow, with the dev environment
atra run -f logout -e dev
# A load test, with the staging environment
atra run -s logout -t load -e staging
# A different group folder, named as the first argument
atra run checkout-flows -f signup -e qa
In a pipeline the environment name is usually the one thing worth making a parameter, so the same job can be pointed at staging or production without editing the file.
environments.json at all, because there is no group folder involved. Substitute values with your shell instead, as in atra GET $base_url/health. The shell expands it before atra ever sees the argument, which is why that works on every platform.Pulling values from Vault instead
A variable whose source is Vault is fetched from HashiCorp Vault at run time. Instead of the value itself, the pipeline supplies credentials for the connection, in an environment variable named after it: VAULT_AUTH_<CONNECTION>.
# Token auth export VAULT_AUTH_MYCONNECTION="<token>@https://vault.example.com" # Username and password export VAULT_AUTH_MYCONNECTION="<username>:<password>@https://vault.example.com"
These are checked up front too. If a connection has no credentials, atra names the connection and prints the exact variable to set before any traffic is sent. One CI secret then covers every variable that connection serves.
Full Vault reference →Checklist before you debug anything else
| Symptom | Almost always |
|---|---|
| Secret variables are not set in your shell | The pipeline never exposed the secret as an environment variable, or used a different name from the key. |
| Unresolved variable(s) | -e is missing, or the variable is not in the environment you selected, or it is there but switched off. |
| Environment not found | The name passed to -e does not exist in this group. Remember each group has its own file. |
| Requests go to the wrong host | The variable is not marked as a secret, so the literal value committed in the file won over the environment variable you set. |