From dcd087c1a96fefaa1207bde449a4a9114ae79f1e Mon Sep 17 00:00:00 2001 From: Jayson Grace Date: Mon, 6 Apr 2026 13:52:59 -0600 Subject: [PATCH 1/2] feat: add GOAD test environment with reusable templates and config-driven secrets **Added:** - Introduced a new GOAD test environment under `infra/goad-deployment/test/` - Added environment configuration (`env.hcl`) for the test environment, setting deployment name, AWS account ID, environment, and VPC CIDR - Created regional configuration (`region.hcl`) for `us-east-2` - Implemented a new VPC network module for the test environment with SSM/S3 VPC endpoints and tagging - Added reusable PowerShell user data templates for domain controllers and member servers, ensuring TLS 1.2, SSM agent installation, and secure admin/ansible account setup - Added wrapper script templates for injecting compressed, base64-encoded PowerShell user data - Added terragrunt configuration for deploying domain controllers (`dc01`, `dc02`, `dc03`) and member servers (`srv02`, `srv03`) in the test environment, sourcing secrets and host metadata from a single config file - Introduced a comprehensive test lab configuration in `ad/GOAD/data/test-config.json` defining hosts, domains, users, groups, ACLs, and vulnerabilities for the test environment **Changed:** - Added prominent region-specific AMI ID warnings and marketplace reference comments to all AWS provider `linux.tf` and `windows.tf` files for clarity - Updated `infra/goad-deployment/host.hcl` to use `find_in_parent_folders` for locating `host-registry.yaml`, improving portability - Modified `infra/goad-deployment/staging/env.hcl` to auto-discover the AWS account ID using `get_aws_account_id()` - Refactored DC and server terragrunt modules (`dc01`, `dc02`, `dc03`, `srv02`, `srv03`) in `staging/us-west-1/goad`: - Now read admin passwords directly from the lab config JSON for single source of truth - Use mock outputs for dependencies to support `init`, `validate`, `plan` without AWS resources - Updated Windows AMI lookup logic to filter by AMI name patterns (`goad-dc-base-*`, `goad-member-base-2016-*`, etc.), removing hardcoded AMI IDs and supporting most recent self-owned images - Improved documentation comments and streamlined input blocks --- ad/DRACARYS/providers/aws/linux.tf | 4 + ad/DRACARYS/providers/aws/windows.tf | 5 + ad/GOAD-Light/providers/aws/windows.tf | 4 + ad/GOAD-Mini/providers/aws/linux.tf | 4 + ad/GOAD-Mini/providers/aws/windows.tf | 4 + ad/GOAD-variant-1/providers/aws/linux.tf | 4 + ad/GOAD-variant-1/providers/aws/windows.tf | 5 + ad/GOAD/data/test-config.json | 681 ++++++++++++++++++ ad/GOAD/providers/aws/windows.tf | 5 + ad/NHA/providers/aws/windows.tf | 5 + ad/SCCM/providers/aws/windows.tf | 5 + infra/goad-deployment/host.hcl | 2 +- infra/goad-deployment/staging/env.hcl | 2 +- .../us-west-1/goad/dc01/terragrunt.hcl | 17 +- .../us-west-1/goad/dc02/terragrunt.hcl | 16 +- .../us-west-1/goad/dc03/terragrunt.hcl | 16 +- .../us-west-1/goad/srv02/terragrunt.hcl | 17 +- .../us-west-1/goad/srv03/terragrunt.hcl | 17 +- infra/goad-deployment/test/env.hcl | 8 + .../goad/dc01/templates/user_data.ps1.tpl | 44 ++ .../dc01/templates/user_data_wrapper.ps1.tpl | 5 + .../test/us-east-2/goad/dc01/terragrunt.hcl | 121 ++++ .../goad/dc02/templates/user_data.ps1.tpl | 44 ++ .../dc02/templates/user_data_wrapper.ps1.tpl | 5 + .../test/us-east-2/goad/dc02/terragrunt.hcl | 120 +++ .../goad/dc03/templates/user_data.ps1.tpl | 44 ++ .../dc03/templates/user_data_wrapper.ps1.tpl | 5 + .../test/us-east-2/goad/dc03/terragrunt.hcl | 120 +++ .../goad/srv02/templates/user_data.ps1.tpl | 44 ++ .../srv02/templates/user_data_wrapper.ps1.tpl | 5 + .../test/us-east-2/goad/srv02/terragrunt.hcl | 120 +++ .../goad/srv03/templates/user_data.ps1.tpl | 44 ++ .../srv03/templates/user_data_wrapper.ps1.tpl | 5 + .../test/us-east-2/goad/srv03/terragrunt.hcl | 120 +++ .../test/us-east-2/network/terragrunt.hcl | 57 ++ .../goad-deployment/test/us-east-2/region.hcl | 3 + 36 files changed, 1702 insertions(+), 25 deletions(-) create mode 100644 ad/GOAD/data/test-config.json create mode 100644 infra/goad-deployment/test/env.hcl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data_wrapper.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc01/terragrunt.hcl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data_wrapper.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc02/terragrunt.hcl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data_wrapper.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/dc03/terragrunt.hcl create mode 100644 infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data_wrapper.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/srv02/terragrunt.hcl create mode 100644 infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data_wrapper.ps1.tpl create mode 100644 infra/goad-deployment/test/us-east-2/goad/srv03/terragrunt.hcl create mode 100644 infra/goad-deployment/test/us-east-2/network/terragrunt.hcl create mode 100644 infra/goad-deployment/test/us-east-2/region.hcl diff --git a/ad/DRACARYS/providers/aws/linux.tf b/ad/DRACARYS/providers/aws/linux.tf index 45739841..322e59c6 100644 --- a/ad/DRACARYS/providers/aws/linux.tf +++ b/ad/DRACARYS/providers/aws/linux.tf @@ -1,3 +1,7 @@ +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "lx01" = { name = "lx01" linux_sku = "24_04-lts-gen2" diff --git a/ad/DRACARYS/providers/aws/windows.tf b/ad/DRACARYS/providers/aws/windows.tf index e1da7885..1af8eb3e 100644 --- a/ad/DRACARYS/providers/aws/windows.tf +++ b/ad/DRACARYS/providers/aws/windows.tf @@ -1,6 +1,11 @@ # Standard_B2s : 2 CPU / 4GB # Standard_B2ms : 2CPU / 8GB # Standard_B4ms : 4 cpu / 16 GB + +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "dracarys.lab" diff --git a/ad/GOAD-Light/providers/aws/windows.tf b/ad/GOAD-Light/providers/aws/windows.tf index 5e5b3906..8a80f75b 100644 --- a/ad/GOAD-Light/providers/aws/windows.tf +++ b/ad/GOAD-Light/providers/aws/windows.tf @@ -1,3 +1,7 @@ +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "sevenkingdoms.local" diff --git a/ad/GOAD-Mini/providers/aws/linux.tf b/ad/GOAD-Mini/providers/aws/linux.tf index c40117d8..0054364c 100644 --- a/ad/GOAD-Mini/providers/aws/linux.tf +++ b/ad/GOAD-Mini/providers/aws/linux.tf @@ -1,3 +1,7 @@ +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + # "lx01" = { # name = "lx01" # linux_sku = "22_04-lts-gen2" diff --git a/ad/GOAD-Mini/providers/aws/windows.tf b/ad/GOAD-Mini/providers/aws/windows.tf index e406ec80..55d2618b 100644 --- a/ad/GOAD-Mini/providers/aws/windows.tf +++ b/ad/GOAD-Mini/providers/aws/windows.tf @@ -1,3 +1,7 @@ +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "sevenkingdoms.local" diff --git a/ad/GOAD-variant-1/providers/aws/linux.tf b/ad/GOAD-variant-1/providers/aws/linux.tf index c40117d8..0054364c 100644 --- a/ad/GOAD-variant-1/providers/aws/linux.tf +++ b/ad/GOAD-variant-1/providers/aws/linux.tf @@ -1,3 +1,7 @@ +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + # "lx01" = { # name = "lx01" # linux_sku = "22_04-lts-gen2" diff --git a/ad/GOAD-variant-1/providers/aws/windows.tf b/ad/GOAD-variant-1/providers/aws/windows.tf index 40b3c2c3..c9e714d5 100644 --- a/ad/GOAD-variant-1/providers/aws/windows.tf +++ b/ad/GOAD-variant-1/providers/aws/windows.tf @@ -1,6 +1,11 @@ # t2.medium = 2cpu / 4GB # t2.large = 2cpu / 8GB # t2.xlarge = 4cpu / 16GB + +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "deltasystems.local" diff --git a/ad/GOAD/data/test-config.json b/ad/GOAD/data/test-config.json new file mode 100644 index 00000000..773aba24 --- /dev/null +++ b/ad/GOAD/data/test-config.json @@ -0,0 +1,681 @@ +{ +"lab" : { + "hosts" : { + "dc01" : { + "hostname" : "kingslanding", + "type" : "dc", + "local_admin_password": "qjQ!bcwXKU!3yBrDM2VU", + "domain" : "sevenkingdoms.local", + "path" : "DC=sevenkingdoms,DC=local", + "local_groups" : { + "Administrators" : [ + "sevenkingdoms\\robert.baratheon", + "sevenkingdoms\\cersei.lannister", + "sevenkingdoms\\DragonRider" + ], + "Remote Desktop Users" : [ + "sevenkingdoms\\Small Council", + "sevenkingdoms\\Baratheon" + ] + }, + "scripts" : ["sidhistory.ps1"], + "vulns" : ["disable_firewall"], + "security": ["account_is_sensitive", "audit_policy"], + "security_vars": { + "account_is_sensitive" : { "renly": {"account" : "renly.baratheon"} } + } + }, + "dc02" : { + "hostname" : "winterfell", + "type" : "dc", + "local_admin_password": "VExkHyfsKTW_HMNA7fQy", + "domain" : "north.sevenkingdoms.local", + "path" : "DC=north,DC=sevenkingdoms,DC=local", + "local_groups" : { + "Administrators" : [ + "north\\eddard.stark", + "north\\catelyn.stark", + "north\\robb.stark" + ], + "Remote Desktop Users" : [ + "north\\Stark" + ] + }, + "scripts" : [ + "asrep_roasting.ps1", + "constrained_delegation_use_any.ps1", + "constrained_delegation_kerb_only.ps1", + "ntlm_relay.ps1", + "responder.ps1", + "gpo_abuse.ps1", + "rdp_scheduler.ps1", + "unconstrained_delegation_user.ps1" + ], + "vulns" : ["disable_firewall","directory", "credentials", "autologon", "files", "enable_llmnr", "enable_nbt_ns", "shares", "anonymous_enum"], + "vulns_vars" : { + "directory": { + "setup": "C:\\setup" + }, + "credentials" : { + "TERMSRV/castelblack": { + "username" : "north\\robb.stark", + "secret" : "sexywolfy", + "runas" : "north\\robb.stark", + "runas_password" : "sexywolfy" + } + }, + "autologon" : { + "robb.stark" : { + "username" : "north\\robb.stark", + "password" : "sexywolfy" + } + }, + "files" : { + "rdp" : { + "src" : "dc02/bot_rdp.ps1", + "dest" : "C:\\setup\\bot_rdp.ps1" + }, + "sysvol_fake_script": { + "src" : "dc02/sysvol_scripts/script.ps1", + "dest": "C:\\Windows\\SYSVOL\\domain\\scripts\\script.ps1" + }, + "sysvol_secret": { + "src" : "dc02/sysvol_scripts/secret.ps1", + "dest": "C:\\Windows\\SYSVOL\\domain\\scripts\\secret.ps1" + } + } + }, + "security": ["audit_policy"] + }, + "srv02" : { + "hostname" : "castelblack", + "type" : "server", + "local_admin_password": "VExkHyfsKTW_HMNA7fQy", + "domain" : "north.sevenkingdoms.local", + "path" : "DC=north,DC=sevenkingdoms,DC=local", + "use_laps": false, + "local_groups" : { + "Administrators" : [ + "north\\jeor.mormont" + ], + "Remote Desktop Users" : [ + "north\\Night Watch", + "north\\Mormont", + "north\\Stark" + ] + }, + "scripts" : [], + "vulns" : ["directory", "disable_firewall", "openshares", "files", "permissions"], + "vulns_vars" : { + "directory": { + "shares": "C:\\shares", + "all": "C:\\shares\\all" + }, + "files" : { + "website" : { + "src" : "srv02/wwwroot", + "dest" : "C:\\inetpub\\" + }, + "letter_in_shares": { + "src" : "srv02/all/arya.txt", + "dest": "C:\\shares\\all\\arya.txt" + } + }, + "permissions" : { + "IIS_IUSRS_upload": { + "path" : "C:\\inetpub\\wwwroot\\upload", + "user" : "IIS_IUSRS", + "rights" : "FullControl" + } + } + }, + "mssql":{ + "sa_password": "Sup1_sa_P@ssw0rd!", + "svcaccount" : "sql_svc", + "sysadmins" : [ + "NORTH\\jon.snow" + ], + "executeaslogin" : { + "NORTH\\samwell.tarly" : "sa", + "NORTH\\brandon.stark" : "NORTH\\jon.snow" + }, + "executeasuser" : { + "arya_master_dbo": { + "user": "NORTH\\arya.stark", + "db" : "master", + "impersonate" : "dbo" + }, + "arya_dbms_dbo": { + "user": "NORTH\\arya.stark", + "db" : "msdb", + "impersonate" : "dbo" + } + }, + "linked_servers": { + "BRAAVOS" : { + "data_src": "braavos.essos.local", + "users_mapping": [ + {"local_login": "NORTH\\jon.snow","remote_login": "sa", "remote_password": "sa_P@ssw0rd!Ess0s"} + ] + } + } + } + }, + "dc03" : { + "hostname" : "meereen", + "type" : "dc", + "local_admin_password": "M!BbXzL48D9mH9dQzp*e", + "domain" : "essos.local", + "path" : "DC=essos,DC=local", + "local_groups" : { + "Administrators" : [ + "essos\\daenerys.targaryen" + ], + "Remote Desktop Users" : [ + "essos\\Targaryen" + ] + }, + "scripts" : ["asrep_roasting2.ps1"], + "vulns" : ["ntlmdowngrade", "disable_firewall"], + "security": ["audit_policy"] + }, + "srv03" : { + "hostname" : "braavos", + "type" : "server", + "local_admin_password": "M!BbXzL48D9mH9dQzp*e", + "domain" : "essos.local", + "path" : "DC=essos,DC=local", + "use_laps": true, + "local_groups" : { + "Administrators" : [ + "essos\\khal.drogo" + ] + }, + "Remote Desktop Users" : [ + "essos\\Dothraki" + ], + "scripts" : [], + "vulns" : ["openshares","disable_firewall"], + "security": ["enable_run_as_ppl"], + "mssql":{ + "sa_password": "sa_P@ssw0rd!Ess0s", + "svcaccount" : "sql_svc", + "sysadmins" : [ + "ESSOS\\khal.drogo" + ], + "executeaslogin" : { + "ESSOS\\jorah.mormont" : "sa" + }, + "executeasuser" : {}, + "linked_servers": { + "CASTELBLACK" : { + "data_src": "castelblack.north.sevenkingdoms.local", + "users_mapping": [ + {"local_login": "ESSOS\\khal.drogo","remote_login": "sa", "remote_password": "Sup1_sa_P@ssw0rd!"} + ] + } + } + } + } + }, + "domains" : { + "essos.local" : { + "dc": "dc03", + "domain_password" : "M!BbXzL48D9mH9dQzp*e", + "netbios_name": "ESSOS", + "ca_server": "Braavos", + "trust" : "sevenkingdoms.local", + "laps_path": "OU=Laps,DC=essos,DC=local", + "organisation_units" : { + }, + "laps_readers": [ + "jorah.mormont", + "Spys" + ], + "groups" : { + "universal" : {}, + "global" : { + "Targaryen" : { + "managed_by" : "viserys.targaryen", + "path" : "CN=Users,DC=essos,DC=local" + }, + "Dothraki" : { + "managed_by" : "khal.drogo", + "path" : "CN=Users,DC=essos,DC=local" + }, + "Dragons":{ + "managed_by" : "Administrator", + "path" : "CN=Users,DC=essos,DC=local" + }, + "QueenProtector":{ + "managed_by" : "Administrator", + "path" : "CN=Users,DC=essos,DC=local", + "members" : ["ESSOS\\Dragons"] + }, + "Domain Admins":{ + "managed_by" : "Administrator", + "path" : "CN=Users,DC=essos,DC=local", + "members" : ["ESSOS\\QueenProtector"] + } + }, + "domainlocal" : { + "DragonsFriends" : { + "managed_by" : "daenerys.targaryen", + "path" : "CN=Users,DC=essos,DC=local" + }, + "Spys" : { + "path" : "CN=Users,DC=essos,DC=local" + } + } + }, + "multi_domain_groups_member" : { + "DragonsFriends" : [ + "sevenkingdoms.local\\tyron.lannister", + "essos.local\\daenerys.targaryen" + ], + "Spys" : [ + "sevenkingdoms.local\\Small Council" + ] + }, + "gmsa" : { + "gmsa_account": { + "gMSA_Name" : "gmsaDragon", + "gMSA_FQDN" : "gmsaDragon.essos.local", + "gMSA_SPNs" : ["HTTP/braavos", "HTTP/braavos.essos.local"], + "gMSA_HostNames" : ["braavos"] + } + }, + "acls" : { + "GenericAll_khal_viserys" : {"for": "khal.drogo", "to": "viserys.targaryen", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_spy_jorah" : {"for": "Spys", "to": "jorah.mormont", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_khal_esc4" : {"for": "khal.drogo", "to": "CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=essos,DC=local", "right": "GenericAll", "inheritance": "None"}, + "WriteProperty_petyer_domadmin" : {"for": "viserys.targaryen", "to": "jorah.mormont", "right": "WriteProperty", "inheritance": "All"}, + "GenericWrite_DragonsFriends_braavos" : {"for": "DragonsFriends", "to": "braavos$", "right": "GenericWrite", "inheritance": "None"}, + "GenericAll_missandei_khal" : {"for": "missandei", "to": "khal.drogo", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_gmsaDragon_drogo" : {"for": "gmsaDragon$", "to": "drogon", "right": "GenericAll", "inheritance": "None"} + }, + "users" : { + "daenerys.targaryen" : { + "firstname" : "daenerys", + "surname" : "targaryen", + "password" : "BurnThemAll!", + "city" : "-", + "description" : "Darnerys Targaryen", + "groups" : ["Targaryen", "Domain Admins"], + "path" : "CN=Users,DC=essos,DC=local" + }, + "viserys.targaryen" : { + "firstname" : "viserys", + "surname" : "targaryen", + "password" : "GoldCrown", + "city" : "-", + "description" : "Viserys Targaryen", + "groups" : ["Targaryen"], + "path" : "CN=Users,DC=essos,DC=local" + }, + "khal.drogo" : { + "firstname" : "khal", + "surname" : "drogo", + "password" : "horse", + "city" : "-", + "description" : "Khal Drogo", + "groups" : ["Dothraki"], + "path" : "CN=Users,DC=essos,DC=local" + }, + "jorah.mormont" : { + "firstname" : "jorah", + "surname" : "mormont", + "password" : "H0nnor!", + "city" : "-", + "description" : "Jorah Mormont", + "groups" : ["Targaryen"], + "path" : "CN=Users,DC=essos,DC=local" + }, + "missandei" : { + "firstname" : "missandei", + "surname" : "-", + "password" : "fr3edom", + "city" : "-", + "description" : "missandei", + "groups" : [], + "path" : "CN=Users,DC=essos,DC=local" + }, + "drogon" : { + "firstname" : "drogon", + "surname" : "-", + "password" : "Dracarys", + "city" : "-", + "description" : "drogon", + "groups" : ["Dragons"], + "path" : "CN=Users,DC=essos,DC=local" + }, + "sql_svc" : { + "firstname" : "sql", + "surname" : "service", + "password" : "YouWillNotKerboroast1ngMeeeeee", + "city" : "-", + "description" : "sql service", + "groups" : [], + "path" : "CN=Users,DC=essos,DC=local", + "spns" : ["MSSQLSvc/braavos.essos.local:1433","MSSQLSvc/braavos.essos.local"] + } + } + }, + "north.sevenkingdoms.local" : { + "dc": "dc02", + "domain_password" : "VExkHyfsKTW_HMNA7fQy", + "netbios_name": "NORTH", + "trust" : "", + "laps_path": "OU=Laps,DC=north,DC=sevenkingdoms,DC=local", + "organisation_units" : { + }, + "groups" : { + "universal" : {}, + "global" : { + "Stark" : { + "managed_by" : "eddard.stark", + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "Night Watch" : { + "managed_by" : "jeor.mormont", + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "Mormont" : { + "managed_by" : "jeor.mormont", + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + } + }, + "domainlocal" : { + "AcrossTheSea" : { + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + } + } + }, + "multi_domain_groups_member" : {}, + "acls" : { + "anonymous_rpc" : {"for": "NT AUTHORITY\\ANONYMOUS LOGON", "to": "DC=North,DC=sevenkingdoms,DC=local", "right": "ReadProperty", "inheritance": "All"}, + "anonymous_rpc2" : {"for": "NT AUTHORITY\\ANONYMOUS LOGON", "to": "DC=North,DC=sevenkingdoms,DC=local", "right": "GenericExecute", "inheritance": "All"} + }, + "users" : { + "arya.stark" : { + "firstname" : "Arya", + "surname" : "Stark", + "password" : "Needle", + "city" : "Winterfell", + "description" : "Arya Stark", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "eddard.stark" : { + "firstname" : "Eddard", + "surname" : "Stark", + "password" : "FightP3aceAndHonor!", + "city" : "King's Landing", + "description" : "Eddard Stark", + "groups" : ["Stark", "Domain Admins"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "catelyn.stark" : { + "firstname" : "Catelyn", + "surname" : "Stark", + "password" : "robbsansabradonaryarickon", + "city" : "King's Landing", + "description" : "Catelyn Stark", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "robb.stark" : { + "firstname" : "Robb", + "surname" : "Stark", + "password" : "sexywolfy", + "city" : "Winterfell", + "description" : "Robb Stark", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "sansa.stark" : { + "firstname" : "Sansa", + "surname" : "Stark", + "password" : "345ertdfg", + "city" : "Winterfell", + "description" : "Sansa Stark", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local", + "spns" : ["HTTP/eyrie.north.sevenkingdoms.local"] + }, + "brandon.stark" : { + "firstname" : "Brandon", + "surname" : "Stark", + "password" : "iseedeadpeople", + "city" : "Winterfell", + "description" : "Brandon Stark", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "rickon.stark" : { + "firstname" : "Rickon", + "surname" : "Stark", + "password" : "Winter2022", + "city" : "Winterfell", + "description" : "Rickon Stark", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "hodor" : { + "firstname" : "hodor", + "surname" : "hodor", + "password" : "hodor", + "city" : "Winterfell", + "description" : "Brainless Giant", + "groups" : ["Stark"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "jon.snow" : { + "firstname" : "Jon", + "surname" : "Snow", + "password" : "iknownothing", + "city" : "Castel Black", + "description" : "Jon Snow", + "groups" : ["Stark", "Night Watch"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local", + "spns" : ["HTTP/thewall.north.sevenkingdoms.local"] + }, + "samwell.tarly" : { + "firstname" : "Samwell", + "surname" : "Tarly", + "password" : "Heartsbane", + "city" : "Castel Black", + "description" : "Samwell Tarly (Password : Heartsbane)", + "groups" : ["Night Watch"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "jeor.mormont" : { + "firstname" : "Jeor", + "surname" : "Mormont", + "password" : "_L0ngCl@w_", + "city" : "Castel Black", + "description" : "Jeor Mormont", + "groups" : ["Night Watch", "Mormont"], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local" + }, + "sql_svc" : { + "firstname" : "sql", + "surname" : "service", + "password" : "YouWillNotKerboroast1ngMeeeeee", + "city" : "-", + "description" : "sql service", + "groups" : [], + "path" : "CN=Users,DC=North,DC=sevenkingdoms,DC=local", + "spns" : ["MSSQLSvc/castelblack.north.sevenkingdoms.local:1433","MSSQLSvc/castelblack.north.sevenkingdoms.local"] + } + } + }, + "sevenkingdoms.local" : { + "dc": "dc01", + "domain_password" : "qjQ!bcwXKU!3yBrDM2VU", + "netbios_name": "SEVENKINGDOMS", + "trust" : "essos.local", + "laps_path": "OU=Laps,DC=sevenkingdoms,DC=local", + "organisation_units" : { + "Vale" : { "path" : "DC=sevenkingdoms,DC=local"}, + "IronIslands" : { "path" : "DC=sevenkingdoms,DC=local"}, + "Riverlands" : { "path" : "DC=sevenkingdoms,DC=local"}, + "Crownlands" : { "path" : "DC=sevenkingdoms,DC=local"}, + "Stormlands" : { "path" : "DC=sevenkingdoms,DC=local"}, + "Westerlands" : { "path" : "DC=sevenkingdoms,DC=local"}, + "Reach" : { "path" : "DC=sevenkingdoms,DC=local"}, + "Dorne" : { "path" : "DC=sevenkingdoms,DC=local"} + }, + "groups" : { + "universal" : {}, + "global" : { + "Lannister" : { + "managed_by" : "tywin.lannister", + "path" : "OU=Westerlands,DC=sevenkingdoms,DC=local" + }, + "Baratheon" : { + "managed_by" : "robert.baratheon", + "path" : "OU=Stormlands,DC=sevenkingdoms,DC=local" + }, + "Small Council" : { + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "DragonStone" : { + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "KingsGuard" : { + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "DragonRider" : { + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + } + }, + "domainlocal" : { + "AcrossTheNarrowSea" : { + "path" : "CN=Users,DC=sevenkingdoms,DC=local" + } + } + }, + "multi_domain_groups_member" : { + "AcrossTheNarrowSea" : [ + "essos.local\\daenerys.targaryen" + ] + }, + "acls" : { + "forcechangepassword_tywin_jaime" : {"for": "tywin.lannister", "to": "jaime.lannister", "right": "Ext-User-Force-Change-Password", "inheritance": "None"}, + "GenericWrite_on_user_jaimie_joffrey" : {"for": "jaime.lannister", "to": "joffrey.baratheon", "right": "GenericWrite", "inheritance": "None"}, + "Writedacl_joffrey_tyron" : {"for": "joffrey.baratheon", "to": "tyron.lannister", "right": "WriteDacl", "inheritance": "None"}, + "self-self-membership-on-group_tyron_small_council" : {"for": "tyron.lannister", "to": "Small Council", "right": "Ext-Self-Self-Membership", "inheritance": "None"}, + "addmember_smallcouncil_DragonStone" : {"for": "Small Council", "to": "DragonStone", "right": "Ext-Write-Self-Membership", "inheritance": "All"}, + "write_owner_dragonstone_kingsguard" : {"for": "DragonStone", "to": "KingsGuard", "right": "WriteOwner", "inheritance": "None"}, + "GenericAll_kingsguard_stanis" : {"for": "KingsGuard", "to": "stannis.baratheon", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_stanis_dc" : {"for": "stannis.baratheon", "to": "kingslanding$", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_group_acrrosdom_dc" : {"for": "AcrossTheNarrowSea", "to": "kingslanding$", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_varys_domadmin" : {"for": "lord.varys", "to": "Domain Admins", "right": "GenericAll", "inheritance": "None"}, + "GenericAll_varys_domadmin_holder" : {"for": "lord.varys", "to": "CN=AdminSDHolder,CN=System,DC=sevenkingdoms,DC=local", "right": "GenericAll", "inheritance": "None"}, + "WriteDACL_renly_Crownlands" : {"for": "renly.baratheon", "to": "OU=Crownlands,DC=sevenkingdoms,DC=local", "right": "WriteDacl", "inheritance": "None"} + }, + "users" : { + "tywin.lannister" : { + "firstname" : "Tywin", + "surname" : "Lanister", + "password" : "powerkingftw135", + "city" : "Casterly Rock", + "description" : "Tywin Lanister", + "groups" : ["Lannister"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "jaime.lannister" : { + "firstname" : "Jaime", + "surname" : "Lanister", + "password" : "cersei", + "city" : "King's Landing", + "description" : "Jaime Lanister", + "groups" : ["Lannister"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "cersei.lannister" : { + "firstname" : "Cersei", + "surname" : "Lanister", + "password" : "il0vejaime", + "city" : "King's Landing", + "description" : "Cersei Lanister", + "groups" : ["Lannister","Baratheon","Domain Admins","Small Council"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "tyron.lannister" : { + "firstname" : "Tyron", + "surname" : "Lanister", + "password" : "Alc00L&S3x", + "city" : "King's Landing", + "description" : "Tyron Lanister", + "groups" : ["Lannister"], + "path" : "OU=Westerlands,DC=sevenkingdoms,DC=local" + }, + "robert.baratheon" : { + "firstname" : "Robert", + "surname" : "Baratheon", + "password" : "iamthekingoftheworld", + "city" : "King's Landing", + "description" : "Robert Lanister", + "groups" : ["Baratheon","Domain Admins","Small Council","Protected Users"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "joffrey.baratheon" : { + "firstname" : "Joffrey", + "surname" : "Baratheon", + "password" : "1killerlion", + "city" : "King's Landing", + "description" : "Joffrey Baratheon", + "groups" : ["Baratheon","Lannister"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "renly.baratheon" : { + "firstname" : "Renly", + "surname" : "Baratheon", + "password" : "lorastyrell", + "city" : "King's Landing", + "description" : "Renly Baratheon", + "groups" : ["Baratheon","Small Council"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "stannis.baratheon" : { + "firstname" : "Stannis", + "surname" : "Baratheon", + "password" : "Drag0nst0ne", + "city" : "King's Landing", + "description" : "Stannis Baratheon", + "groups" : ["Baratheon","Small Council"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "petyer.baelish" : { + "firstname" : "Petyer", + "surname" : "Baelish", + "password" : "@littlefinger@", + "city" : "King's Landing", + "description" : "Petyer Baelish", + "groups" : ["Small Council"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "lord.varys" : { + "firstname" : "Lord", + "surname" : "Varys", + "password" : "_W1sper_$", + "city" : "King's Landing", + "description" : "Lord Varys", + "groups" : ["Small Council"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + }, + "maester.pycelle" : { + "firstname" : "Maester", + "surname" : "Pycelle", + "password" : "MaesterOfMaesters", + "city" : "King's Landing", + "description" : "Maester Pycelle", + "groups" : ["Small Council"], + "path" : "OU=Crownlands,DC=sevenkingdoms,DC=local" + } + } + } + } +}} diff --git a/ad/GOAD/providers/aws/windows.tf b/ad/GOAD/providers/aws/windows.tf index de4f9904..5f5e79a3 100644 --- a/ad/GOAD/providers/aws/windows.tf +++ b/ad/GOAD/providers/aws/windows.tf @@ -1,6 +1,11 @@ # t2.medium = 2cpu / 4GB # t2.large = 2cpu / 8GB # t2.xlarge = 4cpu / 16GB + +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "sevenkingdoms.local" diff --git a/ad/NHA/providers/aws/windows.tf b/ad/NHA/providers/aws/windows.tf index 3ced7649..f4143d2d 100644 --- a/ad/NHA/providers/aws/windows.tf +++ b/ad/NHA/providers/aws/windows.tf @@ -1,6 +1,11 @@ # t2.medium = 2cpu / 4GB # t2.large = 2cpu / 8GB # t2.xlarge = 4cpu / 16GB + +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "ninja.hack" diff --git a/ad/SCCM/providers/aws/windows.tf b/ad/SCCM/providers/aws/windows.tf index bf698f01..6055336f 100644 --- a/ad/SCCM/providers/aws/windows.tf +++ b/ad/SCCM/providers/aws/windows.tf @@ -1,6 +1,11 @@ # t2.medium = 2cpu / 4GB # t2.large = 2cpu / 8GB # t2.xlarge = 4cpu / 16GB + +# NOTE: AMI IDs below are region-specific (originally eu-west-1). +# Replace with AMI IDs for your target AWS region. +# See: https://aws.amazon.com/marketplace for Windows Server base AMIs + "dc01" = { name = "dc01" domain = "sccm.lab" diff --git a/infra/goad-deployment/host.hcl b/infra/goad-deployment/host.hcl index ebe22cbe..570dbbce 100644 --- a/infra/goad-deployment/host.hcl +++ b/infra/goad-deployment/host.hcl @@ -1,5 +1,5 @@ locals { - registry_path = "${get_terragrunt_dir()}/../host-registry.yaml" + registry_path = find_in_parent_folders("host-registry.yaml") host_registry = yamldecode(file(local.registry_path)) terragrunt_dir = get_terragrunt_dir() diff --git a/infra/goad-deployment/staging/env.hcl b/infra/goad-deployment/staging/env.hcl index a3909311..f89262e7 100644 --- a/infra/goad-deployment/staging/env.hcl +++ b/infra/goad-deployment/staging/env.hcl @@ -2,7 +2,7 @@ # This is automatically pulled in by the root terragrunt.hcl configuration. locals { deployment_name = "goad" # Change to your deployment name - aws_account_id = "CHANGE_ME" # Your AWS account ID + aws_account_id = get_aws_account_id() env = "staging" # Environment name (dev, staging, prod) vpc_cidr = "10.1.0.0/16" # VPC CIDR block for this environment } diff --git a/infra/goad-deployment/staging/us-west-1/goad/dc01/terragrunt.hcl b/infra/goad-deployment/staging/us-west-1/goad/dc01/terragrunt.hcl index f820cd8f..0441a2d8 100644 --- a/infra/goad-deployment/staging/us-west-1/goad/dc01/terragrunt.hcl +++ b/infra/goad-deployment/staging/us-west-1/goad/dc01/terragrunt.hcl @@ -24,8 +24,9 @@ locals { role = include.host.locals.role goad_id = include.host.locals.goad_id - # Set admin password via terraform.tfvars or TF_VAR_admin_password env var - admin_password = get_env("TF_VAR_goad_dc01_password", "CHANGE_ME") + # Read admin password from GOAD lab config (single source of truth) + 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 } terraform { @@ -34,6 +35,12 @@ terraform { dependency "network" { config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] } include { @@ -56,15 +63,15 @@ inputs = { s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" } - # Windows AMI - replace with your AMI built from warpgate-templates/goad-dc-base + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) windows_os = "Windows_Server" windows_os_version = "2019-English-Full-Base" windows_ami_owners = ["self"] additional_windows_ami_filters = [ { - name = "image-id" - values = ["CHANGE_ME"] # Your goad-dc-base AMI ID + name = "name" + values = ["goad-dc-base-*"] # warpgate-templates/goad-dc-base } ] diff --git a/infra/goad-deployment/staging/us-west-1/goad/dc02/terragrunt.hcl b/infra/goad-deployment/staging/us-west-1/goad/dc02/terragrunt.hcl index e686b854..5c073bbe 100644 --- a/infra/goad-deployment/staging/us-west-1/goad/dc02/terragrunt.hcl +++ b/infra/goad-deployment/staging/us-west-1/goad/dc02/terragrunt.hcl @@ -23,7 +23,9 @@ locals { role = include.host.locals.role goad_id = include.host.locals.goad_id - admin_password = get_env("TF_VAR_goad_dc02_password", "CHANGE_ME") + # Read admin password from GOAD lab config (single source of truth) + 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 } terraform { @@ -32,6 +34,12 @@ terraform { dependency "network" { config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] } include { @@ -54,15 +62,15 @@ inputs = { s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" } - # Windows AMI - replace with your AMI built from warpgate-templates/goad-dc-base + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) windows_os = "Windows_Server" windows_os_version = "2019-English-Full-Base" windows_ami_owners = ["self"] additional_windows_ami_filters = [ { - name = "image-id" - values = ["CHANGE_ME"] # Your goad-dc-base AMI ID + name = "name" + values = ["goad-dc-base-*"] # warpgate-templates/goad-dc-base } ] diff --git a/infra/goad-deployment/staging/us-west-1/goad/dc03/terragrunt.hcl b/infra/goad-deployment/staging/us-west-1/goad/dc03/terragrunt.hcl index 3df4ec51..668f058a 100644 --- a/infra/goad-deployment/staging/us-west-1/goad/dc03/terragrunt.hcl +++ b/infra/goad-deployment/staging/us-west-1/goad/dc03/terragrunt.hcl @@ -23,7 +23,9 @@ locals { role = include.host.locals.role goad_id = include.host.locals.goad_id - admin_password = get_env("TF_VAR_goad_dc03_password", "CHANGE_ME") + # Read admin password from GOAD lab config (single source of truth) + 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 } terraform { @@ -32,6 +34,12 @@ terraform { dependency "network" { config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] } include { @@ -54,15 +62,15 @@ inputs = { s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" } - # Windows AMI - replace with your AMI built from warpgate-templates/goad-dc-base-2016 + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) windows_os = "Windows_Server" windows_os_version = "2016-English-Full-Base" windows_ami_owners = ["self"] additional_windows_ami_filters = [ { - name = "image-id" - values = ["CHANGE_ME"] # Your goad-dc-base-2016 AMI ID + name = "name" + values = ["goad-dc-base-2016-*"] # warpgate-templates/goad-dc-base-2016 } ] diff --git a/infra/goad-deployment/staging/us-west-1/goad/srv02/terragrunt.hcl b/infra/goad-deployment/staging/us-west-1/goad/srv02/terragrunt.hcl index 46005572..11385662 100644 --- a/infra/goad-deployment/staging/us-west-1/goad/srv02/terragrunt.hcl +++ b/infra/goad-deployment/staging/us-west-1/goad/srv02/terragrunt.hcl @@ -23,8 +23,9 @@ locals { role = include.host.locals.role goad_id = include.host.locals.goad_id - # SRV02 uses DC02's password (it joins the north subdomain) - admin_password = get_env("TF_VAR_goad_dc02_password", "CHANGE_ME") + # Read admin password from GOAD lab config (single source of truth) + 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 } terraform { @@ -33,6 +34,12 @@ terraform { dependency "network" { config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] } include { @@ -55,15 +62,15 @@ inputs = { s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" } - # Windows AMI - replace with your AMI built from warpgate-templates/goad-mssql-base + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) windows_os = "Windows_Server" windows_os_version = "2019-English-Full-Base" windows_ami_owners = ["self"] additional_windows_ami_filters = [ { - name = "image-id" - values = ["CHANGE_ME"] # Your goad-mssql-base AMI ID + name = "name" + values = ["goad-mssql-base-*"] # warpgate-templates/goad-mssql-base } ] diff --git a/infra/goad-deployment/staging/us-west-1/goad/srv03/terragrunt.hcl b/infra/goad-deployment/staging/us-west-1/goad/srv03/terragrunt.hcl index 339dac88..18a6421a 100644 --- a/infra/goad-deployment/staging/us-west-1/goad/srv03/terragrunt.hcl +++ b/infra/goad-deployment/staging/us-west-1/goad/srv03/terragrunt.hcl @@ -23,8 +23,9 @@ locals { role = include.host.locals.role goad_id = include.host.locals.goad_id - # SRV03 uses DC03's password (it joins the essos domain) - admin_password = get_env("TF_VAR_goad_dc03_password", "CHANGE_ME") + # Read admin password from GOAD lab config (single source of truth) + 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 } terraform { @@ -33,6 +34,12 @@ terraform { dependency "network" { config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] } include { @@ -55,15 +62,15 @@ inputs = { s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" } - # Windows AMI - replace with your AMI built from warpgate-templates/goad-member-base-2016 + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) windows_os = "Windows_Server" windows_os_version = "2016-English-Full-Base" windows_ami_owners = ["self"] additional_windows_ami_filters = [ { - name = "image-id" - values = ["CHANGE_ME"] # Your goad-member-base-2016 AMI ID + name = "name" + values = ["goad-member-base-2016-*"] # warpgate-templates/goad-member-base-2016 } ] diff --git a/infra/goad-deployment/test/env.hcl b/infra/goad-deployment/test/env.hcl new file mode 100644 index 00000000..2712a77d --- /dev/null +++ b/infra/goad-deployment/test/env.hcl @@ -0,0 +1,8 @@ +# Set common variables for the test environment. +# This is automatically pulled in by the root terragrunt.hcl configuration. +locals { + deployment_name = "goad" + aws_account_id = get_aws_account_id() + env = "test" + vpc_cidr = "10.8.0.0/16" +} diff --git a/infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data.ps1.tpl new file mode 100644 index 00000000..bbc0ec7c --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data.ps1.tpl @@ -0,0 +1,44 @@ +# Add registry keys to enable TLS 1.2 at the OS level +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force | Out-Null +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'Enabled' -value '1' -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'Enabled' -value 1 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null + +# Enable strong cryptography on .NET Framework +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force + +# Force TLS 1.2 in current PowerShell session and create system-wide PowerShell profile +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Create AllSigned profile for all users +$allUsersAllHosts = "$env:windir\System32\WindowsPowerShell\v1.0\profile.ps1" +New-Item -Path $allUsersAllHosts -ItemType File -Force | Out-Null +Set-Content -Path $allUsersAllHosts -Value "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12" -Force + +# Set the local Administrator password +net user Administrator ${admin_password} /expires:never /y + +# Create ansible user, add to administrators group, and set password +net user ansible ${admin_password} /add /expires:never /y +net localgroup administrators ansible /add + +# Setup SSM Agent +$progressPreference = 'silentlyContinue' + +# Use WebClient instead of Invoke-WebRequest for SSM agent download too +$ssmUrl = "https://amazon-ssm-${aws_region}.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe" +$ssmOutput = "$env:TEMP\SSMAgent_latest.exe" +$webClient = New-Object System.Net.WebClient +$webClient.DownloadFile($ssmUrl, $ssmOutput) + +# Install SSM agent +Start-Process -FilePath $env:TEMP\SSMAgent_latest.exe -ArgumentList "/S" -Wait +Remove-Item -Force $env:TEMP\SSMAgent_latest.exe +Restart-Service AmazonSSMAgent + +# Rename computer and restart +Rename-Computer -NewName "${hostname}" -Force +Restart-Computer -Force diff --git a/infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data_wrapper.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data_wrapper.ps1.tpl new file mode 100644 index 00000000..4f83016f --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc01/templates/user_data_wrapper.ps1.tpl @@ -0,0 +1,5 @@ + +$EncodedUserData = "${compressed_user_data}" +$DecodedUserData = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($EncodedUserData)) +Invoke-Expression $DecodedUserData + diff --git a/infra/goad-deployment/test/us-east-2/goad/dc01/terragrunt.hcl b/infra/goad-deployment/test/us-east-2/goad/dc01/terragrunt.hcl new file mode 100644 index 00000000..0441a2d8 --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc01/terragrunt.hcl @@ -0,0 +1,121 @@ +# ============================================================================= +# DC01 - Primary Domain Controller for Seven Kingdoms +# AMI: Built from warpgate-templates/goad-dc-base (Windows Server 2019) +# ============================================================================= + +include "host" { + path = find_in_parent_folders("host.hcl") + expose = true +} + +locals { + env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + env = local.env_vars.locals.env + aws_region = local.region_vars.locals.aws_region + deployment_name = local.env_vars.locals.deployment_name + + # Host metadata from host-registry.yaml via host.hcl + hostname = include.host.locals.computer_name + friendly_name = include.host.locals.hostname + domain = include.host.locals.domain + os_type = include.host.locals.os_type + role = include.host.locals.role + goad_id = include.host.locals.goad_id + + # Read admin password from GOAD lab config (single source of truth) + 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 +} + +terraform { + source = "${get_repo_root()}/modules//terraform-aws-instance-factory" +} + +dependency "network" { + config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] +} + +include { + path = find_in_parent_folders("root.hcl") +} + +inputs = { + env = local.env + instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" + instance_type = "t3.medium" + os_type = local.os_type + enable_asg = false + subnet_id = dependency.network.outputs.private_subnet_ids[0] + vpc_id = dependency.network.outputs.vpc_id + + enable_ssm = true + + additional_iam_policies = { + cloudwatch_agent = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" + s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" + } + + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) + windows_os = "Windows_Server" + windows_os_version = "2019-English-Full-Base" + windows_ami_owners = ["self"] + + additional_windows_ami_filters = [ + { + name = "name" + values = ["goad-dc-base-*"] # warpgate-templates/goad-dc-base + } + ] + + ingress_rules = [ + { + description = "Allow all traffic from VPC CIDR" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [dependency.network.outputs.vpc_cidr] + }, + ] + + egress_rules = [ + { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + ] + + enable_monitoring = true + enable_metadata = true + require_imdsv2 = true + encrypt_volumes = true + root_volume_size = 100 + volume_type = "gp3" + + user_data = templatefile("${get_terragrunt_dir()}/templates/user_data_wrapper.ps1.tpl", { + compressed_user_data = base64encode(templatefile("${get_terragrunt_dir()}/templates/user_data.ps1.tpl", { + aws_region = local.aws_region, + hostname = local.hostname, + admin_password = local.admin_password + })) + }) + + tags = { + Environment = local.env + Project = "DreadGOAD" + Role = "DomainController" + Lab = "${local.deployment_name}-goad" + Name = "${local.deployment_name}-dreadgoad-${local.hostname}" + Domain = local.domain + ComputerName = local.hostname + } +} diff --git a/infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data.ps1.tpl new file mode 100644 index 00000000..bbc0ec7c --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data.ps1.tpl @@ -0,0 +1,44 @@ +# Add registry keys to enable TLS 1.2 at the OS level +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force | Out-Null +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'Enabled' -value '1' -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'Enabled' -value 1 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null + +# Enable strong cryptography on .NET Framework +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force + +# Force TLS 1.2 in current PowerShell session and create system-wide PowerShell profile +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Create AllSigned profile for all users +$allUsersAllHosts = "$env:windir\System32\WindowsPowerShell\v1.0\profile.ps1" +New-Item -Path $allUsersAllHosts -ItemType File -Force | Out-Null +Set-Content -Path $allUsersAllHosts -Value "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12" -Force + +# Set the local Administrator password +net user Administrator ${admin_password} /expires:never /y + +# Create ansible user, add to administrators group, and set password +net user ansible ${admin_password} /add /expires:never /y +net localgroup administrators ansible /add + +# Setup SSM Agent +$progressPreference = 'silentlyContinue' + +# Use WebClient instead of Invoke-WebRequest for SSM agent download too +$ssmUrl = "https://amazon-ssm-${aws_region}.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe" +$ssmOutput = "$env:TEMP\SSMAgent_latest.exe" +$webClient = New-Object System.Net.WebClient +$webClient.DownloadFile($ssmUrl, $ssmOutput) + +# Install SSM agent +Start-Process -FilePath $env:TEMP\SSMAgent_latest.exe -ArgumentList "/S" -Wait +Remove-Item -Force $env:TEMP\SSMAgent_latest.exe +Restart-Service AmazonSSMAgent + +# Rename computer and restart +Rename-Computer -NewName "${hostname}" -Force +Restart-Computer -Force diff --git a/infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data_wrapper.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data_wrapper.ps1.tpl new file mode 100644 index 00000000..4f83016f --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc02/templates/user_data_wrapper.ps1.tpl @@ -0,0 +1,5 @@ + +$EncodedUserData = "${compressed_user_data}" +$DecodedUserData = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($EncodedUserData)) +Invoke-Expression $DecodedUserData + diff --git a/infra/goad-deployment/test/us-east-2/goad/dc02/terragrunt.hcl b/infra/goad-deployment/test/us-east-2/goad/dc02/terragrunt.hcl new file mode 100644 index 00000000..5c073bbe --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc02/terragrunt.hcl @@ -0,0 +1,120 @@ +# ============================================================================= +# DC02 - Domain Controller for North Subdomain +# AMI: Built from warpgate-templates/goad-dc-base (Windows Server 2019) +# ============================================================================= + +include "host" { + path = find_in_parent_folders("host.hcl") + expose = true +} + +locals { + env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + env = local.env_vars.locals.env + aws_region = local.region_vars.locals.aws_region + deployment_name = local.env_vars.locals.deployment_name + + hostname = include.host.locals.computer_name + friendly_name = include.host.locals.hostname + domain = include.host.locals.domain + os_type = include.host.locals.os_type + role = include.host.locals.role + goad_id = include.host.locals.goad_id + + # Read admin password from GOAD lab config (single source of truth) + 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 +} + +terraform { + source = "${get_repo_root()}/modules//terraform-aws-instance-factory" +} + +dependency "network" { + config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] +} + +include { + path = find_in_parent_folders("root.hcl") +} + +inputs = { + env = local.env + instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" + instance_type = "t3.medium" + os_type = local.os_type + enable_asg = false + subnet_id = dependency.network.outputs.private_subnet_ids[0] + vpc_id = dependency.network.outputs.vpc_id + + enable_ssm = true + + additional_iam_policies = { + cloudwatch_agent = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" + s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" + } + + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) + windows_os = "Windows_Server" + windows_os_version = "2019-English-Full-Base" + windows_ami_owners = ["self"] + + additional_windows_ami_filters = [ + { + name = "name" + values = ["goad-dc-base-*"] # warpgate-templates/goad-dc-base + } + ] + + ingress_rules = [ + { + description = "Allow all traffic from VPC CIDR" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [dependency.network.outputs.vpc_cidr] + }, + ] + + egress_rules = [ + { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + ] + + enable_monitoring = true + enable_metadata = true + require_imdsv2 = true + encrypt_volumes = true + root_volume_size = 100 + volume_type = "gp3" + + user_data = templatefile("${get_terragrunt_dir()}/templates/user_data_wrapper.ps1.tpl", { + compressed_user_data = base64encode(templatefile("${get_terragrunt_dir()}/templates/user_data.ps1.tpl", { + aws_region = local.aws_region, + hostname = local.hostname, + admin_password = local.admin_password + })) + }) + + tags = { + Environment = local.env + Project = "DreadGOAD" + Role = "DomainController" + Lab = "${local.deployment_name}-goad" + Name = "${local.deployment_name}-dreadgoad-${local.hostname}" + Domain = local.domain + ComputerName = local.hostname + } +} diff --git a/infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data.ps1.tpl new file mode 100644 index 00000000..bbc0ec7c --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data.ps1.tpl @@ -0,0 +1,44 @@ +# Add registry keys to enable TLS 1.2 at the OS level +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force | Out-Null +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'Enabled' -value '1' -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'Enabled' -value 1 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null + +# Enable strong cryptography on .NET Framework +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force + +# Force TLS 1.2 in current PowerShell session and create system-wide PowerShell profile +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Create AllSigned profile for all users +$allUsersAllHosts = "$env:windir\System32\WindowsPowerShell\v1.0\profile.ps1" +New-Item -Path $allUsersAllHosts -ItemType File -Force | Out-Null +Set-Content -Path $allUsersAllHosts -Value "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12" -Force + +# Set the local Administrator password +net user Administrator ${admin_password} /expires:never /y + +# Create ansible user, add to administrators group, and set password +net user ansible ${admin_password} /add /expires:never /y +net localgroup administrators ansible /add + +# Setup SSM Agent +$progressPreference = 'silentlyContinue' + +# Use WebClient instead of Invoke-WebRequest for SSM agent download too +$ssmUrl = "https://amazon-ssm-${aws_region}.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe" +$ssmOutput = "$env:TEMP\SSMAgent_latest.exe" +$webClient = New-Object System.Net.WebClient +$webClient.DownloadFile($ssmUrl, $ssmOutput) + +# Install SSM agent +Start-Process -FilePath $env:TEMP\SSMAgent_latest.exe -ArgumentList "/S" -Wait +Remove-Item -Force $env:TEMP\SSMAgent_latest.exe +Restart-Service AmazonSSMAgent + +# Rename computer and restart +Rename-Computer -NewName "${hostname}" -Force +Restart-Computer -Force diff --git a/infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data_wrapper.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data_wrapper.ps1.tpl new file mode 100644 index 00000000..4f83016f --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc03/templates/user_data_wrapper.ps1.tpl @@ -0,0 +1,5 @@ + +$EncodedUserData = "${compressed_user_data}" +$DecodedUserData = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($EncodedUserData)) +Invoke-Expression $DecodedUserData + diff --git a/infra/goad-deployment/test/us-east-2/goad/dc03/terragrunt.hcl b/infra/goad-deployment/test/us-east-2/goad/dc03/terragrunt.hcl new file mode 100644 index 00000000..668f058a --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/dc03/terragrunt.hcl @@ -0,0 +1,120 @@ +# ============================================================================= +# DC03 - Domain Controller for Essos +# AMI: Built from warpgate-templates/goad-dc-base-2016 (Windows Server 2016) +# ============================================================================= + +include "host" { + path = find_in_parent_folders("host.hcl") + expose = true +} + +locals { + env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + env = local.env_vars.locals.env + aws_region = local.region_vars.locals.aws_region + deployment_name = local.env_vars.locals.deployment_name + + hostname = include.host.locals.computer_name + friendly_name = include.host.locals.hostname + domain = include.host.locals.domain + os_type = include.host.locals.os_type + role = include.host.locals.role + goad_id = include.host.locals.goad_id + + # Read admin password from GOAD lab config (single source of truth) + 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 +} + +terraform { + source = "${get_repo_root()}/modules//terraform-aws-instance-factory" +} + +dependency "network" { + config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] +} + +include { + path = find_in_parent_folders("root.hcl") +} + +inputs = { + env = local.env + instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" + instance_type = "t3.medium" + os_type = local.os_type + enable_asg = false + subnet_id = dependency.network.outputs.private_subnet_ids[0] + vpc_id = dependency.network.outputs.vpc_id + + enable_ssm = true + + additional_iam_policies = { + cloudwatch_agent = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" + s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" + } + + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) + windows_os = "Windows_Server" + windows_os_version = "2016-English-Full-Base" + windows_ami_owners = ["self"] + + additional_windows_ami_filters = [ + { + name = "name" + values = ["goad-dc-base-2016-*"] # warpgate-templates/goad-dc-base-2016 + } + ] + + ingress_rules = [ + { + description = "Allow all traffic from VPC CIDR" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [dependency.network.outputs.vpc_cidr] + }, + ] + + egress_rules = [ + { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + ] + + enable_monitoring = true + enable_metadata = true + require_imdsv2 = true + encrypt_volumes = true + root_volume_size = 100 + volume_type = "gp3" + + user_data = templatefile("${get_terragrunt_dir()}/templates/user_data_wrapper.ps1.tpl", { + compressed_user_data = base64encode(templatefile("${get_terragrunt_dir()}/templates/user_data.ps1.tpl", { + aws_region = local.aws_region, + hostname = local.hostname, + admin_password = local.admin_password + })) + }) + + tags = { + Environment = local.env + Project = "DreadGOAD" + Role = "DomainController" + Lab = "${local.deployment_name}-goad" + Name = "${local.deployment_name}-dreadgoad-${local.hostname}" + Domain = local.domain + ComputerName = local.hostname + } +} diff --git a/infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data.ps1.tpl new file mode 100644 index 00000000..bbc0ec7c --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data.ps1.tpl @@ -0,0 +1,44 @@ +# Add registry keys to enable TLS 1.2 at the OS level +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force | Out-Null +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'Enabled' -value '1' -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'Enabled' -value 1 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null + +# Enable strong cryptography on .NET Framework +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force + +# Force TLS 1.2 in current PowerShell session and create system-wide PowerShell profile +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Create AllSigned profile for all users +$allUsersAllHosts = "$env:windir\System32\WindowsPowerShell\v1.0\profile.ps1" +New-Item -Path $allUsersAllHosts -ItemType File -Force | Out-Null +Set-Content -Path $allUsersAllHosts -Value "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12" -Force + +# Set the local Administrator password +net user Administrator ${admin_password} /expires:never /y + +# Create ansible user, add to administrators group, and set password +net user ansible ${admin_password} /add /expires:never /y +net localgroup administrators ansible /add + +# Setup SSM Agent +$progressPreference = 'silentlyContinue' + +# Use WebClient instead of Invoke-WebRequest for SSM agent download too +$ssmUrl = "https://amazon-ssm-${aws_region}.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe" +$ssmOutput = "$env:TEMP\SSMAgent_latest.exe" +$webClient = New-Object System.Net.WebClient +$webClient.DownloadFile($ssmUrl, $ssmOutput) + +# Install SSM agent +Start-Process -FilePath $env:TEMP\SSMAgent_latest.exe -ArgumentList "/S" -Wait +Remove-Item -Force $env:TEMP\SSMAgent_latest.exe +Restart-Service AmazonSSMAgent + +# Rename computer and restart +Rename-Computer -NewName "${hostname}" -Force +Restart-Computer -Force diff --git a/infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data_wrapper.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data_wrapper.ps1.tpl new file mode 100644 index 00000000..4f83016f --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/srv02/templates/user_data_wrapper.ps1.tpl @@ -0,0 +1,5 @@ + +$EncodedUserData = "${compressed_user_data}" +$DecodedUserData = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($EncodedUserData)) +Invoke-Expression $DecodedUserData + diff --git a/infra/goad-deployment/test/us-east-2/goad/srv02/terragrunt.hcl b/infra/goad-deployment/test/us-east-2/goad/srv02/terragrunt.hcl new file mode 100644 index 00000000..11385662 --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/srv02/terragrunt.hcl @@ -0,0 +1,120 @@ +# ============================================================================= +# SRV02 - Member Server in North Subdomain (MSSQL) +# AMI: Built from warpgate-templates/goad-mssql-base (Windows Server 2019) +# ============================================================================= + +include "host" { + path = find_in_parent_folders("host.hcl") + expose = true +} + +locals { + env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + env = local.env_vars.locals.env + aws_region = local.region_vars.locals.aws_region + deployment_name = local.env_vars.locals.deployment_name + + hostname = include.host.locals.computer_name + friendly_name = include.host.locals.hostname + domain = include.host.locals.domain + os_type = include.host.locals.os_type + role = include.host.locals.role + goad_id = include.host.locals.goad_id + + # Read admin password from GOAD lab config (single source of truth) + 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 +} + +terraform { + source = "${get_repo_root()}/modules//terraform-aws-instance-factory" +} + +dependency "network" { + config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] +} + +include { + path = find_in_parent_folders("root.hcl") +} + +inputs = { + env = local.env + instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" + instance_type = "t3.medium" + os_type = local.os_type + enable_asg = false + subnet_id = dependency.network.outputs.private_subnet_ids[0] + vpc_id = dependency.network.outputs.vpc_id + + enable_ssm = true + + additional_iam_policies = { + cloudwatch_agent = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" + s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" + } + + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) + windows_os = "Windows_Server" + windows_os_version = "2019-English-Full-Base" + windows_ami_owners = ["self"] + + additional_windows_ami_filters = [ + { + name = "name" + values = ["goad-mssql-base-*"] # warpgate-templates/goad-mssql-base + } + ] + + ingress_rules = [ + { + description = "Allow all traffic from VPC CIDR" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [dependency.network.outputs.vpc_cidr] + }, + ] + + egress_rules = [ + { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + ] + + enable_monitoring = true + enable_metadata = true + require_imdsv2 = true + encrypt_volumes = true + root_volume_size = 100 + volume_type = "gp3" + + user_data = templatefile("${get_terragrunt_dir()}/templates/user_data_wrapper.ps1.tpl", { + compressed_user_data = base64encode(templatefile("${get_terragrunt_dir()}/templates/user_data.ps1.tpl", { + aws_region = local.aws_region, + hostname = local.hostname, + admin_password = local.admin_password + })) + }) + + tags = { + Environment = local.env + Project = "DreadGOAD" + Role = "MemberServer" + Lab = "${local.deployment_name}-goad" + Name = "${local.deployment_name}-dreadgoad-${local.hostname}" + Domain = local.domain + ComputerName = local.hostname + } +} diff --git a/infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data.ps1.tpl new file mode 100644 index 00000000..bbc0ec7c --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data.ps1.tpl @@ -0,0 +1,44 @@ +# Add registry keys to enable TLS 1.2 at the OS level +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force | Out-Null +New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'Enabled' -value '1' -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'Enabled' -value 1 -PropertyType 'DWord' -Force | Out-Null +New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -name 'DisabledByDefault' -value 0 -PropertyType 'DWord' -Force | Out-Null + +# Enable strong cryptography on .NET Framework +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force +Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -Force + +# Force TLS 1.2 in current PowerShell session and create system-wide PowerShell profile +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Create AllSigned profile for all users +$allUsersAllHosts = "$env:windir\System32\WindowsPowerShell\v1.0\profile.ps1" +New-Item -Path $allUsersAllHosts -ItemType File -Force | Out-Null +Set-Content -Path $allUsersAllHosts -Value "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12" -Force + +# Set the local Administrator password +net user Administrator ${admin_password} /expires:never /y + +# Create ansible user, add to administrators group, and set password +net user ansible ${admin_password} /add /expires:never /y +net localgroup administrators ansible /add + +# Setup SSM Agent +$progressPreference = 'silentlyContinue' + +# Use WebClient instead of Invoke-WebRequest for SSM agent download too +$ssmUrl = "https://amazon-ssm-${aws_region}.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe" +$ssmOutput = "$env:TEMP\SSMAgent_latest.exe" +$webClient = New-Object System.Net.WebClient +$webClient.DownloadFile($ssmUrl, $ssmOutput) + +# Install SSM agent +Start-Process -FilePath $env:TEMP\SSMAgent_latest.exe -ArgumentList "/S" -Wait +Remove-Item -Force $env:TEMP\SSMAgent_latest.exe +Restart-Service AmazonSSMAgent + +# Rename computer and restart +Rename-Computer -NewName "${hostname}" -Force +Restart-Computer -Force diff --git a/infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data_wrapper.ps1.tpl b/infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data_wrapper.ps1.tpl new file mode 100644 index 00000000..4f83016f --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/srv03/templates/user_data_wrapper.ps1.tpl @@ -0,0 +1,5 @@ + +$EncodedUserData = "${compressed_user_data}" +$DecodedUserData = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($EncodedUserData)) +Invoke-Expression $DecodedUserData + diff --git a/infra/goad-deployment/test/us-east-2/goad/srv03/terragrunt.hcl b/infra/goad-deployment/test/us-east-2/goad/srv03/terragrunt.hcl new file mode 100644 index 00000000..18a6421a --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/goad/srv03/terragrunt.hcl @@ -0,0 +1,120 @@ +# ============================================================================= +# SRV03 - Member Server in Essos Domain +# AMI: Built from warpgate-templates/goad-member-base-2016 (Windows Server 2016) +# ============================================================================= + +include "host" { + path = find_in_parent_folders("host.hcl") + expose = true +} + +locals { + env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + env = local.env_vars.locals.env + aws_region = local.region_vars.locals.aws_region + deployment_name = local.env_vars.locals.deployment_name + + hostname = include.host.locals.computer_name + friendly_name = include.host.locals.hostname + domain = include.host.locals.domain + os_type = include.host.locals.os_type + role = include.host.locals.role + goad_id = include.host.locals.goad_id + + # Read admin password from GOAD lab config (single source of truth) + 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 +} + +terraform { + source = "${get_repo_root()}/modules//terraform-aws-instance-factory" +} + +dependency "network" { + config_path = "../../network" + mock_outputs = { + vpc_id = "vpc-mock" + vpc_cidr = "10.0.0.0/16" + private_subnet_ids = ["subnet-mock"] + } + mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"] +} + +include { + path = find_in_parent_folders("root.hcl") +} + +inputs = { + env = local.env + instance_name = "${local.deployment_name}-dreadgoad-${local.hostname}" + instance_type = "t3.medium" + os_type = local.os_type + enable_asg = false + subnet_id = dependency.network.outputs.private_subnet_ids[0] + vpc_id = dependency.network.outputs.vpc_id + + enable_ssm = true + + additional_iam_policies = { + cloudwatch_agent = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" + s3_full_access = "arn:aws:iam::aws:policy/AmazonS3FullAccess" + } + + # Windows AMI - uses latest warpgate-built AMI (most_recent = true, owners = ["self"]) + windows_os = "Windows_Server" + windows_os_version = "2016-English-Full-Base" + windows_ami_owners = ["self"] + + additional_windows_ami_filters = [ + { + name = "name" + values = ["goad-member-base-2016-*"] # warpgate-templates/goad-member-base-2016 + } + ] + + ingress_rules = [ + { + description = "Allow all traffic from VPC CIDR" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [dependency.network.outputs.vpc_cidr] + }, + ] + + egress_rules = [ + { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + ] + + enable_monitoring = true + enable_metadata = true + require_imdsv2 = true + encrypt_volumes = true + root_volume_size = 100 + volume_type = "gp3" + + user_data = templatefile("${get_terragrunt_dir()}/templates/user_data_wrapper.ps1.tpl", { + compressed_user_data = base64encode(templatefile("${get_terragrunt_dir()}/templates/user_data.ps1.tpl", { + aws_region = local.aws_region, + hostname = local.hostname, + admin_password = local.admin_password + })) + }) + + tags = { + Environment = local.env + Project = "DreadGOAD" + Role = "MemberServer" + Lab = "${local.deployment_name}-goad" + Name = "${local.deployment_name}-dreadgoad-${local.hostname}" + Domain = local.domain + ComputerName = local.hostname + } +} diff --git a/infra/goad-deployment/test/us-east-2/network/terragrunt.hcl b/infra/goad-deployment/test/us-east-2/network/terragrunt.hcl new file mode 100644 index 00000000..43a8c989 --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/network/terragrunt.hcl @@ -0,0 +1,57 @@ +locals { + env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + env = local.env_vars.locals.env + aws_region = local.region_vars.locals.aws_region + deployment_name = local.env_vars.locals.deployment_name + vpc_cidr = local.env_vars.locals.vpc_cidr +} + +terraform { + source = "${get_repo_root()}/modules//terraform-aws-net" +} + +include { + path = find_in_parent_folders("root.hcl") +} + +inputs = { + additional_tags = { + Project = "DreadGOAD" + Environment = local.env + } + deployment_name = local.deployment_name + env = local.env + map_public_ip = true + vpc_cidr_block = local.vpc_cidr + + # Security group rules for VPC endpoints + vpce_security_group_rules = { + ingress_cidr_blocks = [local.vpc_cidr] + egress_cidr_blocks = ["0.0.0.0/0"] + } + + # VPC endpoints required for SSM-based instance management + vpc_endpoints = { + ssm = { + service = "ssm" + type = "Interface" + private_dns = true + } + ssmmessages = { + service = "ssmmessages" + type = "Interface" + private_dns = true + } + ec2messages = { + service = "ec2messages" + type = "Interface" + private_dns = true + } + s3 = { + service = "s3" + type = "Gateway" + } + } +} diff --git a/infra/goad-deployment/test/us-east-2/region.hcl b/infra/goad-deployment/test/us-east-2/region.hcl new file mode 100644 index 00000000..d788ddf7 --- /dev/null +++ b/infra/goad-deployment/test/us-east-2/region.hcl @@ -0,0 +1,3 @@ +locals { + aws_region = "us-east-2" +} From 76d5774471cfdfb783babbb24b870cc0ab8aca14 Mon Sep 17 00:00:00 2001 From: Jayson Grace Date: Mon, 6 Apr 2026 13:58:21 -0600 Subject: [PATCH 2/2] chore: add .terragrunt-cache to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index eb0fdd16..fa9c561a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,9 +31,10 @@ ad/*/providers/*/ssh_keys/*id_rsa* ad/*/providers/*/ssh_keys/*.pub ad/*/providers/*/extensions/*.rb -# Terraform +# Terraform / Terragrunt .terraform/ .terraform.lock.hcl +.terragrunt-cache/ *.tfstate *.tfstate.backup *.tfplan