diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2053546a..908ba273 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -184,31 +184,31 @@ jobs: # GKE: set cluster_node_locations sed -i 's/cluster_node_locations = \[\]/cluster_node_locations = ["europe-west1-b", "europe-west1-c", "europe-west1-d"]/g' gke_zero_cluster.tf || true - - name: "Terraform init" + - name: "OpenTofu init" working-directory: ./kubestack-starter-${{ matrix.starter }} run: | docker run --rm \ -v `pwd`:/infra \ test-image:${{ github.sha }} \ - terraform init + tofu init - - name: "Terraform workspace new ops" + - name: "OpenTofu workspace new ops" working-directory: ./kubestack-starter-${{ matrix.starter }} run: | docker run --rm \ -v `pwd`:/infra \ test-image:${{ github.sha }} \ - terraform workspace new ops + tofu workspace new ops - - name: "Terraform validate" + - name: "OpenTofu validate" working-directory: ./kubestack-starter-${{ matrix.starter }} run: | docker run --rm \ -v `pwd`:/infra \ test-image:${{ github.sha }} \ - terraform validate + tofu validate - - name: "Terraform plan" + - name: "OpenTofu plan" working-directory: ./kubestack-starter-${{ matrix.starter }} env: KBST_AUTH_AWS: ${{ secrets.KBST_AUTH_AWS }} @@ -222,7 +222,7 @@ jobs: -v `pwd`:/infra \ -v /var/run/docker.sock:/var/run/docker.sock \ test-image:${{ github.sha }} \ - terraform plan --target module.aks_zero --target module.eks_zero --target module.gke_zero + tofu plan --target module.aks_zero --target module.eks_zero --target module.gke_zero publish-image: runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index 221f5ce3..ac0f28e3 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ BUILD_CACHE_DIST := --cache-to type=registry,mode=max,ref=ghcr.io/kbst/terraform BUILD_OUTPUT := --output type=registry,push=${DOCKER_PUSH} BUILD_CACHE := --cache-to type=registry,mode=max,ref=ghcr.io/kbst/terraform-kubestack/dev:buildcache-${DOCKER_TARGET},push=${DOCKER_PUSH} else -BUILD_PLATFORM := +BUILD_PLATFORM := BUILD_OUTPUT := --output type=docker endif @@ -57,24 +57,24 @@ build: validate: .init docker exec \ test-container-$(GIT_SHA) \ - entrypoint terraform validate + entrypoint tofu validate test: validate docker exec \ test-container-$(GIT_SHA) \ - entrypoint terraform apply --target module.aks_zero --target module.eks_zero --target module.gke_zero --input=false --auto-approve + entrypoint tofu apply --target module.aks_zero --target module.eks_zero --target module.gke_zero --input=false --auto-approve docker exec \ test-container-$(GIT_SHA) \ - entrypoint terraform apply --target module.eks_zero_nginx --input=false --auto-approve + entrypoint tofu apply --target module.eks_zero_nginx --input=false --auto-approve docker exec \ test-container-$(GIT_SHA) \ - entrypoint terraform apply --input=false --auto-approve + entrypoint tofu apply --input=false --auto-approve cleanup: .init docker exec \ -ti \ test-container-$(GIT_SHA) \ - entrypoint terraform destroy --input=false --auto-approve + entrypoint tofu destroy --input=false --auto-approve $(MAKE) .stop-container shell: .check-container @@ -106,7 +106,7 @@ shell: .check-container .init: .check-container docker exec \ test-container-$(GIT_SHA) \ - entrypoint terraform init + entrypoint tofu init docker exec \ test-container-$(GIT_SHA) \ - entrypoint terraform workspace select ops + entrypoint tofu workspace select ops diff --git a/common/configuration/tests/custom_envs.tftest.hcl b/common/configuration/tests/custom_envs.tftest.hcl new file mode 100644 index 00000000..d9872a08 --- /dev/null +++ b/common/configuration/tests/custom_envs.tftest.hcl @@ -0,0 +1,44 @@ +variables { + configuration = { + apps_production = { + apps_key1 = "from_apps_production" + apps_key2 = "from_apps_production" + } + + apps_staging = { + apps_key1 = "from_apps_staging" + apps_key2 = "from_apps_staging" + } + + ops = { + ops_key = "from_ops" + apps_key1 = "from_ops" + } + + loc = {} + } + + base_key = "apps_production" +} + +run "custom_envs" { + assert { + condition = output.merged["apps_production"] == { apps_key1 = "from_apps_production", apps_key2 = "from_apps_production" } + error_message = "apps_production is unchanged" + } + + assert { + condition = output.merged["apps_staging"] == { apps_key1 = "from_apps_staging", apps_key2 = "from_apps_staging" } + error_message = "apps_staging overwrites everything from apps_production" + } + + assert { + condition = output.merged["ops"] == { apps_key1 = "from_ops", apps_key2 = "from_apps_production", ops_key = "from_ops" } + error_message = "ops inherits from apps_production, overwrites apps_key1 and adds ops_key" + } + + assert { + condition = output.merged["loc"] == { apps_key1 = "from_apps_production", apps_key2 = "from_apps_production" } + error_message = "loc inherits everything from apps_production" + } +} diff --git a/common/configuration/tests/custom_envs/test_envs.tf b/common/configuration/tests/custom_envs/test_envs.tf deleted file mode 100644 index 86162a3f..00000000 --- a/common/configuration/tests/custom_envs/test_envs.tf +++ /dev/null @@ -1,85 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } -} - -module "mut" { - source = "../.." - - configuration = { - apps_production = { - apps_key1 = "from_apps_production" - apps_key2 = "from_apps_production" - } - - apps_staging = { - apps_key1 = "from_apps_staging" - apps_key2 = "from_apps_staging" - } - - ops = { - ops_key = "from_ops" - apps_key1 = "from_ops" - } - - loc = {} - } - - base_key = "apps_production" -} - -resource "test_assertions" "apps_production" { - component = "apps_production" - - equal "scheme" { - description = "apps_production is unchanged" - got = module.mut.merged["apps_production"] - want = { - apps_key1 = "from_apps_production" - apps_key2 = "from_apps_production" - } - } -} - -resource "test_assertions" "apps_staging" { - component = "apps_staging" - - equal "scheme" { - description = "apps_staging overwrites everything from apps_production" - got = module.mut.merged["apps_staging"] - want = { - apps_key1 = "from_apps_staging" - apps_key2 = "from_apps_staging" - } - } -} - -resource "test_assertions" "ops" { - component = "ops" - - equal "scheme" { - description = "ops inherits from apps, overwrites apps_key1 and adds ops_key" - got = module.mut.merged["ops"] - want = { - apps_key1 = "from_ops" - apps_key2 = "from_apps_production" - ops_key = "from_ops" - } - } -} - -resource "test_assertions" "loc" { - component = "loc" - - equal "scheme" { - description = "loc inherits from apps, nulls apps_key2, and adds loc_key" - got = module.mut.merged["loc"] - want = { - apps_key1 = "from_apps_production" - apps_key2 = "from_apps_production" - } - } -} diff --git a/common/configuration/tests/default_envs.tftest.hcl b/common/configuration/tests/default_envs.tftest.hcl new file mode 100644 index 00000000..5002b527 --- /dev/null +++ b/common/configuration/tests/default_envs.tftest.hcl @@ -0,0 +1,36 @@ +variables { + configuration = { + apps = { + apps_key1 = "from_apps" + apps_key2 = "from_apps" + } + + ops = { + ops_key = "from_ops" + apps_key1 = "from_ops" + } + + loc = { + loc_key = "from_loc" + } + } + + base_key = "apps" +} + +run "default_envs" { + assert { + condition = output.merged["apps"] == { apps_key1 = "from_apps", apps_key2 = "from_apps" } + error_message = "apps is unchanged" + } + + assert { + condition = output.merged["ops"] == { apps_key1 = "from_ops", apps_key2 = "from_apps", ops_key = "from_ops" } + error_message = "ops inherits from apps, overwrites apps_key1 and adds ops_key" + } + + assert { + condition = output.merged["loc"] == { apps_key1 = "from_apps", apps_key2 = "from_apps", loc_key = "from_loc" } + error_message = "loc inherits from apps and adds loc_key" + } +} diff --git a/common/configuration/tests/default_envs/test_envs.tf b/common/configuration/tests/default_envs/test_envs.tf deleted file mode 100644 index 360a1e51..00000000 --- a/common/configuration/tests/default_envs/test_envs.tf +++ /dev/null @@ -1,70 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } -} - -module "mut" { - source = "../.." - - configuration = { - apps = { - apps_key1 = "from_apps" - apps_key2 = "from_apps" - } - - ops = { - ops_key = "from_ops" - apps_key1 = "from_ops" - } - - loc = { - loc_key = "from_loc" - } - } - - base_key = "apps" -} - -resource "test_assertions" "apps" { - component = "apps" - - equal "scheme" { - description = "apps is unchanged" - got = module.mut.merged["apps"] - want = { - apps_key1 = "from_apps" - apps_key2 = "from_apps" - } - } -} - -resource "test_assertions" "ops" { - component = "ops" - - equal "scheme" { - description = "ops inherits from apps, overwrites apps_key1 and adds ops_key" - got = module.mut.merged["ops"] - want = { - apps_key1 = "from_ops" - apps_key2 = "from_apps" - ops_key = "from_ops" - } - } -} - -resource "test_assertions" "loc" { - component = "loc" - - equal "scheme" { - description = "loc inherits from apps and adds loc_key" - got = module.mut.merged["loc"] - want = { - apps_key1 = "from_apps" - apps_key2 = "from_apps" - loc_key = "from_loc" - } - } -} diff --git a/common/configuration/tests/non_string_values.tftest.hcl b/common/configuration/tests/non_string_values.tftest.hcl new file mode 100644 index 00000000..fb1aefae --- /dev/null +++ b/common/configuration/tests/non_string_values.tftest.hcl @@ -0,0 +1,243 @@ +run "merge_lists" { + variables { + configuration = { + apps = { + test_list = ["from_apps_1", "from_apps_2"] + } + + ops = { + test_list = ["from_ops_1"] + } + + loc = {} + } + + base_key = "apps" + } + + assert { + condition = output.merged["apps"]["test_list"][0] == "from_apps_1" + error_message = "apps list first element is from_apps_1" + } + + assert { + condition = output.merged["apps"]["test_list"][1] == "from_apps_2" + error_message = "apps list second element is from_apps_2" + } + + assert { + condition = length(output.merged["apps"]["test_list"]) == 2 + error_message = "apps list has exactly 2 elements" + } + + assert { + condition = output.merged["ops"]["test_list"][0] == "from_ops_1" + error_message = "ops list is overwritten and first element is from_ops_1" + } + + assert { + condition = length(output.merged["ops"]["test_list"]) == 1 + error_message = "ops list is overwritten and has exactly 1 element" + } + + assert { + condition = output.merged["loc"]["test_list"][0] == "from_apps_1" + error_message = "loc list inherits from apps and first element is from_apps_1" + } + + assert { + condition = output.merged["loc"]["test_list"][1] == "from_apps_2" + error_message = "loc list inherits from apps and second element is from_apps_2" + } + + assert { + condition = length(output.merged["loc"]["test_list"]) == 2 + error_message = "loc list inherits from apps and has exactly 2 elements" + } +} + +run "merge_hashes" { + variables { + configuration = { + apps = { + test_hash = { + "from_apps_1" = "from_apps_1" + "from_apps_2" = "from_apps_2" + } + } + + ops = { + test_hash = { + "from_ops_1" = "from_ops_1" + } + } + + loc = {} + } + + base_key = "apps" + } + + assert { + condition = output.merged["apps"]["test_hash"]["from_apps_1"] == "from_apps_1" + error_message = "apps hash has from_apps_1 key" + } + + assert { + condition = output.merged["apps"]["test_hash"]["from_apps_2"] == "from_apps_2" + error_message = "apps hash has from_apps_2 key" + } + + assert { + condition = output.merged["ops"]["test_hash"]["from_apps_1"] == "from_apps_1" + error_message = "ops hash inherits from_apps_1 from apps" + } + + assert { + condition = output.merged["ops"]["test_hash"]["from_apps_2"] == "from_apps_2" + error_message = "ops hash inherits from_apps_2 from apps" + } + + assert { + condition = output.merged["ops"]["test_hash"]["from_ops_1"] == "from_ops_1" + error_message = "ops hash merges in from_ops_1 key" + } + + assert { + condition = output.merged["loc"]["test_hash"]["from_apps_1"] == "from_apps_1" + error_message = "loc hash inherits from_apps_1 from apps" + } + + assert { + condition = output.merged["loc"]["test_hash"]["from_apps_2"] == "from_apps_2" + error_message = "loc hash inherits from_apps_2 from apps" + } +} + +run "merge_objects" { + variables { + configuration = { + apps = { + test_string = "from_apps" + test_list_string = ["from_apps"] + test_map_string = { key = "from_apps" } + test_list_object = [{ key = "from_apps" }] + test_object = { key = "from_apps" } + test_map_object = { env = { key = "from_apps" } } + } + + ops = { + test_string = "from_ops" + test_list_string = ["from_ops"] + test_map_string = { key = "from_ops" } + test_list_object = [{ key = "from_ops" }] + test_object = { key = "from_ops" } + test_map_object = { env = { key = "from_ops" } } + } + + loc = { + test_string = "from_apps" + test_list_string = ["from_apps"] + test_map_string = { key = "from_apps" } + test_list_object = [{ key = "from_loc" }] + test_object = { key = "from_apps" } + test_map_object = { env = { key = "from_apps" } } + } + } + + base_key = "apps" + } + + # apps is the base and is unchanged + assert { + condition = output.merged["apps"]["test_string"] == "from_apps" + error_message = "apps test_string is from_apps" + } + + assert { + condition = output.merged["apps"]["test_list_string"][0] == "from_apps" + error_message = "apps test_list_string first element is from_apps" + } + + assert { + condition = output.merged["apps"]["test_map_string"]["key"] == "from_apps" + error_message = "apps test_map_string key is from_apps" + } + + assert { + condition = output.merged["apps"]["test_list_object"][0]["key"] == "from_apps" + error_message = "apps test_list_object first element key is from_apps" + } + + assert { + condition = output.merged["apps"]["test_object"]["key"] == "from_apps" + error_message = "apps test_object key is from_apps" + } + + assert { + condition = output.merged["apps"]["test_map_object"]["env"]["key"] == "from_apps" + error_message = "apps test_map_object env key is from_apps" + } + + # ops completely overrides all values from apps + assert { + condition = output.merged["ops"]["test_string"] == "from_ops" + error_message = "ops test_string overrides apps and is from_ops" + } + + assert { + condition = output.merged["ops"]["test_list_string"][0] == "from_ops" + error_message = "ops test_list_string overrides apps and first element is from_ops" + } + + assert { + condition = output.merged["ops"]["test_map_string"]["key"] == "from_ops" + error_message = "ops test_map_string overrides apps and key is from_ops" + } + + assert { + condition = output.merged["ops"]["test_list_object"][0]["key"] == "from_ops" + error_message = "ops test_list_object overrides apps and first element key is from_ops" + } + + assert { + condition = output.merged["ops"]["test_object"]["key"] == "from_ops" + error_message = "ops test_object overrides apps and key is from_ops" + } + + assert { + condition = output.merged["ops"]["test_map_object"]["env"]["key"] == "from_ops" + error_message = "ops test_map_object overrides apps and env key is from_ops" + } + + # loc only overrides test_list_object, inheriting everything else from apps + assert { + condition = output.merged["loc"]["test_string"] == "from_apps" + error_message = "loc test_string is inherited from apps" + } + + assert { + condition = output.merged["loc"]["test_list_string"][0] == "from_apps" + error_message = "loc test_list_string is inherited from apps" + } + + assert { + condition = output.merged["loc"]["test_map_string"]["key"] == "from_apps" + error_message = "loc test_map_string is inherited from apps" + } + + assert { + condition = output.merged["loc"]["test_list_object"][0]["key"] == "from_loc" + error_message = "loc test_list_object is overridden and first element key is from_loc" + } + + assert { + condition = output.merged["loc"]["test_object"]["key"] == "from_apps" + error_message = "loc test_object is inherited from apps" + } + + assert { + condition = output.merged["loc"]["test_map_object"]["env"]["key"] == "from_apps" + error_message = "loc test_map_object is inherited from apps" + } +} diff --git a/common/configuration/tests/non_string_values/test_hash.tf b/common/configuration/tests/non_string_values/test_hash.tf deleted file mode 100644 index b0d40b19..00000000 --- a/common/configuration/tests/non_string_values/test_hash.tf +++ /dev/null @@ -1,53 +0,0 @@ -module "mut_hash" { - source = "../.." - - configuration = { - apps = { - test_hash = { - "from_apps_1" = "from_apps_1" - "from_apps_2" = "from_apps_2" - } - } - - ops = { - test_hash = { - "from_ops_1" = "from_ops_1" - } - } - - loc = { - } - } - - base_key = "apps" -} - -resource "test_assertions" "merge_hash" { - component = "merge_hash" - - equal "scheme" { - description = "can merge hashes" - got = module.mut_hash.merged - want = { - "apps" = { - "test_hash" = { - "from_apps_1" = "from_apps_1" - "from_apps_2" = "from_apps_2" - } - } - "loc" = { - "test_hash" = tomap({ - "from_apps_1" = "from_apps_1" - "from_apps_2" = "from_apps_2" - }) - } - "ops" = { - "test_hash" = { - "from_apps_1" = "from_apps_1" - "from_apps_2" = "from_apps_2" - "from_ops_1" = "from_ops_1" - } - } - } - } -} diff --git a/common/configuration/tests/non_string_values/test_list.tf b/common/configuration/tests/non_string_values/test_list.tf deleted file mode 100644 index 9ec3eb08..00000000 --- a/common/configuration/tests/non_string_values/test_list.tf +++ /dev/null @@ -1,51 +0,0 @@ -module "mut_list" { - source = "../.." - - configuration = { - apps = { - test_list = [ - "from_apps_1", - "from_apps_2" - ] - } - - ops = { - test_list = [ - "from_ops_1" - ] - } - - loc = { - } - } - - base_key = "apps" -} - -resource "test_assertions" "overwrite_list" { - component = "overwrite_list" - - equal "scheme" { - description = "can overwrite lists" - got = module.mut_list.merged - want = { - "apps" = { - "test_list" = tolist([ - "from_apps_1", - "from_apps_2", - ]) - } - "loc" = { - "test_list" = tolist([ - "from_apps_1", - "from_apps_2", - ]) - } - "ops" = { - "test_list" = tolist([ - "from_ops_1", - ]) - } - } - } -} diff --git a/common/configuration/tests/non_string_values/test_object.tf b/common/configuration/tests/non_string_values/test_object.tf deleted file mode 100644 index 99638891..00000000 --- a/common/configuration/tests/non_string_values/test_object.tf +++ /dev/null @@ -1,80 +0,0 @@ -module "mut_object" { - source = "./wrapper" -} - -resource "test_assertions" "merge_object" { - component = "merge_object" - - equal "scheme" { - description = "can merge objects" - got = module.mut_object.merged - want = { - "apps" = { - "test_list_object" = tolist([ - { - "key" = "from_apps" - }, - ]) - "test_list_string" = tolist([ - "from_apps", - ]) - "test_map_object" = { - "env" = { - "key" = "from_apps" - } - } - "test_map_string" = { - "key" = "from_apps" - } - "test_object" = { - "key" = "from_apps" - } - "test_string" = "from_apps" - } - "loc" = { - "test_list_object" = tolist([ - { - "key" = "from_loc" - }, - ]) - "test_list_string" = tolist([ - "from_apps", - ]) - "test_map_object" = tomap({ - "env" = { - "key" = "from_apps" - } - }) - "test_map_string" = tomap({ - "key" = "from_apps" - }) - "test_object" = { - "key" = "from_apps" - } - "test_string" = "from_apps" - } - "ops" = { - "test_list_object" = tolist([ - { - "key" = "from_ops" - }, - ]) - "test_list_string" = tolist([ - "from_ops", - ]) - "test_map_object" = { - "env" = { - "key" = "from_ops" - } - } - "test_map_string" = { - "key" = "from_ops" - } - "test_object" = { - "key" = "from_ops" - } - "test_string" = "from_ops" - } - } - } -} diff --git a/common/configuration/tests/non_string_values/versions.tf b/common/configuration/tests/non_string_values/versions.tf deleted file mode 100644 index 904b50a9..00000000 --- a/common/configuration/tests/non_string_values/versions.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } - - required_version = ">= 1.3.0" -} diff --git a/common/configuration/tests/non_string_values/wrapper/main.tf b/common/configuration/tests/non_string_values/wrapper/main.tf deleted file mode 100644 index 3a16f872..00000000 --- a/common/configuration/tests/non_string_values/wrapper/main.tf +++ /dev/null @@ -1,88 +0,0 @@ -terraform { - required_version = ">= 1.3.0" -} - -variable "test_configuration" { - type = map(object({ - test_string = optional(string) - test_list_string = optional(list(string)) - test_map_string = optional(map(string)) - test_list_object = optional(list(object({ - key = string - }))) - test_object = optional(object({ - key = string - })) - test_map_object = optional(map(object({ - key = string - }))) - })) - description = "Map with per workspace module configuration." - default = { - apps = { - test_string = "from_apps" - - test_list_string = [ - "from_apps" - ] - - test_map_string = { - key = "from_apps" - } - - test_list_object = [{ - key = "from_apps" - }] - - test_object = { - key = "from_apps" - } - - test_map_object = { - env = { key = "from_apps" } - } - } - - ops = { - test_string = "from_ops" - - test_list_string = [ - "from_ops" - ] - - test_map_string = { - key = "from_ops" - } - - test_list_object = [{ - key = "from_ops" - }] - - test_object = { - key = "from_ops" - } - - test_map_object = { - env = { key = "from_ops" } - } - } - - loc = { - test_list_object = [{ - key = "from_loc" - }] - } - } -} - -module "mut_object" { - source = "../../.." - - configuration = var.test_configuration - - base_key = "apps" -} - -output "merged" { - value = module.mut_object.merged -} diff --git a/common/metadata/tests/custom_delimiter.tftest.hcl b/common/metadata/tests/custom_delimiter.tftest.hcl new file mode 100644 index 00000000..02311f79 --- /dev/null +++ b/common/metadata/tests/custom_delimiter.tftest.hcl @@ -0,0 +1,47 @@ +variables { + name_prefix = "testn" + base_domain = "testd.example.com" + provider_name = "testp" + provider_region = "testr" + workspace = "test_custom_delimiter" + delimiter = "" +} + +run "custom_delimiter" { + assert { + condition = output.name == "testntest_custom_delimitertestr" + error_message = "name concatenates name_prefix, workspace and provider_region with empty delimiter" + } + + assert { + condition = output.domain == "testp.testd.example.com" + error_message = "domain is unaffected by the name delimiter and uses dot separation" + } + + assert { + condition = output.fqdn == "testntest_custom_delimitertestr.testp.testd.example.com" + error_message = "fqdn concatenates name (with empty delimiter) and domain" + } + + assert { + condition = output.labels == { + "kubestack.com/cluster_name" = "testntest_custom_delimitertestr" + "kubestack.com/cluster_domain" = "testp.testd.example.com" + "kubestack.com/cluster_fqdn" = "testntest_custom_delimitertestr.testp.testd.example.com" + "kubestack.com/cluster_workspace" = "test_custom_delimiter" + "kubestack.com/cluster_provider_name" = "testp" + "kubestack.com/cluster_provider_region" = "testr" + } + error_message = "labels reflect the name built with the empty delimiter" + } + + assert { + condition = output.label_namespace == "kubestack.com/" + error_message = "label_namespace is unaffected by the delimiter and returns kubestack.com/" + } + + assert { + condition = output.tags == ["testntest_custom_delimitertestr", "test_custom_delimiter", "testp", "testr"] + error_message = "tags contain name (with empty delimiter), workspace, provider_name and provider_region in order" + } +} diff --git a/common/metadata/tests/custom_delimiter/test.tf b/common/metadata/tests/custom_delimiter/test.tf deleted file mode 100644 index cdc64681..00000000 --- a/common/metadata/tests/custom_delimiter/test.tf +++ /dev/null @@ -1,98 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } -} - -module "mut" { - source = "../.." - - name_prefix = "testn" - base_domain = "testd.example.com" - provider_name = "testp" - provider_region = "testr" - delimiter = "" -} - -locals { - exp_name = "testntest_custom_delimitertestr" - exp_domain = "testp.testd.example.com" - exp_fqdn = "testntest_custom_delimitertestr.testp.testd.example.com" - exp_workspace = "test_custom_delimiter" - exp_provider_name = "testp" - exp_provider_region = "testr" -} - -resource "test_assertions" "name" { - component = "name" - - equal "scheme" { - description = "name concatenates name_prefix, workspace and provider_region" - got = module.mut.name - want = local.exp_name - } -} - -resource "test_assertions" "domain" { - component = "domain" - - equal "scheme" { - description = "domain concatenates name and base_domain" - got = module.mut.domain - want = local.exp_domain - } -} - -resource "test_assertions" "fqdn" { - component = "fqdn" - - equal "scheme" { - description = "fqdn concatenates name and domain" - got = module.mut.fqdn - want = local.exp_fqdn - } -} - -resource "test_assertions" "labels" { - component = "labels" - - equal "scheme" { - description = "labels have correct key/value pairs" - got = module.mut.labels - want = { - "kubestack.com/cluster_name" = local.exp_name - "kubestack.com/cluster_domain" = local.exp_domain - "kubestack.com/cluster_fqdn" = local.exp_fqdn - "kubestack.com/cluster_workspace" = local.exp_workspace - "kubestack.com/cluster_provider_name" = local.exp_provider_name - "kubestack.com/cluster_provider_region" = local.exp_provider_region - } - } -} - -resource "test_assertions" "label_namespace" { - component = "label_namespace" - - equal "scheme" { - description = "returns the used label_namespace" - got = module.mut.label_namespace - want = "kubestack.com/" - } -} - -resource "test_assertions" "tags" { - component = "tags" - - equal "scheme" { - description = "returns the used label_namespace" - got = module.mut.tags - want = [ - local.exp_name, - local.exp_workspace, - local.exp_provider_name, - local.exp_provider_region, - ] - } -} diff --git a/common/metadata/tests/custom_label_namespace.tftest.hcl b/common/metadata/tests/custom_label_namespace.tftest.hcl new file mode 100644 index 00000000..fb91a706 --- /dev/null +++ b/common/metadata/tests/custom_label_namespace.tftest.hcl @@ -0,0 +1,27 @@ +variables { + name_prefix = "testn" + base_domain = "testd.example.com" + provider_name = "testp" + provider_region = "testr" + workspace = "test_custom_label_namespace" + label_namespace = "testlns-" +} + +run "custom_label_namespace" { + assert { + condition = output.labels == { + "testlns-cluster_name" = "testn-test_custom_label_namespace-testr" + "testlns-cluster_domain" = "testp.testd.example.com" + "testlns-cluster_fqdn" = "testn-test_custom_label_namespace-testr.testp.testd.example.com" + "testlns-cluster_workspace" = "test_custom_label_namespace" + "testlns-cluster_provider_name" = "testp" + "testlns-cluster_provider_region" = "testr" + } + error_message = "labels use the custom testlns- namespace as key prefix" + } + + assert { + condition = output.label_namespace == "testlns-" + error_message = "label_namespace returns the custom testlns- value" + } +} diff --git a/common/metadata/tests/custom_label_namespace/test.tf b/common/metadata/tests/custom_label_namespace/test.tf deleted file mode 100644 index 0b64beee..00000000 --- a/common/metadata/tests/custom_label_namespace/test.tf +++ /dev/null @@ -1,54 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } -} - -module "mut" { - source = "../.." - - name_prefix = "testn" - base_domain = "testd.example.com" - provider_name = "testp" - provider_region = "testr" - label_namespace = "testlns-" -} - -locals { - exp_name = "testn-test_custom_label_namespace-testr" - exp_domain = "testp.testd.example.com" - exp_fqdn = "testn-test_custom_label_namespace-testr.testp.testd.example.com" - exp_workspace = "test_custom_label_namespace" - exp_provider_name = "testp" - exp_provider_region = "testr" - exp_label_namespace = "testlns-" -} - -resource "test_assertions" "labels" { - component = "labels" - - equal "scheme" { - description = "labels have correct key/value pairs" - got = module.mut.labels - want = { - "${local.exp_label_namespace}cluster_name" = local.exp_name - "${local.exp_label_namespace}cluster_domain" = local.exp_domain - "${local.exp_label_namespace}cluster_fqdn" = local.exp_fqdn - "${local.exp_label_namespace}cluster_workspace" = local.exp_workspace - "${local.exp_label_namespace}cluster_provider_name" = local.exp_provider_name - "${local.exp_label_namespace}cluster_provider_region" = local.exp_provider_region - } - } -} - -resource "test_assertions" "label_namespace" { - component = "label_namespace" - - equal "scheme" { - description = "returns the used label_namespace" - got = module.mut.label_namespace - want = local.exp_label_namespace - } -} diff --git a/common/metadata/tests/custom_workspace.tftest.hcl b/common/metadata/tests/custom_workspace.tftest.hcl new file mode 100644 index 00000000..498125c8 --- /dev/null +++ b/common/metadata/tests/custom_workspace.tftest.hcl @@ -0,0 +1,24 @@ +variables { + name_prefix = "testn" + base_domain = "testd.example.com" + provider_name = "testp" + provider_region = "testr" + workspace = "testw" +} + +run "custom_workspace" { + assert { + condition = output.name == "testn-testw-testr" + error_message = "name uses the explicitly provided workspace value instead of terraform.workspace" + } + + assert { + condition = output.labels["kubestack.com/cluster_workspace"] == "testw" + error_message = "cluster_workspace label reflects the custom workspace value" + } + + assert { + condition = contains(output.tags, "testw") + error_message = "tags contain the custom workspace value" + } +} diff --git a/common/metadata/tests/custom_workspace/test.tf b/common/metadata/tests/custom_workspace/test.tf deleted file mode 100644 index 65a30ed1..00000000 --- a/common/metadata/tests/custom_workspace/test.tf +++ /dev/null @@ -1,51 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } -} - -module "mut" { - source = "../.." - - name_prefix = "testn" - base_domain = "testd.example.com" - provider_name = "testp" - provider_region = "testr" - workspace = "testw" -} - -locals { - exp_workspace = "testw" - exp_name = "testn-${local.exp_workspace}-testr" -} - -resource "test_assertions" "name" { - component = "name" - - equal "scheme" { - description = "name concatenates name_prefix, workspace and provider_region" - got = module.mut.name - want = local.exp_name - } -} - -resource "test_assertions" "workspace_label" { - component = "workspace_label" - - equal "scheme" { - description = "labels have correct key/value pairs" - got = module.mut.labels["kubestack.com/cluster_workspace"] - want = local.exp_workspace - } -} - -resource "test_assertions" "workspace_tag" { - component = "workspace_tag" - - check "contains" { - description = "check the workspace is one of the tags" - condition = contains(module.mut.tags, local.exp_workspace) - } -} diff --git a/common/metadata/tests/defaults.tftest.hcl b/common/metadata/tests/defaults.tftest.hcl new file mode 100644 index 00000000..0285ea81 --- /dev/null +++ b/common/metadata/tests/defaults.tftest.hcl @@ -0,0 +1,48 @@ +variables { + name_prefix = "testn" + base_domain = "testd.example.com" + provider_name = "testp" + provider_region = "testr" + # Set workspace explicitly so the test is self-contained and does not depend + # on whichever Terraform/OpenTofu workspace happens to be selected at runtime. + workspace = "test_defaults" +} + +run "defaults" { + assert { + condition = output.name == "testn-test_defaults-testr" + error_message = "name concatenates name_prefix, workspace and provider_region with default delimiter" + } + + assert { + condition = output.domain == "testp.testd.example.com" + error_message = "domain concatenates provider_name and base_domain" + } + + assert { + condition = output.fqdn == "testn-test_defaults-testr.testp.testd.example.com" + error_message = "fqdn concatenates name and domain" + } + + assert { + condition = output.labels == { + "kubestack.com/cluster_name" = "testn-test_defaults-testr" + "kubestack.com/cluster_domain" = "testp.testd.example.com" + "kubestack.com/cluster_fqdn" = "testn-test_defaults-testr.testp.testd.example.com" + "kubestack.com/cluster_workspace" = "test_defaults" + "kubestack.com/cluster_provider_name" = "testp" + "kubestack.com/cluster_provider_region" = "testr" + } + error_message = "labels have correct key/value pairs using the default kubestack.com/ namespace" + } + + assert { + condition = output.label_namespace == "kubestack.com/" + error_message = "label_namespace returns the default kubestack.com/ value" + } + + assert { + condition = output.tags == ["testn-test_defaults-testr", "test_defaults", "testp", "testr"] + error_message = "tags contain name, workspace, provider_name and provider_region in order" + } +} diff --git a/common/metadata/tests/defaults/test.tf b/common/metadata/tests/defaults/test.tf deleted file mode 100644 index dd8ab540..00000000 --- a/common/metadata/tests/defaults/test.tf +++ /dev/null @@ -1,97 +0,0 @@ -terraform { - required_providers { - test = { - source = "terraform.io/builtin/test" - } - } -} - -module "mut" { - source = "../.." - - name_prefix = "testn" - base_domain = "testd.example.com" - provider_name = "testp" - provider_region = "testr" -} - -locals { - exp_name = "testn-test_defaults-testr" - exp_domain = "testp.testd.example.com" - exp_fqdn = "testn-test_defaults-testr.testp.testd.example.com" - exp_workspace = "test_defaults" - exp_provider_name = "testp" - exp_provider_region = "testr" -} - -resource "test_assertions" "name" { - component = "name" - - equal "scheme" { - description = "name concatenates name_prefix, workspace and provider_region" - got = module.mut.name - want = local.exp_name - } -} - -resource "test_assertions" "domain" { - component = "domain" - - equal "scheme" { - description = "domain concatenates name and base_domain" - got = module.mut.domain - want = local.exp_domain - } -} - -resource "test_assertions" "fqdn" { - component = "fqdn" - - equal "scheme" { - description = "fqdn concatenates name and domain" - got = module.mut.fqdn - want = local.exp_fqdn - } -} - -resource "test_assertions" "labels" { - component = "labels" - - equal "scheme" { - description = "labels have correct key/value pairs" - got = module.mut.labels - want = { - "kubestack.com/cluster_name" = local.exp_name - "kubestack.com/cluster_domain" = local.exp_domain - "kubestack.com/cluster_fqdn" = local.exp_fqdn - "kubestack.com/cluster_workspace" = local.exp_workspace - "kubestack.com/cluster_provider_name" = local.exp_provider_name - "kubestack.com/cluster_provider_region" = local.exp_provider_region - } - } -} - -resource "test_assertions" "label_namespace" { - component = "label_namespace" - - equal "scheme" { - description = "returns the used label_namespace" - got = module.mut.label_namespace - want = "kubestack.com/" - } -} - -resource "test_assertions" "tags" { - component = "tags" - - equal "scheme" { - description = "returns the used label_namespace" - got = module.mut.tags - want = [ - local.exp_name, - local.exp_workspace, - local.exp_provider_name, - local.exp_provider_region, - ] - } -} diff --git a/oci/Dockerfile b/oci/Dockerfile index 16283571..978dc6d5 100644 --- a/oci/Dockerfile +++ b/oci/Dockerfile @@ -31,10 +31,8 @@ ARG KUBECTL_VERSION=v1.31.3 # https://github.com/kubernetes-sigs/kustomize/releases ARG KUSTOMIZE_VERSION=v5.5.0 -# https://www.terraform.io/downloads.html -# 1.5.x is the last OSS Terraform -# do not update major or minor! -ARG TERRAFORM_VERSION=1.5.7 +# https://github.com/opentofu/opentofu/releases +ARG OPENTOFU_VERSION=1.11.5 RUN echo "KUBECTL_VERSION: ${KUBECTL_VERSION}" \ && curl -LO https://dl.k8s.io/${KUBECTL_VERSION}/kubernetes-client-linux-${TARGETARCH}.tar.gz \ @@ -49,11 +47,12 @@ RUN echo "KUSTOMIZE_VERSION: ${KUSTOMIZE_VERSION}" \ && mv kustomize /opt/bin/kustomize \ && /opt/bin/kustomize version -RUN echo "TERRAFORM_VERSION: ${TERRAFORM_VERSION}" \ - && curl -LO https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip \ - && unzip terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip -d /opt/bin \ - && chmod +x /opt/bin/terraform \ - && /opt/bin/terraform version +RUN echo "OPENTOFU_VERSION: ${OPENTOFU_VERSION}" \ + && curl -LO https://github.com/opentofu/opentofu/releases/download/v${OPENTOFU_VERSION}/tofu_${OPENTOFU_VERSION}_linux_${TARGETARCH}.tar.gz \ + && tar -xf tofu_${OPENTOFU_VERSION}_linux_${TARGETARCH}.tar.gz \ + && mv tofu /opt/bin/tofu \ + && chmod +x /opt/bin/tofu \ + && /opt/bin/tofu version COPY oci/entrypoint oci/entrypoint_user /opt/bin/ @@ -157,11 +156,11 @@ COPY common /common # Run inheritance module tests RUN cd /common/configuration &&\ - terraform test + tofu test # Run metadata module tests RUN cd /common/metadata &&\ - terraform test + tofu test ARG GIT_SHA=master ARG GIT_REF=refs/heads/master @@ -179,14 +178,14 @@ ENV GIT_SHA=${GIT_SHA} \ RUN cd build_artifacts &&\ pipenv run python dist.py dist -# Run terraform init for each starter +# Run tofu init for each starter RUN mkdir -p /terraform/plugin-cache ENV TF_PLUGIN_CACHE_DIR=/terraform/plugin-cache RUN set -e &&\ for name in `ls /quickstart/_dist/`; do \ if [ -d /quickstart/_dist/$name ]; then \ cd /quickstart/_dist/$name &&\ - terraform init --upgrade &&\ + tofu init --upgrade &&\ rm -rf .terraform; \ fi; \ done