hashicorp / terraform-provider-azure-classic

Terraform Azure Classic (Service Management) provider
https://www.terraform.io/docs/providers/azure/
Mozilla Public License 2.0
3 stars 11 forks source link

Unable to connect to Azure Windows VM with PowerShell #9

Closed hashibot closed 6 years ago

hashibot commented 7 years ago

This issue was originally opened by @chevalpartners as hashicorp/terraform#3473. It was migrated here as part of the provider split. The original body of the issue is below.


Azure has 2 different types of Virtual Machines. Terraform currently supports the generation 1 VM which were created using Service management API. When we create a new Windows VM WinRM is already configured. I am not a WinRM expert but I think Azure VM requires HTTPS connection for WinRM. Every generation 1 VM sits behind a load balancer. When we create a new VM using the portal at manage.windowsazure.com it create to rules to allow traffic through the load balancer. One of them is called PowerShell port 5986.

However Terraform documentation says that it uses 5985 to communicate with WinRM.

I have tried many different ways to execute a simple powershell script but I have failed so far.

Here are my provisioner settings.

provisioner "remote-exec" {
    connection {
      type         = "winrm"
      user         = "${var.web_username}"
      password     = "${var.web_password}"
      host         = "${self.vip_address}"
      https        = true
      insecure     = true
      timeout      = "10m"
    }

    inline = [ <<COMMANDS
Install-WindowsFeature Web-Server
Install-WindowsFeature Web-Mgmt-Tools
Install-WindowsFeature Web-App-Dev -IncludeAllSubFeature
COMMANDS ]
  }
}

i have tried setting the values of insecure, https to false as well as true.

Here is the error.

Error applying plan:

1 error(s) occurred:

* unknown error Post https://40.112.136.81:5985/wsman: dial tcp 40.112.136.81:5985: operation timed out

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Here are winrm settings from the vm that was provisioned.

C:\Users\rajindersingh>winrm get winrm/config
Config
    MaxEnvelopeSizekb = 500
    MaxTimeoutms = 60000
    MaxBatchItems = 32000
    MaxProviderRequests = 4294967295
    Client
        NetworkDelayms = 5000
        URLPrefix = wsman
        AllowUnencrypted = false
        Auth
            Basic = true
            Digest = true
            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;G
XGW;;;WD)
        MaxConcurrentOperations = 4294967295
        MaxConcurrentOperationsPerUser = 1500
        EnumerationTimeoutms = 240000
        MaxConnections = 300
        MaxPacketRetrievalTimeSeconds = 120
        AllowUnencrypted = false
        Auth
            Basic = false
            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 = 10
        MaxShellRunTime = 2147483647
        MaxProcessesPerShell = 25
        MaxMemoryPerShellMB = 1024
        MaxShellsPerUser = 30

It clearly shows that unencrypted connections are not allowed.

        AllowUnencrypted = false

Could this be my issues?

Azure VM's don't have other ways to configure the settings inside them like AWS EC2 VM's do with user data.

I am hoping that somebody can show me how to execute remote powershell in a windows vm.

hashibot commented 7 years ago

This comment was originally opened by @bensojona as https://github.com/hashicorp/terraform/issues/3473#issuecomment-147946566. It was migrated here as part of the provider split. The original comment is below.


I'm running into the same thing.

Here is a repro. It attempts to connect to the remote host via WinRM but times out after multiple attempts.

I believe all the correct ports are opened up on the instance, but don't have much experience using Azure, this could also just be a configuration error.

hashibot commented 7 years ago

This comment was originally opened by @dotnetdude as https://github.com/hashicorp/terraform/issues/3473#issuecomment-147991176. It was migrated here as part of the provider split. The original comment is below.


We are also facing the similar issue. we are trying to copy the files (powershell scripts) to the VM disk and execute it and Looks like azure is not allowing to copy the file unless you are in same network.. we are getting connection timeout error. ref : http://stackoverflow.com/questions/18049729/windows-azure-powershell-copying-file-to-vm . is there any way to attach the local folder like vagrant does in terraform?

hashibot commented 7 years ago

This comment was originally opened by @rajinders as https://github.com/hashicorp/terraform/issues/3473#issuecomment-154088620. It was migrated here as part of the provider split. The original comment is below.


The only work around I can think of at this time is to create a custom image which has WinRM setup the way Terraform likes it. After that Terraform will be able to connect successfully to windows vm.

hashibot commented 7 years ago

This comment was originally opened by @xied75 as https://github.com/hashicorp/terraform/issues/3473#issuecomment-160135671. It was migrated here as part of the provider split. The original comment is below.


@chevalpartners @bensojona I'll try your repro later, but what do you mean regarding AWS userdata, Azure has a thing called custom-data which is similar:

https://coreos.com/os/docs/latest/booting-on-azure.html

azure vm create --custom-data=cloud-config.yaml --vm-size=Small --ssh=22 --ssh-cert=path/to/cert --no-ssh-password --vm-name=node-1 --location="West US" my-cloud-service 2b171e93f07c4903bcad35bda10acf22__CoreOS-Stable-766.5.0 core
hashibot commented 7 years ago

This comment was originally opened by @rajinders as https://github.com/hashicorp/terraform/issues/3473#issuecomment-160429135. It was migrated here as part of the provider split. The original comment is below.


@xied75 I am aware of custom-data in Azure but it exists in Linux VMs running in Azure. My example above was for Windows VM's. Instead of SSH we use winrm to communicate with Azure VM's and that seems to be broken.

