hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.76k stars 9.56k forks source link

problem with provisioner "connection" - Windows Vm in vsphere - added in domain #33524

Closed athirumalairaja closed 10 months ago

athirumalairaja commented 1 year ago

Terraform Version

Terraform v1.5.1
on windows_amd64

Terraform Configuration Files

terraform {
  required_providers {
    vsphere = {
      source = "hashicorp/vsphere"
      version = "2.4.1"
    }
  }
}

provider "vsphere" {
  vsphere_server       = local.config.vsphere_server
  user                 = local.config.vsphere_username
  password             = local.config.vsphere_password
  allow_unverified_ssl = var.vsphere_insecure
}

data "vsphere_datacenter" "datacenter" {
  name = local.config.vsphere_datacenter
}

data "vsphere_network" "network" {
  name          = local.config.vsphere_network
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_compute_cluster" "cluster" {
  name          = local.config.vsphere_cluster
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_resource_pool" "pool" {
  name          = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources")
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_datastore" "datastore" {
  name          = local.config.vsphere_datastore
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_virtual_machine" "template" {
  name          = local.config.vsphere_template
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

resource "vsphere_virtual_machine" "vm" {
  name                    = local.config.vm_name
  num_cpus                = local.config.vm_cpus
  memory                  = local.config.vm_memory
  firmware                = local.config.vm_firmware
  efi_secure_boot_enabled = local.config.vm_efi_secure_boot_enabled
  guest_id                = data.vsphere_virtual_machine.template.guest_id
  datastore_id            = data.vsphere_datastore.datastore.id
  resource_pool_id        = data.vsphere_resource_pool.pool.id
  network_interface {
    network_id = data.vsphere_network.network.id
  }
  disk {
    label            = "disk0"
    size             = data.vsphere_virtual_machine.template.disks[0].size
    eagerly_scrub    = data.vsphere_virtual_machine.template.disks[0].eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.template.disks[0].thin_provisioned
  }
  clone {
    template_uuid = data.vsphere_virtual_machine.template.id
    customize {
      timeout = 20
      windows_options {
        computer_name         = local.config.vm_name
        time_zone             = 045
        organization_name     = local.config.organization_name
        join_domain           = local.config.domain
        domain_admin_user     = local.config.domain_admin_username
        domain_admin_password = local.config.domain_admin_password
        admin_password        = local.config.vm_admin_password
        auto_logon = true
        auto_logon_count      = 2
        run_once_command_list = [
          # TODO this makes WinRM possible on the VM. This is needed for the post-deployment task(s)!
          "winrm quickconfig -force",
          "winrm set winrm/config @{MaxEnvelopeSizekb=\"100000\"}",
          "winrm set winrm/config/Service/Auth @{Basic=\"true\"}",
          "Start-Service WinRM",
          "Set-service WinRM -StartupType Automatic",
          "Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled false"
        ]
      }
      network_interface {
        ipv4_address = local.config.vm_ipv4_address
        ipv4_netmask = local.config.vm_ipv4_netmask
      }

      ipv4_gateway    = local.config.vm_ipv4_gateway
      dns_suffix_list = local.config.vm_dns_suffix_list
      dns_server_list = local.config.vm_dns_server_list
    }
  }
  lifecycle {
    ignore_changes = [
      clone[0].template_uuid,
    ]
  }
  provisioner "remote-exec" {
    inline = [
      "powershell.exe -Command Write-Host  'HELLO WORLD ! (if you see this, the configuration was a success!)'",
    ]
    connection {
      host     = self.default_ip_address
      type     = "winrm"
      https    = true
      user     = "Administrator"
      password = local.config.domain_admin_password
      agent    = false
      insecure = false
    }
  }
}

Debug Output

https://github.com/athirumalairaja/terraform.log.git

image

Expected Behavior

Create Windows from Template using vsphere provider and add to domain then need to run one PowerShell script on that in the above code I have used a command to execute using WinRm.

i have created VM manually and exacted Script that i want to run its fine, i done below steps by manually

  1. logging in to the VM with my AD login
  2. i have copy the run_onceScript.ps1
  3. open poershell as Administrator
  4. execter the script (Script will install some agents on the machine)

Actual Behavior

VM is Created and also joined to domain when its connecting trough Winrm i am getting error

Steps to Reproduce

1.terraform init

  1. $Env:TF_LOG="TRACE"
  2. terraform apply -no-color 2>&1 | Tee-Object -FilePath apply.txt

Additional Context

No response

References

No response

apparentlymart commented 1 year ago

Hi @athirumalairaja,

The error you have shown here seems to be coming from the WinRM client and so it's presented in a slightly confusing way, but it appears to essentially just be reporting a "connection refused" error.

"Connection refused" is a type of control packet sent by a server when you try to connect to a port that doesn't have any server running on it, and so my first guess would be that either the WinRM server isn't running at all or it is running on a different port number than 5986.

It's also possible that the server, or something else on the network between you and that server, is configured to reject the connection artificially. For example, some firewalls use "connection refused" to make it appear that a server isn't available even though it might be available to another client connecting from another location.

I cannot know what network conditions might exist on your system to make this happen, but unfortunately since it is a network-related problem I expect we won't be able to investigate further without additional information that explains why something in your network path is returning "connection refused" to Terraform when it tries to connect.

This kind of complexity of network configuration is a big part of why provisioners are a last resort. If you can achieve the result you need using features of vSphere to provide this script to the VM then I would recommend using that instead and removing all provisioners from your configuration. The documentation suggests that attaching a "virtual CDROM" containing the script you want to run might be the available alternative in vSphere, but I don't have personal experience with that so I cannot advise on how to implement it.

athirumalairaja commented 1 year ago

@apparentlymart Thank you for your response i will try to achieve that by using Virtual CDROM, And for your info after VM created i can be able to do RDS connection to the machine when i run winrm quickconfig and winrm get winrm/config on the newly created VM i am getting below output.

and one more thing that my account has administrator privilege but when i try to run script on vm i used to run PowerShell as Administrator is it could be the problem (but that is for running the script)

WinRM service is already running on this machine.
WinRM is already set up for remote management on this computer.
Config
    MaxEnvelopeSizekb = 100000
    MaxTimeoutms = 60000
    MaxBatchItems = 32000
    MaxProviderRequests = 4294967295
    Client
        NetworkDelayms = 5000
        URLPrefix = wsman
        AllowUnencrypted = false [Source="GPO"]
        Auth
            Basic = true
            Digest = false [Source="GPO"]
            Kerberos = true
            Negotiate = true
            Certificate = true
            CredSSP = false
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        TrustedHosts
    Service
        RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
        MaxConcurrentOperations = 4294967295
        MaxConcurrentOperationsPerUser = 1500
        EnumerationTimeoutms = 240000
        MaxConnections = 300
        MaxPacketRetrievalTimeSeconds = 120
        AllowUnencrypted = false [Source="GPO"]
        Auth
            Basic = false [Source="GPO"]
            Kerberos = true
            Negotiate = true
            Certificate = false
            CredSSP = false
            CbtHardeningLevel = Relaxed
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        IPv4Filter = *
        IPv6Filter = *
        EnableCompatibilityHttpListener = false
        EnableCompatibilityHttpsListener = false
        CertificateThumbprint
        AllowRemoteAccess = true
    Winrs
        AllowRemoteShellAccess = true
        IdleTimeout = 7200000
        MaxConcurrentUsers = 2147483647
        MaxShellRunTime = 2147483647
        MaxProcessesPerShell = 2147483647
        MaxMemoryPerShellMB = 2147483647
        MaxShellsPerUser = 2147483647
athirumalairaja commented 1 year ago

actually, for an automation perspective i can't use CDROM, as we need to create CDROM with script if script got update again we have to do the same so what i am trying now is, try to create registry entry under "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" my code is as bellow: ` clone { template_uuid = data.vsphere_virtual_machine.template.id customize { timeout = 20 windows_options { computer_name = local.config.vm_name time_zone = 045 organization_name = local.config.organization_name join_domain = local.config.domain domain_admin_user = local.config.domain_admin_username domain_admin_password = local.config.domain_admin_password admin_password = local.config.vm_admin_password run_once_command_list = [ "powershell.exe -ExecutionPolicy Bypass -Command \Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' -Name '1' -Value 'cmd.exe /C Powershell.exe -ExecutionPolicy Bypass -File \\cable\efv-dfs\Workspaces\InfraOpen\VMware_Templates\Automation_Scripts\VM_Deployment\VM_Deploy_RunOnce_Script_V1.0.ps1'", ] } network_interface { ipv4_address = local.config.vm_ipv4_address ipv4_netmask = local.config.vm_ipv4_netmask }

  ipv4_gateway    = local.config.vm_ipv4_gateway
  dns_suffix_list = local.config.vm_dns_suffix_list
  dns_server_list = local.config.vm_dns_server_list
}`

i am getting the entry like : powershell.exe -ExecutionPolicy Bypass -Command \Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' -Name '1' -Value 'cmd.exe /C Powershell.exe -ExecutionPolicy Bypass -File \\cable\efv-dfs\Workspaces\InfraOpen\VMware_Templates\Automation_Scripts\VM_Deployment\VM_Deploy_RunOnce_Script_V1.0.ps1'

its getting entry for hole and the script is not started at fist boot. image

athirumalairaja commented 1 year ago

The problem is that when I build a VM the customization (sysprep) not completed Full I need to restart to complete, any one could you help me on that pls

crw commented 1 year ago

Hello @athirumalairaja, as this seems to be a question about the implementation and usage of a specific configuration, rather than a bug or feature request in Terraform itself, it would be better to use the community forum where there are more people ready to help. The GitHub issues here are monitored only by a few core maintainers. Thanks!

crw commented 10 months ago

I am cleaning up older issues. I believe this is a usage issue which would be better handled in the forums, as currently it does not seem that there is an issue with the implementation of terraform. Please let us know if you have a reproducible issue with terraform itself. Thanks!

github-actions[bot] commented 9 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.