Closed
Description
Hi,
my target is to create a coder Template which creates a local Users on a Windows Terminal Server and then run the coder stuff per user.
The user creation works fine, after the creation the workspace look's like this:
My terraform file looks like this:
terraform {
required_providers {
coder = {
source = "coder/coder"
}
}
}
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
locals{
admin_user = "c***\\coder"
admin_pw = "coder****"
machine = "Coder01"
user = "${substr(data.coder_workspace_owner.me.name,0, 11)}_${substr(data.coder_workspace.me.id, 0, 4)}${substr(data.coder_workspace.me.id, -4, -1)}"
password = data.coder_workspace.me.id
buildScript = "C:/coder/${data.coder_workspace_owner.me.name}_${data.coder_workspace.me.id}_coder_build.ps1"
removeScript = "C:/coder/${data.coder_workspace_owner.me.name}_${data.coder_workspace.me.id}_coder_remove.ps1"
coderScript = "C:/coder/${data.coder_workspace_owner.me.name}_${data.coder_workspace.me.id}_coder_init.ps1"
}
resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = data.coder_provisioner.me.os
metadata {
display_name = "CPU Usage"
key = "0_cpu_usage"
script = "coder stat cpu"
interval = 10
timeout = 1
}
metadata {
display_name = "RAM Usage"
key = "1_ram_usage"
script = "coder stat mem"
interval = 10
timeout = 1
}
}
# Use this to set environment variables in your workspace
# details: https://registry.terraform.io/providers/coder/coder/latest/docs/resources/env
resource "coder_env" "welcome_message" {
agent_id = coder_agent.main.id
name = "WELCOME_MESSAGE"
value = "Welcome to your Coder workspace!"
}
# Adds code-server
# See all available modules at https://registry.coder.com
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.main.id
}
# Runs a script at workspace start/stop or on a cron schedule
# details: https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script
# resource "coder_script" "startup_script" {
# agent_id = coder_agent.main.id
# display_name = "Startup Script"
# run_on_start = true
# start_blocks_login = true
# }
resource "terraform_data" "build" {
input = [
local.removeScript,
local.admin_user,
local.admin_pw,
local.machine
]
connection {
type = "ssh"
user = self.input[1]
password = self.input[2]
host = self.input[3]
target_platform = "windows"
}
provisioner "file" {
destination = local.buildScript
content = <<-EOT
$password = ConvertTo-SecureString "${local.password}" -AsPlainText -Force
New-LocalUser -AccountNeverExpires -Name "${local.user}" -Password $password
Add-LocalGroupMember -Group "Remotedesktopbenutzer" -Member "${local.user}"
# init local user
$Cred = [System.Management.Automation.PSCredential]::new("${local.user}", (ConvertTo-SecureString "${local.password}" -AsPlainText -Force))
Start-Process "cmd.exe" -Credential $Cred -ArgumentList "/C"
EOT
}
provisioner "file" {
destination = local.coderScript
content = <<-EOT
# Sleep for a while in case the underlying provider deletes the resource on error.
trap {
Write-Error "=== Agent script exited with non-zero code. Sleeping 24h to preserve logs..."
Start-Sleep -Seconds 86400
}
$coder_exe = "C:\coder\coder-windows-amd64.exe"
if ((Test-Path $coder_exe))
{
Write-Output "$(Get-Date) Kopiere coder-windows-amd64.exe"
Copy-Item $coder_exe -Destination $env:TEMP\sshd.exe
}
else
{
# Attempt to download the coder agent.
# This could fail for a number of reasons, many of which are likely transient.
# So just keep trying!
while ($true) {
try {
$ProgressPreference = "SilentlyContinue"
# On Windows, VS Code Remote requires a parent process of the
# executing shell to be named "sshd", otherwise it fails. See:
# https://github.com/microsoft/vscode-remote-release/issues/5699
$BINARY_URL="${data.coder_workspace.me.access_url}/bin/coder-windows-amd64.exe"
Write-Output "$(Get-Date) Fetching coder agent from $${BINARY_URL}"
Invoke-WebRequest -Uri "$${BINARY_URL}" -OutFile $env:TEMP\sshd.exe
break
} catch {
Write-Output "$(Get-Date) error: unhandled exception fetching coder agent:"
Write-Output $_
Write-Output "$(Get-Date) trying again in 30 seconds..."
Start-Sleep -Seconds 30
}
}
}
# Check if running in a Windows container
if (-not (Get-Command 'Set-MpPreference' -ErrorAction SilentlyContinue)) {
Write-Output "$(Get-Date) Set-MpPreference not available, skipping..."
} else {
Write-Output "$(Get-Date) Set-MpPreference skipping..."
#Set-MpPreference -DisableRealtimeMonitoring $true -ExclusionPath $env:TEMP\sshd.exe
}
$env:CODER_AGENT_AUTH = "token"
$env:CODER_AGENT_URL = "${data.coder_workspace.me.access_url}"
$env:CODER_AGENT_TOKEN = "${coder_agent.main.token}"
# Check if we're running inside a Windows container!
$inContainer = $false
if ((Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control' -Name 'ContainerType' -ErrorAction SilentlyContinue) -ne $null) {
$inContainer = $true
}
if ($inContainer) {
# If we're in a container, run in a the foreground!
Start-Process -FilePath $env:TEMP\sshd.exe -ArgumentList "agent" -Wait -NoNewWindow
} else {
Start-Process -FilePath $env:TEMP\sshd.exe -ArgumentList "agent" -PassThru
}
EOT
}
provisioner "file" {
destination = local.removeScript
content = <<-EOT
Remove-LocalUser -Name "${local.user}"
Remove-Item "C:\Users\${local.user}" -Recurse -Force
Remove-Item "${local.removeScript}" -Force
Remove-Item "${local.coderScript}" -Force
EOT
}
provisioner "remote-exec"{
inline = [
"powershell.exe \"${local.buildScript}\""
]
}
provisioner "remote-exec"{
when = destroy
inline = [
"powershell.exe \"${self.input[0]}\"",
#"del /f \"${self.input[0]}\"",
]
}
}
resource "terraform_data" "startup" {
connection {
type = "ssh"
target_platform = "windows"
host = local.machine
user = local.user
password = local.password
}
provisioner "remote-exec"{
inline = [
"powershell.exe \"${local.coderScript}\"",
]
}
}
resource "coder_app" "rdp" {
agent_id = coder_agent.main.id
display_name = "RDP Desktop"
slug = "rdp"
icon = "https://raw.githubusercontent.com/matifali/logos/main/windows.svg"
url = "http://localhost" #replace
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost" #replace
interval = 3
threshold = 120
}
}
I think there is a problem with starting up the "coder-windows-amd64.exe".
Any idea why that would fail?
Is my scenario supported by coder?
Thanks for your help in advance.
Best regards,
David