hashibot commented 7 years ago

This comment was originally opened by @davehodgson as https://github.com/hashicorp/terraform/issues/3473#issuecomment-162244631. It was migrated here as part of the provider split. The original comment is below.


This might be a very naive suggestion but...the initial post says that terraform is trying to use port 5985 and by default powershell is set up on 5986, has anyone tried adding a non-default endpoint on the azure_instance resource? i.e. below

endpoint { name = "Powershell" protocol = "tcp" public_port = 5985 private_port = 5986 }

NB I don't know enough about Azure/Terraform endpoints to know if the private port needs to be 5986 as well or if the above will redirect 5985 public to 5986 private on the load balancer which I think is what we want as the VM is presumably open to 5986 by default given that is how Azure provisions by default.

I hit the same problem trying to copy a file up as part of the provisioner and found this issue by searching.

hashibot commented 7 years ago

This comment was originally opened by @davehodgson as https://github.com/hashicorp/terraform/issues/3473#issuecomment-162253647. It was migrated here as part of the provider split. The original comment is below.


I did some playing around but couldn't get the idea above to run, I did manage to set up an endpoint on 5985 public to both 5985 private and 5986 private (2 seperate tests) but it always timed out.

I'll keep playing over next couple of days, I suspect I will end up calling a local PS script with local-exec to connect remote powershell and copy the file that way

hashibot commented 7 years ago

This comment was originally opened by @davehodgson as https://github.com/hashicorp/terraform/issues/3473#issuecomment-162271729. It was migrated here as part of the provider split. The original comment is below.


I've done some more digging, I can't connect a remote powershell script to an azure_instance after it has been built in Terraform, but if I build one via the portal GUI, the exact same script will connect no problem.

There are some differences if I look at the VM properties, the one that I think is most important here is the default thumbprint - when Azure creates a VM it generates a self signed cert, which you can request the thumbprint of and add it to your key store as part of your script, you can then get a session etc via powershell.

However, when terraform creates the instance, the default thumbprint is empty, i.e. the cert is either not created or created and not attached. So that when you try and open a connection to the server using remote powershell it is not possible.

I suspect that the provisioner is probably doing something similar under the hood and as a result is unable to open a connection because Azure is blocking it, but I don't know enough about Terraform or the code to have a look at this to confirm it.

Below is a script to let you see what I mean, just set svcname, it assumes the vm and hosted service have the same name (i.e. the hosted service wasn't explicitly altered):

$svcname = "test-deleteme1"

Get-AzureVM -ServiceName $svcname -Name $svcname | select -ExpandProperty vm

The only other thing I am aware of being different in the creation is I left the install vm agent box ticked during the creation wizard

hashibot commented 7 years ago

This comment was originally opened by @davehodgson as https://github.com/hashicorp/terraform/issues/3473#issuecomment-162284582. It was migrated here as part of the provider split. The original comment is below.


I had a good try at updating an existing VM by uploading a new default WinRM cert but can't find a way to do it through the powershell commandlets and cant find any hints on where to look.

So unless my analysis is off, that means that any VM created by terraform in Azure is not able to use remote powershell because as noted above:

  1. Terraform tries to connect on the wrong port (can be fixed by including an extra winrm endpoint)
  2. No defaultWinRM cert is present after creation so the thumbprint cant be used to create an HTTPS connection
hashibot commented 7 years ago

This comment was originally opened by @deftflux as https://github.com/hashicorp/terraform/issues/3473#issuecomment-199382585. It was migrated here as part of the provider split. The original comment is below.


I just ran into this issue, but with AWS. I found out the root cause is actually a problem with the WinRM communicator. See this line:

https://github.com/hashicorp/terraform/blob/v0.6.13/communicator/winrm/communicator.go#L196

Terraform does not pass HTTPS, Insecure, or CACert connection information to the winrm copy client. Thus, it will always default to HTTP. Any provisioning that involves copying files to the VM will fail to work over HTTPS. I have a working fix for this that I will do a PR for soon.

That having been said, yes, you do have to set up WinRM for HTTPS first. This can be done using a user-data powershell script (in AWS anyway; not sure what the Azure equivalent is). You could also do this as a manual step and then generate a base machine image from it. I found this article helpful: http://www.jayway.com/2011/11/21/winrm-w-self-signed-certificate-in-4-steps/

That article uses makecert, but you can just as easily use the New-SelfSignedCertificate powershell cmdlet. Or, if you don't like self-signed certificates, write a script that requests a certificate from a local certifying authority.

Also keep in mind that Windows has its own firewall that needs to be configured to allow incoming WinRM connections. By default, Windows Firewall has rules for WinRM, but they are not enabled, and they do not apply so much to interfaces that Windows considers "public". In my case, I just used New-NetFirewallRule to create the necessary rule for port 5986.

vancluever commented 6 years ago

Hello!

Thank you for opening this issue and participating in the discussion. Today (December 19, 2017) we’ve announced the deprecation and archival of the Azure Classic Provider. Matching Microsoft’s commitment to gradually remove access to Azure Classic (or Service Management) which is outlined in this blog post, we are closing all open PR's and Issues here. This repository will remain available here on GitHub, but in an archived state, and no longer receiving support or new releases.

The Azure (Resource Manager) Provider remains fully supported and is our recommended approach for managing Azure with Terraform. More information about this process is available in the blog post linked above.

Thanks! The Terraform Team