Repository navigation
feat: add coder_script_order data source #550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
BobbyHo
merged 4 commits into
main
from
bobby/plat-542-phase-1-add-coder_script_order-data-source
Oct 7, 2026
Merged
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
a35da93
feat: add coder_script_order data source
BobbyHo fe15cf0
docs: name the Coder version that enforces coder_script_order
BobbyHo 392916d
docs: clarify coder_script_order selector direction and phase inference
BobbyHo 61f33d9
docs: note coder_script_order selected scripts need one lifecycle flag
BobbyHo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| --- | ||
| # generated by https://github.com/hashicorp/terraform-plugin-docs | ||
| page_title: "coder_script_order Data Source - terraform-provider-coder" | ||
| subcategory: "" | ||
| description: |- | ||
| Use this data source to declare ordering constraints between coder_script resources on the same agent. It does not run scripts. Every script selected by run waits for every script selected by after. | ||
| Selectors are Terraform address strings (coder_script.name, coder_script.name[0], coder_script.name["key"], module.name), resolved by Coder relative to the module that declares the data source. Terraform and terraform validate do not check them; Coder reports unknown or unsupported selectors when the template is imported. All values must be known at plan time, and the data source needs no depends_on. | ||
| -> This data source is only available in Coder v2.39 and later. Older versions ignore it and run scripts concurrently. | ||
| --- | ||
|
|
||
| # coder_script_order (Data Source) | ||
|
|
||
| Use this data source to declare ordering constraints between `coder_script` resources on the same agent. It does not run scripts. Every script selected by `run` waits for every script selected by `after`. | ||
|
|
||
| Selectors are Terraform address strings (`coder_script.name`, `coder_script.name[0]`, `coder_script.name["key"]`, `module.name`), resolved by Coder relative to the module that declares the data source. Terraform and `terraform validate` do not check them; Coder reports unknown or unsupported selectors when the template is imported. All values must be known at plan time, and the data source needs no `depends_on`. | ||
|
|
||
| -> This data source is only available in Coder v2.39 and later. Older versions ignore it and run scripts concurrently. | ||
|
|
||
| ## Example Usage | ||
|
|
||
| ```terraform | ||
| provider "coder" {} | ||
|
|
||
| data "coder_script_order" "startup_dependencies" { | ||
| rule { | ||
| run = ["coder_script.install_tools"] | ||
| after = ["coder_script.clone_repo"] | ||
| } | ||
|
|
||
| rule { | ||
| run = ["coder_script.configure_workspace"] | ||
| after = ["module.bootstrap"] | ||
| requires = "completion" | ||
| } | ||
|
|
||
| # module.cleanup has both start and stop scripts. phase keeps only the | ||
| # stop scripts and suppresses the inferred-phase warning. | ||
| rule { | ||
| run = ["coder_script.archive_logs"] | ||
| after = ["module.cleanup"] | ||
| phase = "stop" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| <!-- schema generated by tfplugindocs --> | ||
| ## Schema | ||
|
|
||
| ### Required | ||
|
|
||
| - `rule` (Block List, Min: 1) One or more ordering rules. Rules from every `coder_script_order` in the template are merged into one graph per agent. (see [below for nested schema](#nestedblock--rule)) | ||
|
|
||
| ### Read-Only | ||
|
|
||
| - `id` (String) The ID of this resource. | ||
|
|
||
| <a id="nestedblock--rule"></a> | ||
| ### Nested Schema for `rule` | ||
|
|
||
| Required: | ||
|
|
||
| - `after` (List of String) Selectors for the scripts that must finish before any `run` script starts. | ||
| - `run` (List of String) Selectors for the scripts that wait for every `after` script. | ||
|
|
||
| Optional: | ||
|
|
||
| - `phase` (String) Which lifecycle the rule applies to: `start` or `stop`. When omitted, Coder infers the phase from any `coder_script` selector in the rule and filters `module` selectors to that phase with a warning. If the rule has only `module` selectors and they expand to both start and stop scripts, Coder cannot infer the phase and rejects the rule at template import, so set `phase` explicitly in that case. | ||
| - `requires` (String) The outcome required from every `after` script before a `run` script starts. `success` (the default) skips the `run` scripts if any `after` script fails, times out or is skipped. `completion` runs them once every `after` script has finished, whatever the outcome. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| provider "coder" {} | ||
|
|
||
| data "coder_script_order" "startup_dependencies" { | ||
| rule { | ||
| run = ["coder_script.install_tools"] | ||
| after = ["coder_script.clone_repo"] | ||
| } | ||
|
|
||
| rule { | ||
| run = ["coder_script.configure_workspace"] | ||
| after = ["module.bootstrap"] | ||
| requires = "completion" | ||
| } | ||
|
|
||
| # module.cleanup has both start and stop scripts. phase keeps only the | ||
| # stop scripts and suppresses the inferred-phase warning. | ||
| rule { | ||
| run = ["coder_script.archive_logs"] | ||
| after = ["module.cleanup"] | ||
| phase = "stop" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| package provider | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "github.com/google/uuid" | ||
| "github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
| ) | ||
|
|
||
| // Coder's provisioner accepts the same values. The provider and Coder | ||
| // share no Go types, so the plan JSON is the contract between them. | ||
| const ( | ||
| scriptOrderRequiresSuccess = "success" | ||
| scriptOrderRequiresCompletion = "completion" | ||
|
|
||
| scriptOrderPhaseStart = "start" | ||
| scriptOrderPhaseStop = "stop" | ||
| ) | ||
|
|
||
| func scriptOrderDataSource() *schema.Resource { | ||
| // Selector syntax is not checked here. Coder resolves selectors | ||
| // against the whole plan and reports unknown or unsupported ones at | ||
| // template import. A stricter check here could reject selectors that | ||
| // Coder accepts. | ||
| selectorSchema := func(description string) *schema.Schema { | ||
| return &schema.Schema{ | ||
| Type: schema.TypeList, | ||
| Description: description, | ||
| Required: true, | ||
| MinItems: 1, | ||
| Elem: &schema.Schema{ | ||
| Type: schema.TypeString, | ||
| ValidateFunc: validation.StringIsNotEmpty, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| return &schema.Resource{ | ||
| SchemaVersion: 0, | ||
|
|
||
| Description: "Use this data source to declare ordering constraints between `coder_script` " + | ||
| "resources on the same agent. It does not run scripts. Every script selected by " + | ||
| "`run` waits for every script selected by `after`.\n\n" + | ||
| "Selectors are Terraform address strings (`coder_script.name`, " + | ||
| "`coder_script.name[0]`, `coder_script.name[\"key\"]`, `module.name`), resolved " + | ||
| "by Coder relative to the module that declares the data source. Terraform and " + | ||
| "`terraform validate` do not check them; Coder reports unknown or unsupported " + | ||
| "selectors when the template is imported. All values must be known at plan time, " + | ||
| "and the data source needs no `depends_on`.\n\n" + | ||
| "-> This data source is only available in Coder v2.39 and later. Older versions " + | ||
| "ignore it and run scripts concurrently.", | ||
| ReadContext: func(_ context.Context, rd *schema.ResourceData, _ any) diag.Diagnostics { | ||
| rd.SetId(uuid.NewString()) | ||
| return nil | ||
| }, | ||
| Schema: map[string]*schema.Schema{ | ||
| "rule": { | ||
| Type: schema.TypeList, | ||
| Description: "One or more ordering rules. Rules from every `coder_script_order` in the template are merged into one graph per agent.", | ||
| Required: true, | ||
| MinItems: 1, | ||
| Elem: &schema.Resource{ | ||
| Schema: map[string]*schema.Schema{ | ||
| "run": selectorSchema("Selectors for the scripts that wait for every `after` script."), | ||
| "after": selectorSchema("Selectors for the scripts that must finish before any `run` script starts."), | ||
| "requires": { | ||
| Type: schema.TypeString, | ||
| Description: "The outcome required from every `after` script before a `run` script starts. " + | ||
| "`success` (the default) skips the `run` scripts if any `after` script fails, times out or is skipped. " + | ||
| "`completion` runs them once every `after` script has finished, whatever the outcome.", | ||
| Optional: true, | ||
| Default: scriptOrderRequiresSuccess, | ||
| ValidateFunc: validation.StringInSlice([]string{ | ||
| scriptOrderRequiresSuccess, | ||
| scriptOrderRequiresCompletion, | ||
| }, false), | ||
| }, | ||
| "phase": { | ||
| Type: schema.TypeString, | ||
| Description: "Which lifecycle the rule applies to: `start` or `stop`. " + | ||
|
BobbyHo marked this conversation as resolved.
|
||
| "When omitted, Coder infers the phase from any `coder_script` selector in the rule " + | ||
| "and filters `module` selectors to that phase with a warning. " + | ||
| "If the rule has only `module` selectors and they expand to both start and stop " + | ||
| "scripts, Coder cannot infer the phase and rejects the rule at template import, " + | ||
| "so set `phase` explicitly in that case.", | ||
| Optional: true, | ||
| // No default on purpose. Coder infers the phase when | ||
| // this is unset, warns when inference filtered a | ||
| // module selector, and rejects a module-only rule | ||
| // that spans both phases. A default would hide all | ||
| // three. | ||
| ValidateFunc: validation.StringInSlice([]string{ | ||
| scriptOrderPhaseStart, | ||
| scriptOrderPhaseStop, | ||
| }, false), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.