Skip to content

Commit 13e5287

Browse files
committed
flatten demo terraform
1 parent e1061d7 commit 13e5287

File tree

9 files changed

+1869
-0
lines changed

9 files changed

+1869
-0
lines changed

testdata/demo_flat/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Demo Template
2+
3+
3 security "zones" exist. Their role defines which are available
4+
- `high` - all roles
5+
- `medium` - developers + admins
6+
- `low` - admins only
7+
8+
Regions exists. Users are defaulted to their region based on their groups.
9+
- `us-pittsburgh`
10+
- `eu-helsinki`
11+
- `ap-sydney`
12+
- `sa-saopaulo`
13+
- `za-jnb`
14+
15+
Select your IDE from jetbrains based on your team.
16+
- Frontend
17+
- Backend
18+
- Fullstack
19+
20+
Select your CPUs
21+
- 1-8
22+
- On `high` security zones, only 1-4 are available.
23+
24+
Select your image hash (only available to admins)
25+
26+
## User Groups
27+
28+
Group options:
29+
- Role
30+
- `admin`
31+
- `developer`
32+
- Region
33+
- `us-pittsburgh`
34+
- `eu-helsinki`
35+
- `ap-sydney`
36+
- `sa-saopaulo`
37+
- `za-jnb`

testdata/demo_flat/base.tf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
locals {
2+
// default to the only option if only 1 exists
3+
choose_security = length(keys(local.allowed_security_levels)) > 1
4+
secutity_level = local.choose_security ? data.coder_parameter.security_level[0].value : keys(module.deploys.security_levels)[0]
5+
}
6+
7+
data "coder_parameter" "security_level" {
8+
count = local.choose_security ? 1 : 0
9+
name = "security_level"
10+
display_name = "Security Level"
11+
description = "What security level do you need?"
12+
type = "string"
13+
default = "high"
14+
order = 50
15+
16+
17+
dynamic "option" {
18+
for_each = local.allowed_security_levels
19+
content {
20+
name = option.value.display_name
21+
value = option.key
22+
description = option.value.description
23+
}
24+
}
25+
26+
# validation {
27+
# regex = "^high|medium|low$"
28+
# error = "You must select either high, medium, or low."
29+
# }
30+
}

testdata/demo_flat/deploys.tf

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Handles which cluster the workspace should be deployed to
2+
// using workspace tags.
3+
locals {
4+
security_levels = {
5+
"high" = {
6+
display_name = "High"
7+
description = "Most confidentiality, restricted access. Deployed into the confidential cluster."
8+
tags = {"cluster": "confidential"}
9+
}
10+
"medium" = {
11+
display_name = "Medium"
12+
description = "A medium security level. Deployed into the standard production cluster."
13+
tags = {"cluster": "production"}
14+
}
15+
"low" = {
16+
display_name = "Low"
17+
description = "The lowest security level. Deployed into the public cluster."
18+
tags = {"cluster": "public"}
19+
}
20+
}
21+
22+
admin = local.security_levels
23+
developer = {for k in ["high", "medium"] : k => local.security_levels[k]}
24+
contractor = {for k in ["high"] : k => local.security_levels[k]}
25+
isAdmin = contains(data.coder_workspace_owner.me.groups, "admin")
26+
isDeveloper = contains(data.coder_workspace_owner.me.groups, "developer")
27+
28+
allowed_security_levels = (
29+
local.isAdmin ? local.admin :
30+
local.isDeveloper ? local.developer : local.contractor
31+
)
32+
33+
direct_ssh_allowed = local.isAdmin && var.security == "low"
34+
}
35+
36+
variable "security" {
37+
type = string
38+
default = "high"
39+
}
40+
41+
data "coder_workspace_tags" "custom_workspace_tags" {
42+
tags = local.security_levels[var.security].tags
43+
}
44+
45+
46+
data "coder_parameter" "direct_ssh" {
47+
count = local.direct_ssh_allowed ? 1 : 0
48+
name = "Direct SSH to Pod"
49+
description = "Should direct SSH access be enabled to the workspace pod? This should be set to false for production workspaces, and is a debugging tool."
50+
type = "bool"
51+
default = false
52+
}

testdata/demo_flat/locals.tf

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
locals {
2+
fe_codes = ["PS", "WS"]
3+
be_codes = ["CL", "GO", "IU", "PY"]
4+
teams = {
5+
"frontend" = {
6+
"display_name" = "Frontend",
7+
"codes" = local.fe_codes,
8+
"description" = "The team that works on the frontend.",
9+
"icon" = "/icon/desktop.svg"
10+
},
11+
"backend" = {
12+
"display_name" = "Backend",
13+
"codes" = local.be_codes,
14+
"description" = "The team that works on the backend.",
15+
"icon" = "/emojis/2699.png",
16+
},
17+
"fullstack" = {
18+
"display_name" = "Fullstack",
19+
"codes" = concat(local.be_codes, local.fe_codes),
20+
"description" = "The team that works on both the frontend and backend.",
21+
"icon" = "/emojis/1f916.png",
22+
}
23+
}
24+
25+
regions = [
26+
{
27+
icon = "/emojis/1f1fa-1f1f8.png"
28+
name = "Pittsburgh"
29+
value = "us-pittsburgh"
30+
},
31+
{
32+
icon = "/emojis/1f1eb-1f1ee.png"
33+
name = "Helsinki"
34+
value = "eu-helsinki"
35+
},
36+
{
37+
icon = "/emojis/1f1e6-1f1fa.png"
38+
name = "Sydney"
39+
value = "ap-sydney"
40+
},
41+
{
42+
icon = "/emojis/1f1e7-1f1f7.png"
43+
name = "São Paulo"
44+
value = "sa-saopaulo"
45+
},
46+
{
47+
icon = "/emojis/1f1ff-1f1e6.png"
48+
name = "Johannesburg"
49+
value = "za-jnb"
50+
}
51+
]
52+
53+
region_values = [for region in local.regions : region.value]
54+
default_regions = tolist(setintersection(data.coder_workspace_owner.me.groups, local.region_values))
55+
default_region = length(local.default_regions) > 0 ? local.default_regions[0] : local.region_values[0]
56+
}
57+
58+
output "test" {
59+
value = local.default_region
60+
}

