diff --git a/.icons/exoscale.svg b/.icons/exoscale.svg new file mode 100644 index 0000000..c56a615 --- /dev/null +++ b/.icons/exoscale.svg @@ -0,0 +1 @@ +Artboard 1 \ No newline at end of file diff --git a/.images/exoscale-custom.png b/.images/exoscale-custom.png new file mode 100644 index 0000000..3646c8c Binary files /dev/null and b/.images/exoscale-custom.png differ diff --git a/.images/exoscale-exclude.png b/.images/exoscale-exclude.png new file mode 100644 index 0000000..40683c1 Binary files /dev/null and b/.images/exoscale-exclude.png differ diff --git a/.images/exoscale-zones.png b/.images/exoscale-zones.png new file mode 100644 index 0000000..b78cd01 Binary files /dev/null and b/.images/exoscale-zones.png differ diff --git a/exoscale-zone/README.md b/exoscale-zone/README.md new file mode 100644 index 0000000..91097c8 --- /dev/null +++ b/exoscale-zone/README.md @@ -0,0 +1,93 @@ +--- +display_name: exoscale-zone +description: A parameter with human zone names and icons +icon: ../.icons/exoscale.svg +maintainer_github: WhizUs +verified: false +tags: [helper, parameter, zones, regions, exoscale] +--- + +# exoscale-zone + +A parameter with all Exoscale zones. This allows developers to select +the zone closest to them. + +Customize the preselected parameter value: + +```hcl +module "exoscale-zone" { + source = "https://registry.coder.com/modules/exoscale-zone" + default = "ch-dk-2" +} + + +data "exoscale_compute_template" "my_template" { + zone = module.exoscale-zone.value + name = "Linux Ubuntu 22.04 LTS 64-bit" +} + +resource "exoscale_compute_instance" "instance" { + zone = module.exoscale-zone.value + .... +} +``` + +![Exoscale Zones](../.images/exoscale-zones.png) + +## Examples + +### Customize zones + +Change the display name and icon for a zone using the corresponding maps: + +```hcl +module "exoscale-zone" { + source = "https://registry.coder.com/modules/exoscale-zone" + default = "at-vie-1" + custom_names = { + "at-vie-1": "Home Vienna" + } + custom_icons = { + "at-vie-1": "/emojis/1f3e0.png" + } +} + +data "exoscale_compute_template" "my_template" { + zone = module.exoscale-zone.value + name = "Linux Ubuntu 22.04 LTS 64-bit" +} + +resource "exoscale_compute_instance" "instance" { + zone = module.exoscale-zone.value + .... +} +``` + +![Exoscale Custom](../.images/exoscale-custom.png) + +### Exclude regions + +Hide the Switzerland zones Geneva and Zurich + +```hcl +module "exoscale-zone" { + source = "https://registry.coder.com/modules/exoscale-zone" + exclude = [ "ch-gva-2", "ch-dk-2" ] +} + +data "exoscale_compute_template" "my_template" { + zone = module.exoscale-zone.value + name = "Linux Ubuntu 22.04 LTS 64-bit" +} + +resource "exoscale_compute_instance" "instance" { + zone = module.exoscale-zone.value + .... +} +``` + +![Exoscale Exclude](../.images/exoscale-exclude.png) + +## Related templates + +An exoscale sample template will be delivered soon. diff --git a/exoscale-zone/main.test.ts b/exoscale-zone/main.test.ts new file mode 100644 index 0000000..7c423e7 --- /dev/null +++ b/exoscale-zone/main.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from "bun:test"; +import { + executeScriptInContainer, + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +describe("exoscale-zone", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, {}); + + it("default output", async () => { + const state = await runTerraformApply(import.meta.dir, {}); + expect(state.outputs.value.value).toBe(""); + }); + + it("customized default", async () => { + const state = await runTerraformApply(import.meta.dir, { + default: "at-vie-1", + }); + expect(state.outputs.value.value).toBe("at-vie-1"); + }); +}); diff --git a/exoscale-zone/main.tf b/exoscale-zone/main.tf new file mode 100644 index 0000000..01f1467 --- /dev/null +++ b/exoscale-zone/main.tf @@ -0,0 +1,110 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 0.12" + } + } +} + +variable "display_name" { + default = "Exoscale Region" + description = "The display name of the parameter." + type = string +} + +variable "description" { + default = "The region to deploy workspace infrastructure." + description = "The description of the parameter." + type = string +} + +variable "default" { + default = "" + description = "The default region to use if no region is specified." + type = string +} + +variable "mutable" { + default = false + description = "Whether the parameter can be changed after creation." + type = bool +} + +variable "custom_names" { + default = {} + description = "A map of custom display names for region IDs." + type = map(string) +} + +variable "custom_icons" { + default = {} + description = "A map of custom icons for region IDs." + type = map(string) +} + +variable "exclude" { + default = [] + description = "A list of region IDs to exclude." + type = list(string) +} + + +locals { + # This is a static list because the zones don't change _that_ + # frequently and including the `exoscale_zones` data source requires + # the provider, which requires a zone. + # https://www.exoscale.com/datacenters/ + zones = { + "de-fra-1" = { + name = "Frankfurt - Germany" + icon = "/emojis/1f1e9-1f1ea.png" + } + "at-vie-1" = { + name = "Vienna 1 - Austria" + icon = "/emojis/1f1e6-1f1f9.png" + } + "at-vie-2" = { + name = "Vienna 2 - Austria" + icon = "/emojis/1f1e6-1f1f9.png" + } + "ch-gva-2" = { + name = "Geneva - Switzerland" + icon = "/emojis/1f1e8-1f1ed.png" + } + "ch-dk-2" = { + name = "Zurich - Switzerland" + icon = "/emojis/1f1e8-1f1ed.png" + } + "bg-sof-1" = { + name = "Sofia - Bulgaria" + icon = "/emojis/1f1e7-1f1ec.png" + } + "de-muc-1" = { + name = "Munich - Germany" + icon = "/emojis/1f1e9-1f1ea.png" + } + } +} + +data "coder_parameter" "zone" { + name = "exoscale_zone" + display_name = var.display_name + description = var.description + default = var.default == "" ? null : var.default + mutable = var.mutable + dynamic "option" { + for_each = { for k, v in local.zones : k => v if !(contains(var.exclude, k)) } + content { + name = try(var.custom_names[option.key], option.value.name) + icon = try(var.custom_icons[option.key], option.value.icon) + value = option.key + } + } +} + +output "value" { + value = data.coder_parameter.zone.value +} \ No newline at end of file