Configuration
The .stategraph/config.yml file at the root of your repository configures Stategraph Orchestration: who can plan and apply, what an apply requires, which directories run, and which steps they run. Without it, Orchestration reads the older .terrateam/config.yml.
Do you need a config file?
Without a config file, Orchestration uses defaults. Add one only when you need custom workflows, OIDC, policies, or other advanced settings.
Basic structure
The file is YAML. The version key names the file format. Its only value is "1", which is also the default, so you can omit it. Quote the value: an unquoted 1 is a YAML integer, and the key requires a string.
version: "1"
access_control:
policies: []
apply_requirements:
checks: []
dirs: {}
hooks:
all:
pre: []
post: []
workflows: []
Access control
access_control policies set who can do each operation, such as plan and apply. You can give access to users, teams, or repository collaborator roles.
access_control:
policies:
- tag_query: ''
plan: ['*']
apply: ['team:sre']
The empty tag query matches all directories and workspaces. Anyone can plan. Only members of the sre team can apply.
On GitLab:
- A
team:entry names a GitLab group by its full path, and matches the direct members of the group. - A
role:entry matches the access level of the user in the GitLab project.
Enterprise
Access control is on by default in Enterprise. In the Open Source edition it is always off, and Orchestration rejects access_control.enabled: true. See Editions.
For all options, see access_control.
Apply requirements
apply_requirements sets the conditions that must be true before an apply can run on an unmerged pull request. Changes then get review and checks before they reach your infrastructure.
apply_requirements:
create_pending_apply_check: true
checks:
- tag_query: ""
approved:
enabled: true
any_of: []
any_of_count: 2
all_of: []
merge_conflicts:
enabled: true
status_checks:
enabled: true
ignore_matching:
- "ci/.*"
Before an apply can run, this configuration requires at least two approvals, no merge conflicts, and passing status checks. It ignores each check whose name matches ci/.*.
With create_pending_apply_check enabled, Orchestration creates a stategraph apply commit check:
- On GitHub, with branch protection rules, the pull request cannot merge until all applies are complete.
- On GitLab, the check is a commit status on the merge request pipeline for the commit, when the project runs merge request pipelines. A project that requires a successful pipeline before merge then holds the merge request until all applies are complete.
For details, see apply_requirements.
Dirs
dirs assigns tags, workspaces, and when_modified rules to directories in your repository.
dirs:
ec2:
tags: [aws, ec2]
workspaces:
production:
tags: [production]
when_modified:
file_patterns: ["${DIR}/*.tf", "${DIR}/*.tfvars", "iam/*.tf", "iam/*.tfvars"]
iam:
tags: [aws, iam]
This configuration:
- Assigns the directory-level tags
awsandec2to theec2directory. - Assigns the directory-level tags
awsandiamto theiamdirectory. - Creates a
productionworkspace for theec2directory with the tagproduction. - Lists the files that trigger operations for the
ec2directory when they change.
Directory tags and workspace tags
Directory tags (tags at the directory level) apply to all operations in that directory, in all workspaces. Workspace tags (tags under a workspace) apply only to operations on that workspace. Tag queries such as tag_query: "aws" match both kinds.
The dirs keys accept glob patterns, so one entry can configure many directories with the same shape. ${DIR} expands to the current directory, relative to the repository root.
For details, see dirs.
Hooks
hooks run custom commands or set environment variables before (pre-hooks) or after (post-hooks) an operation, in three groups:
allruns for plan and apply operations.planruns only for plan operations.applyruns only for apply operations.
hooks:
all:
pre:
- type: run
cmd: ['echo', 'Running pre-hook for all operations']
plan:
post:
- type: run
cmd: ['echo', 'Running post-hook for plan operations']
For details, see hooks.
Workflows
workflows set the steps of plan and apply operations, to replace or extend the default behavior. This workflow shows the default steps:
workflows:
- tag_query: ""
plan:
- type: init
- type: plan
apply:
- type: init
- type: apply
initrunsterraform initto prepare the directory.planrunsterraform planto make the execution plan.applyapplies the changes to your infrastructure.
A workflow can also add arguments and error handling:
workflows:
- tag_query: "production"
plan:
- type: init
- type: plan
extra_args: ["-var-file=production.tfvars"]
apply:
- type: init
- type: apply
- type: run
cmd: ['echo', 'Error running apply']
run_on: failure
This workflow applies to all directories with the production tag. It passes a production variable file to the plan, and runs a custom command only when the apply fails.
For details, see workflows.
Reference pages
Each key has its own page in the configuration reference:
- access_control: who can plan, apply, and unlock.
- apply_requirements: approvals, merge conflicts, and status checks required before apply.
- automerge: merge the pull request after a successful apply.
- batch_runs: split a large operation across several CI jobs.
- config_builder: generate configuration with a script at run time.
- cost_estimation: turn on cost estimates in pull request comments.
- default_branch_overrides: which settings are always read from the default branch.
- definitions: reusable templates with YAML anchors.
- destination_branches: which branches a pull request may target to trigger operations.
- dirs: per-directory tags, workspaces, and trigger rules.
- drift: drift detection schedules and reconciliation.
- enabled: turn Orchestration on or off for a repository.
- engine: the IaC tool and its version. Orchestration runs Terraform, OpenTofu, the
stategraphCLI with Infrastructure as a Database, Terragrunt, Pulumi, CDKTF, or a custom command. - hooks: commands before and after operations.
- ignore_patterns: directories that never run on their own.
- indexer: automatic module dependency discovery.
- lock_policy: when a directory acquires a lock.
- notifications: which comments and checks Orchestration posts.
- parallel_runs: how many directories run at once.
- stacks: group workspaces with dependencies and shared variables.
- storage: where plan files are stored.
- tag_queries: the query language that selects directories and workspaces.
- tags: custom tags based on dynamic criteria such as the destination branch.
- tree_builder: a script that defines which files exist and which have changed.
- version: the configuration file format version.
- when_modified: file patterns and autoplan (which changes trigger a plan), and autoapply (apply after merge).
- workflows: custom plan and apply steps.
Basic example
A complete file with the sections above:
access_control:
policies:
- tag_query: ''
plan: ['*']
apply: ['team:infra', 'team:platform']
apply_requirements:
create_pending_apply_check: true
checks:
- tag_query: ""
approved:
enabled: true
any_of_count: 1
dirs:
staging:
tags: [aws, staging]
production:
tags: [aws, production, critical]
workspaces:
default:
tags: [default]
hooks:
all:
pre:
- type: run
cmd: ['echo', 'Starting Terraform operation']
workflows:
- tag_query: "staging"
plan:
- type: init
- type: plan
extra_args: ["-var-file=staging.tfvars"]
- tag_query: "production"
plan:
- type: init
- type: plan
extra_args: ["-var-file=production.tfvars"]
This configuration:
- Lets anyone plan, but only members of the
infraorplatformteams apply. - Requires at least one approval before an apply.
- Tags the staging and production directories.
- Runs a pre-hook before every operation.
- Passes the matching variable file to the staging and production plans.
Start with a file like this, and add sections when you need them.
Next Steps
- Modules: trigger dependent directories when a module changes.
- Secrets and variables: pass secrets and
.tfvarsfiles to Terraform. - Pull request workflow: what happens from open to merge.
- Configuration reference: every key, type, and default.