diff --git a/cli/cmd/env_cmd.go b/cli/cmd/env_cmd.go index f10856bc..a77b6864 100644 --- a/cli/cmd/env_cmd.go +++ b/cli/cmd/env_cmd.go @@ -511,6 +511,15 @@ func createAzureEnvHCL(envDir, envName, vnetCIDR string) error { env = %q vnet_cidr = %q + # DC02 runs the recurring attack-simulation tasks and needs additional memory. + goad_instance_sizes = { + dc01 = "Standard_D2s_v3" + dc02 = "Standard_D4s_v3" + dc03 = "Standard_D2s_v3" + srv02 = "Standard_D2s_v3" + srv03 = "Standard_D2s_v3" + } + bastion_sku = "Standard" bastion_subnet_cidr = %q bastion_tunneling_enabled = true diff --git a/cli/cmd/env_cmd_test.go b/cli/cmd/env_cmd_test.go index b20d0033..4cd5046d 100644 --- a/cli/cmd/env_cmd_test.go +++ b/cli/cmd/env_cmd_test.go @@ -1,6 +1,11 @@ package cmd -import "testing" +import ( + "os" + "path/filepath" + "strings" + "testing" +) func TestDeriveAzureSubnets(t *testing.T) { tests := []struct { @@ -36,3 +41,32 @@ func TestDeriveAzureSubnets(t *testing.T) { }) } } + +func TestCreateAzureEnvHCLSetsGOADInstanceSizes(t *testing.T) { + envDir := t.TempDir() + if err := createAzureEnvHCL(envDir, "memory-test", "10.8.0.0/16"); err != nil { + t.Fatalf("createAzureEnvHCL() error = %v", err) + } + + content, err := os.ReadFile(filepath.Join(envDir, "env.hcl")) + if err != nil { + t.Fatalf("read env.hcl: %v", err) + } + + for _, want := range []string{ + `goad_instance_sizes = {`, + `dc01 = "Standard_D2s_v3"`, + `dc02 = "Standard_D4s_v3"`, + `dc03 = "Standard_D2s_v3"`, + `srv02 = "Standard_D2s_v3"`, + `srv03 = "Standard_D2s_v3"`, + } { + if !strings.Contains(string(content), want) { + t.Errorf("env.hcl missing %q", want) + } + } + + if got := strings.Count(string(content), `"Standard_D4s_v3"`); got != 1 { + t.Errorf("D4s_v3 count = %d, want 1", got) + } +} diff --git a/docs/mkdocs/docs/providers/azure.md b/docs/mkdocs/docs/providers/azure.md index 39a50496..3cd0100b 100644 --- a/docs/mkdocs/docs/providers/azure.md +++ b/docs/mkdocs/docs/providers/azure.md @@ -47,6 +47,27 @@ env: test !!! warning "Subscription capacity" The Dreadnode MSFT Startup subscription has tight quota limits in `eastus`. Default to `centralus` unless you know the target region has capacity. +### GOAD VM sizes + +Azure environment configuration supports a `goad_instance_sizes` map in `env.hcl`. +DC02 defaults to `Standard_D4s_v3` because it runs the recurring attack-simulation +tasks; the other GOAD hosts default to `Standard_D2s_v3`. + +```hcl +goad_instance_sizes = { + dc01 = "Standard_D2s_v3" + dc02 = "Standard_D4s_v3" + dc03 = "Standard_D2s_v3" + srv02 = "Standard_D2s_v3" + srv03 = "Standard_D2s_v3" +} +``` + +New environments include and consume these defaults automatically. Environments +created before this setting was introduced still have a hard-coded size in each host +configuration. Before the next apply, set `instance_size = "Standard_D4s_v3"` in the +existing environment's `dc02/terragrunt.hcl` so Terraform retains the larger VM size. + ## Installation diff --git a/infra/azure/goad-deployment/test/centralus/goad/dc01/terragrunt.hcl b/infra/azure/goad-deployment/test/centralus/goad/dc01/terragrunt.hcl index 3e762c81..53484d60 100644 --- a/infra/azure/goad-deployment/test/centralus/goad/dc01/terragrunt.hcl +++ b/infra/azure/goad-deployment/test/centralus/goad/dc01/terragrunt.hcl @@ -18,6 +18,10 @@ locals { hostname = include.host.locals.computer_name goad_id = include.host.locals.goad_id + instance_size = try( + local.env_vars.locals.goad_instance_sizes[local.goad_id], + "Standard_D2s_v3", + ) lab_config = jsondecode(file("${get_repo_root()}/ad/GOAD/data/${local.env}-config.json")) admin_password = local.lab_config.lab.hosts[local.goad_id].local_admin_password @@ -45,7 +49,7 @@ inputs = { env = local.env instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" computer_name = local.hostname - instance_size = "Standard_D2s_v3" + instance_size = local.instance_size source_image = { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" diff --git a/infra/azure/goad-deployment/test/centralus/goad/dc02/terragrunt.hcl b/infra/azure/goad-deployment/test/centralus/goad/dc02/terragrunt.hcl index 55f1a153..a83c8ada 100644 --- a/infra/azure/goad-deployment/test/centralus/goad/dc02/terragrunt.hcl +++ b/infra/azure/goad-deployment/test/centralus/goad/dc02/terragrunt.hcl @@ -18,6 +18,10 @@ locals { hostname = include.host.locals.computer_name goad_id = include.host.locals.goad_id + instance_size = try( + local.env_vars.locals.goad_instance_sizes[local.goad_id], + "Standard_D2s_v3", + ) lab_config = jsondecode(file("${get_repo_root()}/ad/GOAD/data/${local.env}-config.json")) admin_password = local.lab_config.lab.hosts[local.goad_id].local_admin_password @@ -45,7 +49,7 @@ inputs = { env = local.env instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" computer_name = local.hostname - instance_size = "Standard_D2s_v3" + instance_size = local.instance_size source_image = { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" diff --git a/infra/azure/goad-deployment/test/centralus/goad/dc03/terragrunt.hcl b/infra/azure/goad-deployment/test/centralus/goad/dc03/terragrunt.hcl index a750b35f..b005335c 100644 --- a/infra/azure/goad-deployment/test/centralus/goad/dc03/terragrunt.hcl +++ b/infra/azure/goad-deployment/test/centralus/goad/dc03/terragrunt.hcl @@ -18,6 +18,10 @@ locals { hostname = include.host.locals.computer_name goad_id = include.host.locals.goad_id + instance_size = try( + local.env_vars.locals.goad_instance_sizes[local.goad_id], + "Standard_D2s_v3", + ) lab_config = jsondecode(file("${get_repo_root()}/ad/GOAD/data/${local.env}-config.json")) admin_password = local.lab_config.lab.hosts[local.goad_id].local_admin_password @@ -45,7 +49,7 @@ inputs = { env = local.env instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" computer_name = local.hostname - instance_size = "Standard_D2s_v3" + instance_size = local.instance_size source_image = { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" diff --git a/infra/azure/goad-deployment/test/centralus/goad/srv02/terragrunt.hcl b/infra/azure/goad-deployment/test/centralus/goad/srv02/terragrunt.hcl index e099e8e8..b4f142e2 100644 --- a/infra/azure/goad-deployment/test/centralus/goad/srv02/terragrunt.hcl +++ b/infra/azure/goad-deployment/test/centralus/goad/srv02/terragrunt.hcl @@ -18,6 +18,10 @@ locals { hostname = include.host.locals.computer_name goad_id = include.host.locals.goad_id + instance_size = try( + local.env_vars.locals.goad_instance_sizes[local.goad_id], + "Standard_D2s_v3", + ) lab_config = jsondecode(file("${get_repo_root()}/ad/GOAD/data/${local.env}-config.json")) admin_password = local.lab_config.lab.hosts[local.goad_id].local_admin_password @@ -45,7 +49,7 @@ inputs = { env = local.env instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" computer_name = local.hostname - instance_size = "Standard_D2s_v3" + instance_size = local.instance_size source_image = { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" diff --git a/infra/azure/goad-deployment/test/centralus/goad/srv03/terragrunt.hcl b/infra/azure/goad-deployment/test/centralus/goad/srv03/terragrunt.hcl index 6bfe889b..bf4c50fc 100644 --- a/infra/azure/goad-deployment/test/centralus/goad/srv03/terragrunt.hcl +++ b/infra/azure/goad-deployment/test/centralus/goad/srv03/terragrunt.hcl @@ -18,6 +18,10 @@ locals { hostname = include.host.locals.computer_name goad_id = include.host.locals.goad_id + instance_size = try( + local.env_vars.locals.goad_instance_sizes[local.goad_id], + "Standard_D2s_v3", + ) lab_config = jsondecode(file("${get_repo_root()}/ad/GOAD/data/${local.env}-config.json")) admin_password = local.lab_config.lab.hosts[local.goad_id].local_admin_password @@ -45,7 +49,7 @@ inputs = { env = local.env instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" computer_name = local.hostname - instance_size = "Standard_D2s_v3" + instance_size = local.instance_size source_image = { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" diff --git a/infra/azure/goad-deployment/test/env.hcl b/infra/azure/goad-deployment/test/env.hcl index b6a3cb4b..75d5fdc3 100644 --- a/infra/azure/goad-deployment/test/env.hcl +++ b/infra/azure/goad-deployment/test/env.hcl @@ -3,6 +3,15 @@ locals { env = "test" vnet_cidr = "10.8.0.0/16" + # DC02 runs the recurring attack-simulation tasks and needs additional memory. + goad_instance_sizes = { + dc01 = "Standard_D2s_v3" + dc02 = "Standard_D4s_v3" + dc03 = "Standard_D2s_v3" + srv02 = "Standard_D2s_v3" + srv03 = "Standard_D2s_v3" + } + bastion_sku = "Standard" bastion_subnet_cidr = "10.8.2.0/26" bastion_tunneling_enabled = true