-
Notifications
You must be signed in to change notification settings - Fork 881
docs: describe workspace tags #13352
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
Merged
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
caa6ee7
docs: describe workspace tags
mtojek 1042d5b
WIP
mtojek f3016fb
typos
mtojek 0c6c844
link
mtojek 7443d42
typo
mtojek 716d01e
example
mtojek b43d8a1
lacks
mtojek 883a17d
rephrased
mtojek cfd0c23
rename os to runtime
mtojek 12a292c
Cian's review
mtojek 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
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,87 @@ | ||
# Workspace Tags | ||
|
||
Template administrators can leverage static template tags to limit workspace | ||
provisioning to designated provisioner groups that have locally deployed | ||
credentials for creating workspace resources. While this method ensures | ||
controlled access, it offers limited flexibility and does not permit users to | ||
select the nodes for their workspace creation. | ||
|
||
By using `coder_workspace_tags` and `coder_parameter`s, template administrators | ||
can enable dynamic tag selection and modify static template tags. | ||
|
||
## Dynamic tag selection | ||
|
||
Here is a sample `coder_workspace_tags` data resource with a few workspace tags | ||
specified: | ||
|
||
```hcl | ||
data "coder_workspace_tags" "custom_workspace_tags" { | ||
tags = { | ||
"zone" = "developers" | ||
"runtime" = data.coder_parameter.runtime_selector.value | ||
"project_id" = "PROJECT_${data.coder_parameter.project_name.value}" | ||
"cache" = data.coder_parameter.feature_cache_enabled.value == "true" ? "with-cache" : "no-cache" | ||
} | ||
} | ||
``` | ||
|
||
**Legend** | ||
|
||
- `zone` - static tag value set to `developers` | ||
- `runtime` - supported by the string-type `coder_parameter` to select | ||
provisioner runtime, `runtime_selector` | ||
- `project_id` - a formatted string supported by the string-type | ||
`coder_parameter`, `project_name` | ||
- `cache` - an HCL condition involving boolean-type `coder_parameter`, | ||
`feature_cache_enabled` | ||
|
||
Review the | ||
[full template example](https://github.com/coder/coder/tree/main/examples/workspace-tags) | ||
using `coder_workspace_tags` and `coder_parameter`s. | ||
|
||
## Constraints | ||
|
||
### Tagged provisioners | ||
|
||
With incorrectly selected workspace tags, it is possible to choose a tag | ||
configuration that is not observed by any provisioner, causing the provisioner | ||
job to get stuck in the queue indefinitely. | ||
mtojek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Before releasing the template version with configurable workspace tags, ensure | ||
that every tag set is associated with at least one healthy provisioner. | ||
|
||
### Parameters types | ||
mtojek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Provisioners require job tags to be defined in plain string format. When a | ||
workspace tag refers to a `coder_parameter` without involving the string | ||
formatter, for example, | ||
(`"runtime" = data.coder_parameter.runtime_selector.value`), the Coder | ||
provisioner server can transform only the following parameter types to strings: | ||
_string_, _number_, and _bool_. | ||
|
||
### Mutability | ||
|
||
A mutable `coder_parameter` can be dangerous for a workspace tag as it allows | ||
the workspace owner to change a provisioner group (due to different tags). In | ||
most cases, `coder_parameter`s backing `coder_workspace_tags` should be marked | ||
as immutable and set only once, during workspace creation. | ||
|
||
### HCL syntax | ||
|
||
When importing the template version with `coder_workspace_tags`, the Coder | ||
provisioner server extracts raw partial queries for each workspace tag and | ||
stores them in the database. During workspace build time, the Coder server uses | ||
the [Hashicorp HCL library](https://github.com/hashicorp/hcl) to evaluate these | ||
raw queries on-the-fly without processing the entire Terraform template. This | ||
evaluation is simpler but also limited in terms of available functions, | ||
variables, and references to other resources. | ||
|
||
**Supported syntax** | ||
|
||
- Static string: `foobar_tag = "foobaz"` | ||
- Formatted string: `foobar_tag = "foobaz ${data.coder_parameter.foobaz.value}"` | ||
- Reference to `coder_parameter`: | ||
`foobar_tag = data.coder_parameter.foobar.value` | ||
- Boolean logic: `production_tag = !data.coder_parameter.staging_env.value` | ||
- Condition: | ||
`cache = data.coder_parameter.feature_cache_enabled.value == "true" ? "with-cache" : "no-cache"` |
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,26 @@ | ||
--- | ||
name: Sample Template with Workspace Tags | ||
description: Review the sample template and introduce dynamic workspace tags to your template | ||
tags: [local, docker, workspace-tags] | ||
icon: /icon/docker.png | ||
--- | ||
|
||
# Overview | ||
|
||
This Coder template presents use of [Workspace Tags](https://coder.com/docs/v2/latest/templates/workspace-tags) [Coder Parameters](https://coder.com/docs/v2/latest/templates/parameters). | ||
|
||
# Use case | ||
|
||
Template administrators can use static tags to control workspace provisioning, limiting it to specific provisioner groups. However, this restricts workspace users from choosing their preferred workspace nodes. | ||
mtojek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
By using `coder_workspace_tags` and `coder_parameter`s, template administrators can allow dynamic tag selection, avoiding the need to push the same template multiple times with different tags. | ||
|
||
## Development | ||
|
||
Update the template and push it using the following command: | ||
|
||
``` | ||
./scripts/coder-dev.sh templates push examples-workspace-tags \ | ||
-d examples/workspace-tags \ | ||
-y | ||
``` |
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,170 @@ | ||
terraform { | ||
required_providers { | ||
coder = { | ||
source = "coder/coder" | ||
} | ||
docker = { | ||
source = "kreuzwerker/docker" | ||
} | ||
} | ||
} | ||
|
||
locals { | ||
username = data.coder_workspace.me.owner | ||
} | ||
|
||
data "coder_provisioner" "me" { | ||
} | ||
|
||
data "coder_workspace" "me" { | ||
} | ||
|
||
data "coder_workspace_tags" "custom_workspace_tags" { | ||
tags = { | ||
"zone" = "developers" | ||
"runtime" = data.coder_parameter.runtime_selector.value | ||
"project_id" = "PROJECT_${data.coder_parameter.project_name.value}" | ||
"cache" = data.coder_parameter.feature_cache_enabled.value == "true" ? "with-cache" : "no-cache" | ||
} | ||
} | ||
|
||
data "coder_parameter" "runtime_selector" { | ||
name = "runtime_selector" | ||
display_name = "Provisioner Runtime" | ||
default = "development" | ||
|
||
option { | ||
name = "Development (free zone)" | ||
value = "development" | ||
} | ||
option { | ||
name = "Staging (internal access)" | ||
value = "staging" | ||
} | ||
option { | ||
name = "Production (air-gapped)" | ||
value = "production" | ||
} | ||
|
||
mutable = false | ||
} | ||
|
||
data "coder_parameter" "project_name" { | ||
name = "project_name" | ||
display_name = "Project name" | ||
description = "Specify the project name." | ||
|
||
mutable = false | ||
} | ||
|
||
data "coder_parameter" "feature_cache_enabled" { | ||
name = "feature_cache_enabled" | ||
display_name = "Enable cache?" | ||
type = "bool" | ||
default = false | ||
|
||
mutable = false | ||
} | ||
|
||
resource "coder_agent" "main" { | ||
arch = data.coder_provisioner.me.arch | ||
os = "linux" | ||
startup_script = <<EOF | ||
#!/bin/sh | ||
# install and start code-server | ||
curl -fsSL https://code-server.dev/install.sh | sh -s -- --version 4.8.3 | ||
code-server --auth none --port 13337 | ||
EOF | ||
|
||
env = { | ||
GIT_AUTHOR_NAME = "${data.coder_workspace.me.owner}" | ||
GIT_COMMITTER_NAME = "${data.coder_workspace.me.owner}" | ||
GIT_AUTHOR_EMAIL = "${data.coder_workspace.me.owner_email}" | ||
GIT_COMMITTER_EMAIL = "${data.coder_workspace.me.owner_email}" | ||
} | ||
} | ||
|
||
resource "coder_app" "code-server" { | ||
agent_id = coder_agent.main.id | ||
slug = "code-server" | ||
display_name = "code-server" | ||
url = "http://localhost:13337/?folder=/home/${local.username}" | ||
icon = "/icon/code.svg" | ||
subdomain = false | ||
share = "owner" | ||
|
||
healthcheck { | ||
url = "http://localhost:13337/healthz" | ||
interval = 5 | ||
threshold = 6 | ||
} | ||
} | ||
|
||
resource "docker_volume" "home_volume" { | ||
name = "coder-${data.coder_workspace.me.id}-home" | ||
lifecycle { | ||
ignore_changes = all | ||
} | ||
labels { | ||
label = "coder.owner" | ||
value = data.coder_workspace.me.owner | ||
} | ||
labels { | ||
label = "coder.owner_id" | ||
value = data.coder_workspace.me.owner_id | ||
} | ||
labels { | ||
label = "coder.workspace_id" | ||
value = data.coder_workspace.me.id | ||
} | ||
labels { | ||
label = "coder.workspace_name_at_creation" | ||
value = data.coder_workspace.me.name | ||
} | ||
} | ||
|
||
resource "coder_metadata" "home_info" { | ||
resource_id = docker_volume.home_volume.id | ||
|
||
item { | ||
key = "size" | ||
value = "5 GiB" | ||
} | ||
} | ||
|
||
resource "docker_container" "workspace" { | ||
count = data.coder_workspace.me.start_count | ||
image = "ubuntu:22.04" | ||
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" | ||
hostname = data.coder_workspace.me.name | ||
entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] | ||
env = [ | ||
"CODER_AGENT_TOKEN=${coder_agent.main.token}", | ||
] | ||
host { | ||
host = "host.docker.internal" | ||
ip = "host-gateway" | ||
} | ||
volumes { | ||
container_path = "/home/${local.username}" | ||
volume_name = docker_volume.home_volume.name | ||
read_only = false | ||
} | ||
|
||
labels { | ||
label = "coder.owner" | ||
value = data.coder_workspace.me.owner | ||
} | ||
labels { | ||
label = "coder.owner_id" | ||
value = data.coder_workspace.me.owner_id | ||
} | ||
labels { | ||
label = "coder.workspace_id" | ||
value = data.coder_workspace.me.id | ||
} | ||
labels { | ||
label = "coder.workspace_name" | ||
value = data.coder_workspace.me.name | ||
} | ||
} |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SEO suggestion:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good hint!