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.

There is no automatic mapping between them. Deploying to a GitHub environment named 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.

SettingWhat it does
KeyThe placeholder name. A key of base_url replaces {{base_url}} in URLs, headers, bodies, query and path parameters, and auth config.
EnabledTurn a variable off and it is skipped entirely, as though it were not there.
SecretKeeps 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.
SourceWhere the value comes from. Manual keeps it with the variable, OS reads it from an environment variable, Vault fetches it from HashiCorp Vault.
Secret and OS travel together. A variable is only read from the environment when it is marked as a secret and its source is OS. Set the source to OS but leave Secret off, and the value saved with the variable wins, which is the quiet way to end up testing the wrong host.

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.

1In the app, mark the variable as a secret with source os, then commit. The real value never enters the repository.
2Store the value in your CI platform's secret store, under whatever name that platform prefers.
3In the pipeline, expose that secret as an environment variable named the same as the key. This is the step people forget.
4Run atra with -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"
Case matters. Environment variable names are case-sensitive on Linux and macOS runners, which is what nearly all CI runs on. A key of 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.json

Selecting 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.

Single requests do not use 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

SymptomAlmost always
Secret variables are not set in your shellThe 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 foundThe name passed to -e does not exist in this group. Remember each group has its own file.
Requests go to the wrong hostThe variable is not marked as a secret, so the literal value committed in the file won over the environment variable you set.