code: func (a AzureClient) waitVMPowerState(resourceGroup, name string, goalState VMPowerState, timeout time.Duration) error {
  	// NOTE(ahmetalpbalkan): Azure APIs for Start and Stop are actually async
  	// operations on which our SDK blocks and does polling until the operation
  	// is complete.
  	//
  	// By the time the issued power cycle operation is complete, the VM will be
  	// already in the goal PowerState. Hence, this method will return in the
  	// first check, however there is no harm in being defensive.
  	log.Debug("Waiting until VM reaches goal power state.", logutil.Fields{
  		"vm":        name,
  		"goalState": goalState,
  		"timeout":   timeout,
  	})
  
  	chErr := make(chan error)
  	go func(ch chan error) {
  		for {
  			select {
  			case <-ch:
  				// channel closed
  				return
  			default:
  				state, err := a.GetVirtualMachinePowerState(resourceGroup, name)
  				if err != nil {
  					ch <- err
  					return
  				}
  				if state != goalState {
  					log.Debug(fmt.Sprintf("Waiting %v...", powerStatePollingInterval),
  						logutil.Fields{
  							"goalState": goalState,
  							"state":     state,
  						})
  					time.Sleep(powerStatePollingInterval)
  				} else {
  					log.Debug("Reached goal power state.",
  						logutil.Fields{"state": state})
  					ch <- nil
  					return
  				}
  			}
  		}
  	}(chErr)
  
  	select {
  	case <-time.After(timeout):
  		close(chErr)
  		return fmt.Errorf("Waiting for goal state %q timed out after %v", goalState, timeout)
  	case err := <-chErr:
  		return err
  	}
  }
docs: // waitVMPowerState polls the Virtual Machine instance view until it reaches the
  // specified goal power state or times out. If checking for virtual machine
  // state fails or waiting times out, an error is returned.