{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "This template will deploy Windows Server 2025 .",
  "Parameters": {
    "CloudLabsDeploymentID": {
      "Description": "DeploymentID Value",
      "Type": "String"
    },
    "CheckAcknowledgement": {
      "Type": "String",
      "Default": "TRUE"
    },
    "VPCCIDR": {
      "Type": "String",
      "Default": "10.0.0.0/16"
    },
    "clgclusterSubnetCidr": {
      "Type": "String",
      "Default": "10.0.2.0/24"
    },
    "cgWhitelist": {
      "Type": "String",
      "Default": "0.0.0.0/0"
    },
    "WindowsInstancesSubnetCIDR": {
      "Type": "String",
      "Default": "10.0.1.0/24"
    },
    "WindowsVMUserName": {
      "Type": "String",
      "Default": "labuser"
    },
    "WindowsVMPassword": {
      "Type": "String"
    },
    "WindowsAMIID": {
  "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
  "Default": "/aws/service/ami-windows-latest/Windows_Server-2025-English-Full-Base"
},
    "AppEnabled": {
      "Type": "String",
      "Default": "True"
    },
    "ShutdownOnIdle": {
      "Type": "String",
      "Default": "True"
    },
    "ShutdownOnIdleTimeout": {
      "Type": "Number",
      "Default": 15
    },
    "WarningWaitTimeout": {
      "Type": "Number",
      "Default": 15
    },
    "TrackingMode": {
      "Type": "Number",
      "Default": 1
    },
    "ShutdownOnDisconnect": {
      "Type": "String",
      "Default": "True"
    },
    "ShutdownOnDisconnectTimeout": {
      "Type": "Number",
      "Default": 15
    },
    "ShutdownWhenNoUsersConnected": {
      "Type": "String",
      "Default": "True"
    },
    "ShutdownWhenNoUsersConnectedTimeout": {
      "Type": "Number",
      "Default": 15
    },
    "WindowsIdletrackingInstallationScriptUrl": {
      "Type": "String",
      "Default": "WindowsIdletrackingInstallationScriptUrl"
    },
    "WindowsIdlecheckFeatureConnectionString": {
      "Type": "String",
      "Default": "WindowsIdlecheckFeatureConnectionString"
    },
    "OdlTrackingSource": {
      "Type": "Number",
      "Default": 3
    },
    "Version": {
      "Type": "String",
      "Default": "Version"
    },
    "AppCheckFrequency": {
      "Type": "Number",
      "Default": 2
    },
    "CloudLabsDeploymentIDEncrypt": {
      "Type": "String",
      "Default": "CloudLabsDeploymentIDEncrypt"
    },
    "AccountId": {
      "Type": "String"
    },
    "AvailabilityZoneIndex": {
    "Type": "Number",
    "Default": "0",
    "Description": "Select AZ index from available AZs in the region"
    },
    "AmazonECSTaskExecutionRolePolicy": {
      "Type": "String",
      "Default": "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
    }
  },
  "Resources": {
    "TaskExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "ecs-tasks.amazonaws.com"
                ]
              },
              "Action": [
                "sts:AssumeRole"
              ]
            }
          ]
        },
        "Path": "/",
        "ManagedPolicyArns": [
          {
            "Ref": "AmazonECSTaskExecutionRolePolicy"
          }
        ],
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "TaskExecutionRole-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "EC2InstancesVPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": {
          "Ref": "VPCCIDR"
        },
        "EnableDnsSupport": true,
        "EnableDnsHostnames": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "EC2InstancesVPC-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "clgClusterSubnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "MapPublicIpOnLaunch": true,
        "VpcId": {
          "Ref": "EC2InstancesVPC"
        },
        "CidrBlock": {
          "Ref": "clgclusterSubnetCidr"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "clgClusterSubnet-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "WindowsEC2InstanceSubnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "MapPublicIpOnLaunch": true,
        "VpcId": {
          "Ref": "EC2InstancesVPC"
        },
        "AvailabilityZone": {
      "Fn::Select": [
        {
          "Ref": "AvailabilityZoneIndex"
        },
        {
          "Fn::GetAZs": ""
        }
      ]
      },
        "CidrBlock": {
          "Ref": "WindowsInstancesSubnetCIDR"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "WindowsEC2InstanceSubnet-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "InternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Properties": {
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "InternetGateway-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "AttachInternetGateway": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "InternetGatewayId": {
          "Ref": "InternetGateway"
        },
        "VpcId": {
          "Ref": "EC2InstancesVPC"
        }
      }
    },
    "EC2InstancesVPCpublicRT": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "EC2InstancesVPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "EC2InstancesVPCpublicRT",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "EC2InstancesVPCRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": "AttachInternetGateway",
      "Properties": {
        "RouteTableId": {
          "Ref": "EC2InstancesVPCpublicRT"
        },
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": {
          "Ref": "InternetGateway"
        }
      }
    },
    "WindowsInstancesVPCRouteattach": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "WindowsEC2InstanceSubnet"
        },
        "RouteTableId": {
          "Ref": "EC2InstancesVPCpublicRT"
        }
      }
    },
    "clusterSubnetRouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "clgClusterSubnet"
        },
        "RouteTableId": {
          "Ref": "EC2InstancesVPCpublicRT"
        }
      }
    },
    "clgSg": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "this is for container",
        "GroupName": "clgSg",
        "VpcId": {
          "Ref": "EC2InstancesVPC"
        },
        "SecurityGroupIngress": [
          {
            "FromPort": 443,
            "ToPort": 443,
            "IpProtocol": "tcp",
            "CidrIp": "0.0.0.0/0"
          },
          {
            "FromPort": 443,
            "ToPort": 443,
            "IpProtocol": "tcp",
            "CidrIpv6": "::/0"
          }
        ],
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "clgSg-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    },
    "EC2InstancesVPCRDP": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "security group that allows RDP and all egress traffic",
        "VpcId": {
          "Ref": "EC2InstancesVPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "EC2InstancesVPCRDP-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ],
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": "0",
            "ToPort": "65535",
            "CidrIp": {
              "Ref": "clgclusterSubnetCidr"
            }
          },
            {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "8.36.116.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "8.39.144.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "31.186.239.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "66.151.135.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "74.217.93.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "113.31.158.128/26"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "113.31.185.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "117.50.129.64/26"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "117.50.166.0/24"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "222.126.180.0/22"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "163.116.128.0/17"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "162.10.0.0/16"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "158.95.0.0/16"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "24.206.64.0/19"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "24.206.96.0/19"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "24.239.176.0/21"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "24.239.128.0/19"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 3389,
        "ToPort": 3389,
        "CidrIp": "24.239.160.0/20"
      } 
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "FromPort": 0,
            "ToPort": 65535,
            "CidrIp": {
              "Ref": "cgWhitelist"
            }
          }
        ]
      }
    },
    "WindowsEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": {
          "Ref": "WindowsAMIID"
        },
        "InstanceType": "t3.medium",
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "\n",
              [
              {
                "Fn::Sub": "<powershell>\nStart-Transcript -Path 'C:\\Windows\\Logs\\userdata-logs.txt' -Append\n\ntry {\n\n# Create Local Administrator User\n$username = '${WindowsVMUserName}'\n$password = ConvertTo-SecureString '${WindowsVMPassword}' -AsPlainText -Force\n\nif (-not (Get-LocalUser -Name $username -ErrorAction SilentlyContinue)) {\n    New-LocalUser -Name $username -Password $password -AccountNeverExpires\n    Add-LocalGroupMember -Group 'Administrators' -Member $username\n    Write-Host 'Local administrator user created successfully.'\n}\nelse {\n    Write-Host 'Local administrator user already exists.'\n}\n\n# Disable password expiration for the local user\nSet-LocalUser -Name $username -PasswordNeverExpires $true\nWrite-Host 'Password expiration disabled for local administrator user.'\n\n# Disable New Network Window\nNew-Item -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Network' -Name 'NewNetworkWindowOff' -Force -ErrorAction SilentlyContinue\n\n# Disable IE Enhanced Security Configuration\n$HKLM = 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3'\n$HKCU = 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3'\nSet-ItemProperty -Path $HKLM -Name '1803' -Value 0 -ErrorAction SilentlyContinue\nSet-ItemProperty -Path $HKCU -Name '1803' -Value 0 -ErrorAction SilentlyContinue\nSet-ItemProperty -Path $HKLM -Name '1604' -Value 0 -ErrorAction SilentlyContinue\nSet-ItemProperty -Path $HKCU -Name '1604' -Value 0 -ErrorAction SilentlyContinue\n\n# Create Temp Directory\n$TempDir = 'C:\\Temp'\nNew-Item -ItemType Directory -Path $TempDir -Force | Out-Null\n\n# Install Google Chrome\n$ChromeInstaller = \"$TempDir\\ChromeSetup.exe\"\nInvoke-WebRequest -Uri 'https://dl.google.com/chrome/install/latest/chrome_installer.exe' -OutFile $ChromeInstaller\nStart-Process -FilePath $ChromeInstaller -ArgumentList '/silent /install' -Wait\n\n# Install Visual Studio Code (System Installer)\n$VSCodeInstaller = \"$TempDir\\VSCodeSetup.exe\"\nInvoke-WebRequest -Uri 'https://update.code.visualstudio.com/latest/win32-x64/stable' -MaximumRedirection 5 -OutFile $VSCodeInstaller\nStart-Process -FilePath $VSCodeInstaller -ArgumentList '/VERYSILENT /NORESTART /MERGETASKS=!runcode' -Wait\n\n# Install PuTTY\n$PuttyInstaller = \"$TempDir\\putty-64bit-installer.msi\"\nInvoke-WebRequest -Uri 'https://the.earth.li/~sgtatham/putty/latest/w64/putty-64bit-installer.msi' -OutFile $PuttyInstaller\nStart-Process msiexec.exe -ArgumentList \"/i `\"$PuttyInstaller`\" /qn /norestart\" -Wait\n\n# Wait for Applications to Become Available\nStart-Sleep -Seconds 30\n\n# Create Desktop Shortcuts\n$Desktop = 'C:\\Users\\Public\\Desktop'\n$WshShell = New-Object -ComObject WScript.Shell\n\n# Chrome Shortcut\n$ChromePath = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'\nif (Test-Path $ChromePath) {\n    $Shortcut = $WshShell.CreateShortcut(\"$Desktop\\Google Chrome.lnk\")\n    $Shortcut.TargetPath = $ChromePath\n    $Shortcut.WorkingDirectory = Split-Path $ChromePath\n    $Shortcut.Save()\n}\n\n# VS Code Shortcut\n$VSCodePath = 'C:\\Program Files\\Microsoft VS Code\\Code.exe'\nif (Test-Path $VSCodePath) {\n    $Shortcut = $WshShell.CreateShortcut(\"$Desktop\\Visual Studio Code.lnk\")\n    $Shortcut.TargetPath = $VSCodePath\n    $Shortcut.WorkingDirectory = Split-Path $VSCodePath\n    $Shortcut.Save()\n}\n\n# PuTTY Shortcut\n$PuttyPath = 'C:\\Program Files\\PuTTY\\putty.exe'\nif (Test-Path $PuttyPath) {\n    $Shortcut = $WshShell.CreateShortcut(\"$Desktop\\PuTTY.lnk\")\n    $Shortcut.TargetPath = $PuttyPath\n    $Shortcut.WorkingDirectory = Split-Path $PuttyPath\n    $Shortcut.Save()\n}\n\nWrite-Host 'Windows configuration completed successfully.'\n}\ncatch {\n    Write-Host \"UserData execution failed: $($_.Exception.Message)\"\n    Write-Host $_.Exception.StackTrace\n}\nfinally {\n    Stop-Transcript\n}\n</powershell>"
                },
                {
                  "Fn::If": [
                    "AppEnabledAndOdlTrackingCondition",
                    {
                      "Fn::Join": [
                        "\n",
                        [
                          {
                            "Fn::Sub": "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;"
                          },
                          {
                            "Fn::Sub": "Invoke-WebRequest ${WindowsIdletrackingInstallationScriptUrl} -OutFile 'C:/WindowsIdleTrackingInstallationScripts.ps1'"
                          },
                          {
                            "Fn::Sub": "$Token = (Invoke-WebRequest -Method PUT -Uri \"http://169.254.169.254/latest/api/token\" -Headers @{\"X-aws-ec2-metadata-token-ttl-seconds\" = \"21600\"} -UseBasicParsing).Content\n$InstanceID = (Invoke-WebRequest -Uri \"http://169.254.169.254/latest/meta-data/instance-id\" -Headers @{\"X-aws-ec2-metadata-token\" = $Token} -UseBasicParsing).Content"
                          },
                          {
                            "Fn::Sub": "C:\\WindowsIdleTrackingInstallationScripts.ps1 ${WindowsIdlecheckFeatureConnectionString} ${Version} ${AppEnabled} ${ShutdownOnIdle} ${ShutdownOnIdleTimeout} ${WarningWaitTimeout} ${TrackingMode} ${ShutdownOnDisconnect} ${ShutdownOnDisconnectTimeout} ${ShutdownWhenNoUsersConnected} ${ShutdownWhenNoUsersConnectedTimeout} ${AppCheckFrequency} $InstanceID ${CloudLabsDeploymentIDEncrypt}"
                          },
                          {
                            "Fn::Sub": "Remove-Item 'C:/WindowsIdleTrackingInstallationScripts.ps1' -Force"
                          }
                        ]
                      ]
                    },
                    {
                      "Fn::Sub": "echo 'App Enabled is False'"
                    }
                  ]
                },
                {
                  "Fn::Sub": "</powershell>"
                }
              ]
            ]
          }
        },
        "BlockDeviceMappings": [
          {
            "DeviceName": "/dev/sda1",
            "Ebs": {
              "Encrypted": false,
              "DeleteOnTermination": true,
              "VolumeSize": 60,
              "VolumeType": "gp3"
            }
          }
        ],
        "NetworkInterfaces": [
          {
            "AssociatePublicIpAddress": true,
            "DeviceIndex": 0,
            "GroupSet": [
              {
                "Ref": "EC2InstancesVPCRDP"
              }
            ],
            "SubnetId": {
              "Ref": "WindowsEC2InstanceSubnet"
            }
          }
        ],
        "Tags": [
          {
            "Key": "Name",
            "Value": {
              "Fn::Join": [
                "",
                [
                  "WindowsVM-",
                  {
                    "Ref": "CloudLabsDeploymentID"
                  }
                ]
              ]
            }
          }
        ]
      }
    }
  },
  "Conditions": {
    "AppEnabledAndOdlTrackingCondition": {
      "Fn::And": [
        {
          "Fn::Equals": [
            {
              "Ref": "AppEnabled"
            },
            "True"
          ]
        },
        {
          "Fn::Or": [
            {
              "Fn::Equals": [
                {
                  "Ref": "OdlTrackingSource"
                },
                1
              ]
            },
            {
              "Fn::Equals": [
                {
                  "Ref": "OdlTrackingSource"
                },
                2
              ]
            }
          ]
        }
      ]
    }
  },
  "Outputs": {
    "CloudLabsDeploymentID": {
      "Description": "DeploymentID Value",
      "Value": {
        "Ref": "CloudLabsDeploymentID"
      }
    },
    "VpcId": {
      "Description": "The ID of the VPC",
      "Value": {
        "Ref": "EC2InstancesVPC"
      }
    },
    "WindowsVMUserName": {
      "Description": "WindowsVMUserName",
      "Value": {
        "Ref": "WindowsVMUserName"
      }
    },
    "WindowsVMPassword": {
      "Description": "WindowsVMPassword",
      "Value": {
        "Ref": "WindowsVMPassword"
      }
    },
    "WindowsVMPublicIp": {
      "Description": "Public Ip of the Windows VM",
      "Value": {
        "Fn::GetAtt": [
          "WindowsEC2Instance",
          "PublicIp"
        ]
      }
    },
    "PublicDNS": {
    "Description": "Public DNS Name",
    "Value": {
      "Fn::GetAtt": [
        "WindowsEC2Instance",
        "PublicDnsName"
      ]
    }
     },
    "WindowsVMPrivateIp": {
      "Description": "Private Ip of the Windows VM",
      "Value": {
        "Fn::GetAtt": [
          "WindowsEC2Instance",
          "PrivateIp"
        ]
      }
    },
    "clusterSubnetId": {
      "Description": "The ID of the ClusterSubnet",
      "Value": {
        "Ref": "clgClusterSubnet"
      }
    },
    "clusterSecurityGroupId": {
      "Description": "The SG ID of the Cluster",
      "Value": {
        "Ref": "clgSg"
      }
    },
    "TaskExecutionRole": {
      "Description": "The Arn of Role that is utilised by ECS Task Definition",
      "Value": {
        "Fn::GetAtt": [
          "TaskExecutionRole",
          "Arn"
        ]
      }
    }
  }
}