Runner rules
Runner rules are attached to runners and define under which circumstances to use which runner.
Each environment must have exactly one runner linked to it as a result of the runner rules in order to perform a deployment into that environment.
The runner creates the link to the Terraform/OpenTofu state for that environment through its state storage configuration.

The environment remains linked to a runner even when the runner rules change until the refresh_runner API is called on the environment. This is because changing a runner may lead to dropping access to the previously used Terraform/OpenTofu state and thus a potentially undesired destruction of resources.
Basic example
Create an runner rule for the runner my-runner and the project my-project like this:
hctl create runner-rule --set=runner_id=my-runner --set=project_id=my-project
Manage runner rules
Manage runner rules using the hctl CLI:
# Create a runner rule
hctl create runner-rule --set=runner_id=my-runner --set=project_id=my-project
hctl get runner-rules # List all runner rules of your organization
hctl get runner-rule 1f8a1ecd-2b06-41de-a646-34717b138582 # Get details on a runner rule
hctl delete runner-rule 1f8a1ecd-2b06-41de-a646-34717b138582 # Delete a runner rule
You cannot update a runner rule. Instead, delete the unwanted one and create a new runner rule with the desired configuration instead.
Runners will remain assigned to their environments even when the relevant runner rule has been deleted until you refresh the runner for an environment.
Configuration
A runner rule configuration consists of these elements:
# The ID of the runner this rule applies to (required)
runner_id: my-runner
# An optional project ID to limit the runner to a specific project
project_id: my-project
# An optional environment type ID to limit the runner to a specific environment type
env_type_id: my-environment-type
Omitting both project_id and env_type_id creates an empty runner rule (“match anything”).
The Orchestrator will assign a runner rule a technical id in uuid format upon creation.
More than one runner rule can be attached to a runner.
There cannot be more than one runner rule with the same configuration.
Runner assignment to environments
A runner is assigned to an environment on first deployment or when the runner is refreshed. The most specific runner rule matching the environment determines the runner to be assigned.
Runner rules are evaluated from most to least specific in this order:
- A runner rule configured with
project_idandenv_type_id - A runner rule configured with
project_idonly - A runner rule configured with
env_type_idonly - A runner rule with neither
project_idnorenv_type_idconfigured (“match anything”)
Example:
- Runner rule configured for runner
Awith aproject_idofmy-projectand anenv_type_idofdevelopment - Runner rule configured for runner
Bwith aproject_idofmy-project - New environment
devbeing created in projectmy-projectwith an environment typedevelopment
→ Runner A will be assigned because both runner rules match, but the first one is more specific.
Refresh the runner for an environment
An environment remains linked to a runner even when the runner rules change. Execute the refresh_runner command on the environment to re-assign a runner based on the current runner rules.
Use the dry_run flag to test the result of the command without applying any change.
curl https://api.humanitec.dev/orgs/my-org/projects/my-project/envs/my-environment/actions/refresh_runner \
-X POST \
-H "Authorization: Bearer ${HUMANITEC_AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-d '
{
"dry_run": false
}'
If a runner could be identified for the environment, the command will return that runner’s id.
If no runner could be identified, the command will return an error and the environment will remain associated with the previous runner.