testdata/demo_flat/main.tf

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Demo terraform has a complex configuration.
2+
// CODER_WORKSPACE_OWNER_GROUPS='["admin","developer"]' terraform apply
3+
//
4+
// Some run options
5+
// preview -v Team=backend -g admin
6+
// preview -v Team=backend -g admin -g sa-saopaulo
7+
terraform {
8+
required_providers {
9+
coder = {
10+
source = "coder/coder"
11+
}
12+
docker = {
13+
source = "kreuzwerker/docker"
14+
version = "3.0.2"
15+
}
16+
}
17+
}
18+
19+
20+
data coder_workspace_owner "me" {}
21+
22+
module "jetbrains_gateway" {
23+
count = 1
24+
source = "registry.coder.com/modules/jetbrains-gateway/coder"
25+
version = "1.0.28"
26+
agent_id = "random"
27+
folder = "/home/coder/example"
28+
jetbrains_ides = local.teams[data.coder_parameter.team.value].codes
29+
default = local.teams[data.coder_parameter.team.value].codes[0]
30+
coder_parameter_order = 11
31+
}

testdata/demo_flat/parameters.tf

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
data "coder_parameter" "team" {
2+
name = "Team"
3+
description = "Which team are you on?"
4+
type = "string"
5+
default = "fullstack"
6+
order = 10
7+
8+
dynamic "option" {
9+
for_each = local.teams
10+
content {
11+
name = option.value.display_name
12+
value = option.key
13+
description = option.value.description
14+
icon = option.value.icon
15+
}
16+
}
17+
18+
validation {
19+
regex = "^frontend|backend|fullstack$"
20+
error = "You must select either frontend, backend, or fullstack."
21+
}
22+
}
23+
24+
data "coder_parameter" "browser" {
25+
name = "browser"
26+
description = "Which browser do you prefer?"
27+
type = "string"
28+
default = "chromium"
29+
order = 12
30+
count = (
31+
data.coder_parameter.team.value == "frontend" ||
32+
data.coder_parameter.team.value == "fullstack"? 1 : 0
33+
)
34+
35+
option {
36+
name = "Chrome"
37+
value = "chrome"
38+
}
39+
40+
option {
41+
name = "Firefox"
42+
value = "firefox"
43+
}
44+
45+
option {
46+
name = "Safari"
47+
value = "safari"
48+
}
49+
50+
option {
51+
name = "Edge"
52+
value = "edge"
53+
}
54+
55+
option {
56+
name = "Chromium"
57+
value = "chromium"
58+
}
59+
}
60+
61+
62+
data "coder_parameter" "cpu" {
63+
name = "cpu"
64+
display_name = "CPU"
65+
description = "The number of CPU cores"
66+
type = "number"
67+
default = "2"
68+
icon = "/icon/memory.svg"
69+
mutable = true
70+
order = 20
71+
72+
validation {
73+
min = 1
74+
// Confidential instances are more expensive, or some justification like
75+
// that
76+
// TODO: This breaks when the user is an admin
77+
max = local.secutity_level == "high" ? 4 : 8
78+
error = "CPU range must be between {min} and {max}."
79+
}
80+
}
81+
82+
data "coder_workspace_tags" "test" {
83+
tags = {
84+
"hash": trimprefix(data.docker_registry_image.coder.sha256_digest, "sha256:")
85+
}
86+
}
87+
88+
// Advanced admin parameter
89+
data "coder_parameter" "image_hash" {
90+
count = local.isAdmin ? 1 : 0
91+
name = "Image Hash"
92+
description = "Override the hash of the image to use. Only available to admins."
93+
// Value can get stale
94+
default = trimprefix(data.docker_registry_image.coder.sha256_digest, "sha256:")
95+
order = 100
96+
97+
validation {
98+
regex = "^[a-f0-9A-F]{64}$"
99+
error = "The image hash must be a 64-character hexadecimal string."
100+
}
101+
}
102+
103+
data "docker_registry_image" "coder" {
104+
name = "ghcr.io/coder/coder:latest"
105+
}
106+
107+
data "coder_parameter" "region" {
108+
name = "Region"
109+
display_name = "Region"
110+
description = "What region are you in?"
111+
default = local.default_region
112+
icon = "/icon/memory.svg"
113+
mutable = false
114+
order = 1
115+
116+
dynamic "option" {
117+
for_each = local.regions
118+
content {
119+
name = option.value.name
120+
value = option.value.value
121+
icon = option.value.icon
122+
}
123+
}
124+
}

0 commit comments

Comments
 (0)