The trunk-io/trunk Terraform provider lets you manage merge queue configuration as infrastructure as code. Define your queue settings in Terraform, track changes in version control, and apply them consistently across repositories.
The provider currently supports the trunk_merge_queue resource for creating, updating, importing, and deleting merge queues.
Current version: 0.1.3
Prerequisites
Authentication
Set your org-level API token using the TRUNK_API_KEY environment variable:
export TRUNK_API_KEY="your-org-api-token"
Alternatively, you can pass it directly in the provider block:
provider "trunk" {
api_key = var.trunk_api_key
}
Never commit your API key to version control. Use environment variables or a secrets manager to supply the TRUNK_API_KEY value.
Quick Start
terraform {
required_version = ">= 1.0"
required_providers {
trunk = {
source = "trunk-io/trunk"
version = "0.1.3"
}
}
}
provider "trunk" {}
resource "trunk_merge_queue" "main" {
repo = {
host = "github.com"
owner = "my-org"
name = "my-repo"
}
target_branch = "main"
concurrency = 5
}
Run terraform plan to preview changes and terraform apply to apply them. If a merge queue already exists for the specified repository and branch, the provider will import it automatically rather than creating a duplicate.
Importing Existing Queues
Merge queues created through the UI or API can be imported into Terraform. This lets you start managing an existing queue as code without recreating it.
terraform import trunk_merge_queue.main github.com/my-org/my-repo/main
The import ID format is {host}/{owner}/{name}/{target_branch}.
After importing, run terraform plan to compare the Terraform configuration against the current queue settings. Resolve any differences before running terraform apply.
Resource Reference: trunk_merge_queue
Required Attributes
| Attribute | Type | Description |
|---|
repo.host | string | Repository host (e.g., github.com). Changing this forces a new resource. |
repo.owner | string | Repository owner or organization. Changing this forces a new resource. |
repo.name | string | Repository name. Changing this forces a new resource. |
target_branch | string | Branch the merge queue targets (e.g., main). Changing this forces a new resource. |
The repo and target_branch attributes are immutable. Changing any of them will destroy the existing queue and create a new one.
Optional Attributes With API Defaults
These attributes are computed by the API if not specified. You only need to set them if you want to override the defaults.
| Attribute | Type | Default | Description |
|---|
mode | string | "single" | Queue mode: "single" or "parallel". See Merge Queue mode. |
concurrency | integer | API default | Number of PRs that can test simultaneously (minimum 1). See Testing concurrency. |
state | string | "RUNNING" | Queue state: "RUNNING", "PAUSED", or "DRAINING". See Merge Queue state. |
Other Optional Attributes
| Attribute | Type | Description |
|---|
testing_timeout_minutes | integer | Maximum minutes to wait for tests before auto-cancellation. See Timeout for tests to complete. |
pending_failure_depth | integer | Number of successor test runs to wait on before transitioning a failed group. See Pending failure depth. |
can_optimistically_merge | Boolean | Enable optimistic merging. |
batch | Boolean | Enable batching. |
batching_max_wait_time_minutes | integer | Maximum minutes to wait for a batch to fill. |
batching_min_size | integer | Minimum number of PRs in a batch before testing begins. |
merge_method | string | How PRs are merged: "MERGE_COMMIT", "SQUASH", or "REBASE". See Merge Method. |
comments_enabled | Boolean | Whether Trunk posts status comments on PRs. See GitHub comments. |
commands_enabled | Boolean | Whether /trunk slash commands are enabled. See GitHub commands. |
create_prs_for_testing_branches | Boolean | Create draft PRs for testing branches. See Draft pull request creation. |
status_check_enabled | Boolean | Whether Trunk posts a status check on PRs. |
direct_merge_mode | string | "OFF" or "ALWAYS". See Direct merge to main. |
optimization_mode | string | "OFF" or "BISECTION_SKIP_REDUNDANT_TESTS". |
bisection_concurrency | integer | Concurrency for bisection testing during batch failure isolation. See Bisection Testing Concurrency. |
required_statuses | list(string) | CI status checks that must pass. Set to null to use branch protection defaults. Set to [] to explicitly require no statuses. See Required Status Checks. |
Managing Drift
When a merge queue is managed by Terraform, the Trunk UI displays a banner indicating that the queue is under Terraform management.
Users can still adjust merge queue settings through the UI. However, any changes made in the UI will cause drift between the live configuration and your Terraform state. The UI highlights when drift exists so your team is aware of the discrepancy.
To detect drift, run:
This shows any differences between your Terraform configuration and the current queue state. Run terraform apply to reconcile the configuration back to what is defined in Terraform, or update your .tf files to match the desired state.
If your team adjusts settings through the UI, run terraform plan periodically to detect drift. Apply to reconcile, or update your Terraform configuration to match the desired state.
Deleting a Queue
A merge queue must be empty before it can be deleted. If the queue still has PRs in it, terraform destroy will fail.
To empty a queue, you can set state = "DRAINING" and wait for all in-flight PRs to finish testing and merge. Once the queue is empty, run terraform destroy or remove the resource from your configuration and apply.
Terraform will fail to delete a queue that still has PRs in it. Ensure the queue is empty before destroying the resource.
Examples
High-Throughput Queue With Batching
resource "trunk_merge_queue" "main" {
repo = {
host = "github.com"
owner = "my-org"
name = "my-repo"
}
target_branch = "main"
mode = "parallel"
concurrency = 20
batch = true
batching_min_size = 4
batching_max_wait_time_minutes = 5
can_optimistically_merge = true
}
Queue With Explicit Required Statuses
resource "trunk_merge_queue" "main" {
repo = {
host = "github.com"
owner = "my-org"
name = "my-repo"
}
target_branch = "main"
concurrency = 3
merge_method = "SQUASH"
commands_enabled = true
comments_enabled = true
required_statuses = [
"ci/build",
"ci/test",
"ci/lint",
]
}