Skip to content

Commit 24bf54d

Browse files
author
masterwendu
authored
Add Exoscale zone Module (coder#87)
1 parent b6ec1d8 commit 24bf54d

File tree

7 files changed

+229
-0
lines changed

7 files changed

+229
-0
lines changed

.icons/exoscale.svg

Lines changed: 1 addition & 0 deletions
Loading

.images/exoscale-custom.png

27.5 KB
Loading

.images/exoscale-exclude.png

20.6 KB
Loading

.images/exoscale-zones.png

27.1 KB
Loading

exoscale-zone/README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
display_name: exoscale-zone
3+
description: A parameter with human zone names and icons
4+
icon: ../.icons/exoscale.svg
5+
maintainer_github: WhizUs
6+
verified: false
7+
tags: [helper, parameter, zones, regions, exoscale]
8+
---
9+
10+
# exoscale-zone
11+
12+
A parameter with all Exoscale zones. This allows developers to select
13+
the zone closest to them.
14+
15+
Customize the preselected parameter value:
16+
17+
```hcl
18+
module "exoscale-zone" {
19+
source = "https://registry.coder.com/modules/exoscale-zone"
20+
default = "ch-dk-2"
21+
}
22+
23+
24+
data "exoscale_compute_template" "my_template" {
25+
zone = module.exoscale-zone.value
26+
name = "Linux Ubuntu 22.04 LTS 64-bit"
27+
}
28+
29+
resource "exoscale_compute_instance" "instance" {
30+
zone = module.exoscale-zone.value
31+
....
32+
}
33+
```
34+
35+
![Exoscale Zones](../.images/exoscale-zones.png)
36+
37+
## Examples
38+
39+
### Customize zones
40+
41+
Change the display name and icon for a zone using the corresponding maps:
42+
43+
```hcl
44+
module "exoscale-zone" {
45+
source = "https://registry.coder.com/modules/exoscale-zone"
46+
default = "at-vie-1"
47+
custom_names = {
48+
"at-vie-1": "Home Vienna"
49+
}
50+
custom_icons = {
51+
"at-vie-1": "/emojis/1f3e0.png"
52+
}
53+
}
54+
55+
data "exoscale_compute_template" "my_template" {
56+
zone = module.exoscale-zone.value
57+
name = "Linux Ubuntu 22.04 LTS 64-bit"
58+
}
59+
60+
resource "exoscale_compute_instance" "instance" {
61+
zone = module.exoscale-zone.value
62+
....
63+
}
64+
```
65+
66+
![Exoscale Custom](../.images/exoscale-custom.png)
67+
68+
### Exclude regions
69+
70+
Hide the Switzerland zones Geneva and Zurich
71+
72+
```hcl
73+
module "exoscale-zone" {
74+
source = "https://registry.coder.com/modules/exoscale-zone"
75+
exclude = [ "ch-gva-2", "ch-dk-2" ]
76+
}
77+
78+
data "exoscale_compute_template" "my_template" {
79+
zone = module.exoscale-zone.value
80+
name = "Linux Ubuntu 22.04 LTS 64-bit"
81+
}
82+
83+
resource "exoscale_compute_instance" "instance" {
84+
zone = module.exoscale-zone.value
85+
....
86+
}
87+
```
88+
89+
![Exoscale Exclude](../.images/exoscale-exclude.png)
90+
91+
## Related templates
92+
93+
An exoscale sample template will be delivered soon.

exoscale-zone/main.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { describe, expect, it } from "bun:test";
2+
import {
3+
executeScriptInContainer,
4+
runTerraformApply,
5+
runTerraformInit,
6+
testRequiredVariables,
7+
} from "../test";
8+
9+
describe("exoscale-zone", async () => {
10+
await runTerraformInit(import.meta.dir);
11+
12+
testRequiredVariables(import.meta.dir, {});
13+
14+
it("default output", async () => {
15+
const state = await runTerraformApply(import.meta.dir, {});
16+
expect(state.outputs.value.value).toBe("");
17+
});
18+
19+
it("customized default", async () => {
20+
const state = await runTerraformApply(import.meta.dir, {
21+
default: "at-vie-1",
22+
});
23+
expect(state.outputs.value.value).toBe("at-vie-1");
24+
});
25+
});

exoscale-zone/main.tf

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
coder = {
6+
source = "coder/coder"
7+
version = ">= 0.12"
8+
}
9+
}
10+
}
11+
12+
variable "display_name" {
13+
default = "Exoscale Region"
14+
description = "The display name of the parameter."
15+
type = string
16+
}
17+
18+
variable "description" {
19+
default = "The region to deploy workspace infrastructure."
20+
description = "The description of the parameter."
21+
type = string
22+
}
23+
24+
variable "default" {
25+
default = ""
26+
description = "The default region to use if no region is specified."
27+
type = string
28+
}
29+
30+
variable "mutable" {
31+
default = false
32+
description = "Whether the parameter can be changed after creation."
33+
type = bool
34+
}
35+
36+
variable "custom_names" {
37+
default = {}
38+
description = "A map of custom display names for region IDs."
39+
type = map(string)
40+
}
41+
42+
variable "custom_icons" {
43+
default = {}
44+
description = "A map of custom icons for region IDs."
45+
type = map(string)
46+
}
47+
48+
variable "exclude" {
49+
default = []
50+
description = "A list of region IDs to exclude."
51+
type = list(string)
52+
}
53+
54+
55+
locals {
56+
# This is a static list because the zones don't change _that_
57+
# frequently and including the `exoscale_zones` data source requires
58+
# the provider, which requires a zone.
59+
# https://www.exoscale.com/datacenters/
60+
zones = {
61+
"de-fra-1" = {
62+
name = "Frankfurt - Germany"
63+
icon = "/emojis/1f1e9-1f1ea.png"
64+
}
65+
"at-vie-1" = {
66+
name = "Vienna 1 - Austria"
67+
icon = "/emojis/1f1e6-1f1f9.png"
68+
}
69+
"at-vie-2" = {
70+
name = "Vienna 2 - Austria"
71+
icon = "/emojis/1f1e6-1f1f9.png"
72+
}
73+
"ch-gva-2" = {
74+
name = "Geneva - Switzerland"
75+
icon = "/emojis/1f1e8-1f1ed.png"
76+
}
77+
"ch-dk-2" = {
78+
name = "Zurich - Switzerland"
79+
icon = "/emojis/1f1e8-1f1ed.png"
80+
}
81+
"bg-sof-1" = {
82+
name = "Sofia - Bulgaria"
83+
icon = "/emojis/1f1e7-1f1ec.png"
84+
}
85+
"de-muc-1" = {
86+
name = "Munich - Germany"
87+
icon = "/emojis/1f1e9-1f1ea.png"
88+
}
89+
}
90+
}
91+
92+
data "coder_parameter" "zone" {
93+
name = "exoscale_zone"
94+
display_name = var.display_name
95+
description = var.description
96+
default = var.default == "" ? null : var.default
97+
mutable = var.mutable
98+
dynamic "option" {
99+
for_each = { for k, v in local.zones : k => v if !(contains(var.exclude, k)) }
100+
content {
101+
name = try(var.custom_names[option.key], option.value.name)
102+
icon = try(var.custom_icons[option.key], option.value.icon)
103+
value = option.key
104+
}
105+
}
106+
}
107+
108+
output "value" {
109+
value = data.coder_parameter.zone.value
110+
}

0 commit comments

Comments
 (0)