From cb46520f78c44e679c5abae694242709314401ad Mon Sep 17 00:00:00 2001 From: Rafferty Uy <1037626+raffertyuy@users.noreply.github.com> Date: Fri, 9 May 2025 16:35:23 +0800 Subject: [PATCH 1/3] Bump the actions group with 3 updates (#1) Bumps the actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [terraform-linters/setup-tflint](https://github.com/terraform-linters/setup-tflint) and [hashicorp/setup-terraform](https://github.com/hashicorp/setup-terraform). Updates `actions/checkout` from 3 to 4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) Updates `terraform-linters/setup-tflint` from 3 to 4 - [Release notes](https://github.com/terraform-linters/setup-tflint/releases) - [Commits](https://github.com/terraform-linters/setup-tflint/compare/v3...v4) Updates `hashicorp/setup-terraform` from 2 to 3 - [Release notes](https://github.com/hashicorp/setup-terraform/releases) - [Changelog](https://github.com/hashicorp/setup-terraform/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/setup-terraform/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: terraform-linters/setup-tflint dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: hashicorp/setup-terraform dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Arnaud Lheureux --- .github/workflows/terraform-lint.yml | 4 ++-- .github/workflows/terraform-security-msdo.yml | 2 +- .github/workflows/terraform-tests.yml | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/terraform-lint.yml b/.github/workflows/terraform-lint.yml index 7f57abf..1f8f77b 100644 --- a/.github/workflows/terraform-lint.yml +++ b/.github/workflows/terraform-lint.yml @@ -18,10 +18,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup TFLint - uses: terraform-linters/setup-tflint@v3 + uses: terraform-linters/setup-tflint@v4 with: tflint_version: v0.46.1 diff --git a/.github/workflows/terraform-security-msdo.yml b/.github/workflows/terraform-security-msdo.yml index 7bff264..b6da49c 100644 --- a/.github/workflows/terraform-security-msdo.yml +++ b/.github/workflows/terraform-security-msdo.yml @@ -18,7 +18,7 @@ jobs: name: MSDO Security Scan runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: microsoft/security-devops-action@v1.12.0 id: msdo with: diff --git a/.github/workflows/terraform-tests.yml b/.github/workflows/terraform-tests.yml index 24dd870..3d8fa50 100644 --- a/.github/workflows/terraform-tests.yml +++ b/.github/workflows/terraform-tests.yml @@ -15,8 +15,8 @@ jobs: name: Format and Validate runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: hashicorp/setup-terraform@v2 + - uses: actions/checkout@v4 + - uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.11.4 - name: Terraform Init @@ -33,7 +33,7 @@ jobs: integration_tests: ${{ steps.find-integration-tests.outputs.tests }} example_tests: ${{ steps.find-example-tests.outputs.tests }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Find unit tests id: find-unit-tests run: | @@ -58,8 +58,8 @@ jobs: matrix: test: ${{fromJson(needs.discover-tests.outputs.unit_tests)}} steps: - - uses: actions/checkout@v3 - - uses: hashicorp/setup-terraform@v2 + - uses: actions/checkout@v4 + - uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.11.4 - name: Terraform Init @@ -75,8 +75,8 @@ jobs: matrix: test: ${{fromJson(needs.discover-tests.outputs.integration_tests)}} steps: - - uses: actions/checkout@v3 - - uses: hashicorp/setup-terraform@v2 + - uses: actions/checkout@v4 + - uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.11.4 - name: Terraform Init @@ -92,8 +92,8 @@ jobs: matrix: test: ${{fromJson(needs.discover-tests.outputs.example_tests)}} steps: - - uses: actions/checkout@v3 - - uses: hashicorp/setup-terraform@v2 + - uses: actions/checkout@v4 + - uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.11.4 - name: Terraform Init From 209357c006d20735d39fe297ab3455069954e211 Mon Sep 17 00:00:00 2001 From: Rafferty Uy <1037626+raffertyuy@users.noreply.github.com> Date: Fri, 9 May 2025 14:13:20 +0000 Subject: [PATCH 2/3] implement dev_box_definitions for default images. --- .github/copilot-instructions.md | 2 - dev_center_dev_box_definitions.tf | 10 +++ docs/module_guide.md | 10 +-- .../simple_case/configuration.tfvars | 20 +++++ .../configuration.tfvars | 53 +++++++++++ .../dev_center_dev_box_definition/module.tf | 34 +++++++ .../dev_center_dev_box_definition/output.tf | 4 + .../variables.tf | 35 ++++++++ .../dev_box_definition_test.tftest.hcl | 88 +++++++++++++++++++ 9 files changed, 249 insertions(+), 7 deletions(-) create mode 100644 dev_center_dev_box_definitions.tf create mode 100644 examples/dev_center_dev_box_definition/configuration.tfvars create mode 100644 modules/dev_center_dev_box_definition/module.tf create mode 100644 modules/dev_center_dev_box_definition/output.tf create mode 100644 modules/dev_center_dev_box_definition/variables.tf create mode 100644 tests/unit/dev_center_dev_box_definition/dev_box_definition_test.tftest.hcl diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 29777a8..186761a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -254,6 +254,4 @@ resource "azurerm_key_vault" "kv" { --- - - This dev container includes the Azure CLI, GitHub CLI, Terraform CLI, TFLint, and Terragrunt pre-installed and available on the PATH, along with the Terraform and Azure extensions for development. diff --git a/dev_center_dev_box_definitions.tf b/dev_center_dev_box_definitions.tf new file mode 100644 index 0000000..b2efa6f --- /dev/null +++ b/dev_center_dev_box_definitions.tf @@ -0,0 +1,10 @@ +# Dev Center Dev Box Definitions module instantiation +module "dev_center_dev_box_definitions" { + source = "./modules/dev_center_dev_box_definition" + for_each = try(var.dev_center_dev_box_definitions, {}) + + global_settings = var.global_settings + dev_box_definition = each.value + dev_center_id = lookup(each.value, "dev_center_id", null) != null ? each.value.dev_center_id : module.dev_centers[each.value.dev_center.key].id + location = lookup(each.value, "region", null) != null ? each.value.region : module.resource_groups[each.value.resource_group.key].location +} diff --git a/docs/module_guide.md b/docs/module_guide.md index e46bf6e..95b4b36 100644 --- a/docs/module_guide.md +++ b/docs/module_guide.md @@ -122,12 +122,12 @@ dev_center_dev_box_definitions = { dev_center = { key = "devcenter1" } - image_reference = { - offer = "windows-11" - publisher = "microsoftwindowsdesktop" - sku = "win11-22h2-ent" - version = "latest" + resource_group = { + key = "rg1" } + # Currently assumes that image definition is one of that's available in the default gallery + # Format: /galleries/{gallery}/images/{image-definition} + image_reference_id = "/galleries/default/images/microsoftwindowsdesktop_windows-ent-cpc_win11-24h2-ent-cpc-m365" sku_name = "general_i_8c32gb256ssd_v2" hibernate_support = { enabled = true diff --git a/examples/dev_center/simple_case/configuration.tfvars b/examples/dev_center/simple_case/configuration.tfvars index 69b7bb6..5be45b8 100644 --- a/examples/dev_center/simple_case/configuration.tfvars +++ b/examples/dev_center/simple_case/configuration.tfvars @@ -24,3 +24,23 @@ dev_centers = { } } } + +dev_center_dev_box_definitions = { + definition1 = { + name = "win11-dev" + dev_center = { + key = "devcenter1" + } + resource_group = { + key = "rg1" + } + # Currently assumes that image definition is one of that's available in the default gallery + # Format: /galleries/{gallery}/images/{image-definition} + image_reference_id = "/galleries/default/images/microsoftwindowsdesktop_windows-ent-cpc_win11-24h2-ent-cpc-m365" + sku_name = "general_i_8c32gb256ssd_v2" + tags = { + environment = "demo" + module = "dev_center_dev_box_definition" + } + } +} diff --git a/examples/dev_center_dev_box_definition/configuration.tfvars b/examples/dev_center_dev_box_definition/configuration.tfvars new file mode 100644 index 0000000..a995b66 --- /dev/null +++ b/examples/dev_center_dev_box_definition/configuration.tfvars @@ -0,0 +1,53 @@ +global_settings = { + prefixes = ["dev"] + random_length = 3 + passthrough = false + use_slug = true +} + +resource_groups = { + rg1 = { + name = "devfactory-dc" + region = "eastus" + tags = { + environment = "development" + workload = "devbox-example" + } + } +} + +dev_centers = { + devcenter1 = { + name = "devcenter" + resource_group = { + key = "rg1" + } + identity = { + type = "SystemAssigned" + } + tags = { + environment = "demo" + module = "dev_center" + } + } +} + +dev_center_dev_box_definitions = { + definition1 = { + name = "win11-dev" + dev_center = { + key = "devcenter1" + } + resource_group = { + key = "rg1" + } + # Currently assumes that image definition is one of that's available in the default gallery + # Format: /galleries/{gallery}/images/{image-definition} + image_reference_id = "/galleries/default/images/microsoftwindowsdesktop_windows-ent-cpc_win11-24h2-ent-cpc-m365" + sku_name = "general_i_8c32gb256ssd_v2" + tags = { + environment = "demo" + module = "dev_center_dev_box_definition" + } + } +} diff --git a/modules/dev_center_dev_box_definition/module.tf b/modules/dev_center_dev_box_definition/module.tf new file mode 100644 index 0000000..7fb33a3 --- /dev/null +++ b/modules/dev_center_dev_box_definition/module.tf @@ -0,0 +1,34 @@ +terraform { + required_version = ">= 1.9.0" + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + version = "~> 1.2.0" + } + azurerm = { + source = "hashicorp/azurerm" + version = "~> 4.26.0" + } + } +} + +locals {} + +resource "azurecaf_name" "dev_box_definition" { + name = var.dev_box_definition.name + resource_type = "general" + prefixes = var.global_settings.prefixes + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} + +resource "azurerm_dev_center_dev_box_definition" "dev_box_definition" { + name = azurecaf_name.dev_box_definition.result + location = var.location + dev_center_id = var.dev_center_id + image_reference_id = var.dev_box_definition.image_reference_id != null ? "${var.dev_center_id}${var.dev_box_definition.image_reference_id}" : null + sku_name = try(var.dev_box_definition.sku_name, null) + tags = try(var.tags, null) +} \ No newline at end of file diff --git a/modules/dev_center_dev_box_definition/output.tf b/modules/dev_center_dev_box_definition/output.tf new file mode 100644 index 0000000..d2f05ec --- /dev/null +++ b/modules/dev_center_dev_box_definition/output.tf @@ -0,0 +1,4 @@ +output "id" { + description = "The ID of the Dev Center Dev Box Definition" + value = azurerm_dev_center_dev_box_definition.dev_box_definition.id +} diff --git a/modules/dev_center_dev_box_definition/variables.tf b/modules/dev_center_dev_box_definition/variables.tf new file mode 100644 index 0000000..b922079 --- /dev/null +++ b/modules/dev_center_dev_box_definition/variables.tf @@ -0,0 +1,35 @@ +variable "global_settings" { + description = "Global settings object" + type = object({ + prefixes = optional(list(string)) + random_length = optional(number) + passthrough = optional(bool) + use_slug = optional(bool) + }) +} + +variable "dev_center_id" { + description = "The ID of the Dev Center in which to create the project" + type = string +} + +variable "location" { + description = "The location/region where the Dev Center Project is created" + type = string +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} + +variable "dev_box_definition" { + description = "Configuration object for the Dev Box Definition" + type = object({ + name = string + image_reference_id = string + sku_name = string + tags = optional(map(string)) + }) +} diff --git a/tests/unit/dev_center_dev_box_definition/dev_box_definition_test.tftest.hcl b/tests/unit/dev_center_dev_box_definition/dev_box_definition_test.tftest.hcl new file mode 100644 index 0000000..9e1b395 --- /dev/null +++ b/tests/unit/dev_center_dev_box_definition/dev_box_definition_test.tftest.hcl @@ -0,0 +1,88 @@ +variables { + global_settings = { + prefixes = ["dev"] + random_length = 3 + passthrough = false + use_slug = true + } + + resource_groups = { + rg1 = { + name = "test-resource-group" + region = "eastus" + tags = { + environment = "test" + } + } + } + + dev_centers = { + devcenter1 = { + name = "test-dev-center" + resource_group = { + key = "rg1" + } + tags = { + environment = "test" + module = "dev_center" + } + } + } + + dev_center_dev_box_definitions = { + definition1 = { + name = "test-dev-box-definition" + dev_center = { + key = "devcenter1" + } + resource_group = { + key = "rg1" + } + image_reference_id = try(var.dev_box_definition.image_reference_id, null) + sku_name = try(var.dev_box_definition.sku_name, null) + tags = { + environment = "test" + module = "dev_center_dev_box_definition" + } + } + } + + // Empty variables required by the root module + dev_center_galleries = {} + dev_center_projects = {} + dev_center_environment_types = {} + dev_center_project_environment_types = {} + dev_center_network_connections = {} + dev_center_catalogs = {} + shared_image_galleries = {} +} + +mock_provider "azurerm" {} + +run "dev_box_definition_creation" { + command = plan + + module { + source = "../../../" + } + + assert { + condition = module.dev_center_dev_box_definitions["definition1"].name != "" + error_message = "Dev Box Definition name should not be empty" + } + + assert { + condition = contains(keys(module.dev_center_dev_box_definitions["definition1"]), "id") + error_message = "Dev Box Definition ID should be present in module outputs" + } + + assert { + condition = contains(keys(module.dev_center_dev_box_definitions["definition1"].tags), "environment") + error_message = "Dev Box Definition tags did not contain environment tag" + } + + assert { + condition = contains(keys(module.dev_center_dev_box_definitions["definition1"].tags), "module") + error_message = "Dev Box Definition tags did not contain module tag" + } +} From b48c4f0fe463208239fe0cd345fb749d57146c3b Mon Sep 17 00:00:00 2001 From: Rafferty Uy <1037626+raffertyuy@users.noreply.github.com> Date: Sat, 10 May 2025 00:46:32 +0000 Subject: [PATCH 3/3] fix terraform fmt issue --- dev_center_dev_box_definitions.tf | 8 +++---- .../simple_case/configuration.tfvars | 22 +------------------ .../dev_center_dev_box_definition/module.tf | 12 +++++----- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/dev_center_dev_box_definitions.tf b/dev_center_dev_box_definitions.tf index b2efa6f..8fa0d30 100644 --- a/dev_center_dev_box_definitions.tf +++ b/dev_center_dev_box_definitions.tf @@ -3,8 +3,8 @@ module "dev_center_dev_box_definitions" { source = "./modules/dev_center_dev_box_definition" for_each = try(var.dev_center_dev_box_definitions, {}) - global_settings = var.global_settings - dev_box_definition = each.value - dev_center_id = lookup(each.value, "dev_center_id", null) != null ? each.value.dev_center_id : module.dev_centers[each.value.dev_center.key].id - location = lookup(each.value, "region", null) != null ? each.value.region : module.resource_groups[each.value.resource_group.key].location + global_settings = var.global_settings + dev_box_definition = each.value + dev_center_id = lookup(each.value, "dev_center_id", null) != null ? each.value.dev_center_id : module.dev_centers[each.value.dev_center.key].id + location = lookup(each.value, "region", null) != null ? each.value.region : module.resource_groups[each.value.resource_group.key].location } diff --git a/examples/dev_center/simple_case/configuration.tfvars b/examples/dev_center/simple_case/configuration.tfvars index 5be45b8..1ee44fc 100644 --- a/examples/dev_center/simple_case/configuration.tfvars +++ b/examples/dev_center/simple_case/configuration.tfvars @@ -23,24 +23,4 @@ dev_centers = { module = "dev_center" } } -} - -dev_center_dev_box_definitions = { - definition1 = { - name = "win11-dev" - dev_center = { - key = "devcenter1" - } - resource_group = { - key = "rg1" - } - # Currently assumes that image definition is one of that's available in the default gallery - # Format: /galleries/{gallery}/images/{image-definition} - image_reference_id = "/galleries/default/images/microsoftwindowsdesktop_windows-ent-cpc_win11-24h2-ent-cpc-m365" - sku_name = "general_i_8c32gb256ssd_v2" - tags = { - environment = "demo" - module = "dev_center_dev_box_definition" - } - } -} +} \ No newline at end of file diff --git a/modules/dev_center_dev_box_definition/module.tf b/modules/dev_center_dev_box_definition/module.tf index 7fb33a3..680d54a 100644 --- a/modules/dev_center_dev_box_definition/module.tf +++ b/modules/dev_center_dev_box_definition/module.tf @@ -25,10 +25,10 @@ resource "azurecaf_name" "dev_box_definition" { } resource "azurerm_dev_center_dev_box_definition" "dev_box_definition" { - name = azurecaf_name.dev_box_definition.result - location = var.location - dev_center_id = var.dev_center_id - image_reference_id = var.dev_box_definition.image_reference_id != null ? "${var.dev_center_id}${var.dev_box_definition.image_reference_id}" : null - sku_name = try(var.dev_box_definition.sku_name, null) - tags = try(var.tags, null) + name = azurecaf_name.dev_box_definition.result + location = var.location + dev_center_id = var.dev_center_id + image_reference_id = var.dev_box_definition.image_reference_id != null ? "${var.dev_center_id}${var.dev_box_definition.image_reference_id}" : null + sku_name = try(var.dev_box_definition.sku_name, null) + tags = try(var.tags, null) } \ No newline at end of file