func main() {
	psPath := "path/to/publishSettings"

	dnsName := "test-vm-from-go"
	storageAccount := "mystorageaccount"
	location := "central us"
	vmSize := "Small"
	vmImage := "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB"
	userName := "******"
	userPassword := "******"

	fmt.Println("Create client")
	client, err := management.ClientFromPublishSettingsFile(fmt.Sprintf("%s.publishsettings", psPath), "")
	if err != nil {
		panic(err)
	}

	fmt.Println("Create hosted service")
	if err := hostedservice.NewClient(client).CreateHostedService(hostedservice.CreateHostedServiceParameters{
		ServiceName: dnsName,
		Location:    location,
		Label:       base64.StdEncoding.EncodeToString([]byte(dnsName))}); err != nil {
		panic(err)
	}

	fmt.Println("Create storage account")
	_, err = storageservice.NewClient(client).CreateStorageService(storageservice.StorageAccountCreateParameters{
		ServiceName: storageAccount,
		Label:       base64.URLEncoding.EncodeToString([]byte(storageAccount)),
		Location:    location,
		AccountType: storageservice.AccountTypeStandardLRS})
	if err != nil {
		panic(err)
	}

	fmt.Println("Create virtual machine")
	role := vmutils.NewVMConfiguration(dnsName, vmSize)
	vmutils.ConfigureDeploymentFromPlatformImage(
		&role,
		vmImage,
		fmt.Sprintf("http://%s.blob.core.windows.net/%s/%s.vhd", storageAccount, dnsName, dnsName),
		"")
	vmutils.ConfigureForLinux(&role, dnsName, userName, userPassword)
	vmutils.ConfigureWithPublicSSH(&role)

	fmt.Println("Deploy")
	operationID, err := virtualmachine.NewClient(client).
		CreateDeployment(role, dnsName, virtualmachine.CreateDeploymentOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Println("Waiting...")
	if err = client.WaitForOperation(operationID, nil); err != nil {
		panic(err)
	}
}
func createRole(isOSImage bool, vmName, vmSize, certThumbprint, userName, osImageName, mediaLoc string) (role vm.Role) {
	role = vmutils.NewVMConfiguration(vmName, vmSize)
	vmutils.ConfigureForLinux(&role, vmName, userName, "", certThumbprint)
	vmutils.ConfigureWithPublicSSH(&role)
	if isOSImage {
		vmutils.ConfigureDeploymentFromPlatformImage(&role, osImageName, mediaLoc, "")
	} else {
		vmutils.ConfigureDeploymentFromVMImage(&role, osImageName, mediaLoc, true)
	}
	return role
}
Beispiel #3
0
//
// configureForLinux sets up the VM role for Linux specific configuration
//
// Paramters:
//   role: role that needs to be updated with Linux configuration
//   dnsName: name of the machine that we are trying to create
//
// Returns:
//   error: errors from reading certs, getting thumbprint and adding
//   certificate to hostedservice
//
func (d *Driver) configureForLinux(role *virtualmachine.Role, dnsName string) error {

	// Get the Azure client
	client, err := d.getClient()
	if err != nil {
		return err
	}

	mediaLink := fmt.Sprintf("http://%s.blob.core.windows.net/vhds/%s.vhd",
		d.StorageAccount, dnsName)

	// Setup the image configuration
	vmutils.ConfigureDeploymentFromPlatformImage(
		role,
		d.Image,
		mediaLink,
		"")

	// Read the certificate
	data, err := ioutil.ReadFile(d.azureCertPath())
	if err != nil {
		return err
	}

	// Add the certificate to the hostedservice
	if _, err := hostedservice.NewClient(client).AddCertificate(dnsName, data, "pfx", ""); err != nil {
		return err
	}

	thumbPrint, err := getServiceCertFingerprint(d.azureCertPath())
	if err != nil {
		return err
	}

	vmutils.ConfigureForLinux(role, dnsName, d.SSHUser, d.UserPassword, thumbPrint)
	vmutils.ConfigureWithPublicSSH(role)

	role.UseCertAuth = true
	role.CertPath = d.azureCertPath()

	// Attach VM to a specific subnet
	if d.Subnet != "" {
		err = vmutils.ConfigureWithSubnet(role, d.Subnet)
		if err != nil {
			log.Error("failed to configure subnet:", d.Subnet, ", err:", err)
			return err
		}
		log.Debug("subnet is:", d.Subnet)
	}

	return nil
}
func main() {
	dnsName := "test-vm-from-go"
	storageAccount := "gosdktest"
	location := "West US"
	vmSize := "Small"
	vmImage := "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB"
	userName := "******"
	userPassword := "******"

	client, err := management.ClientFromPublishSettingsFile("/Users/niklasg/Downloads/Internal-credentials.publishsettings", "")
	if err != nil {
		panic(err)
	}

	// create hosted service
	if err := hostedservice.NewClient(client).CreateHostedService(hostedservice.CreateHostedServiceParameters{
		ServiceName: dnsName,
		Location:    location,
		Label:       base64.StdEncoding.EncodeToString([]byte(dnsName))}); err != nil {

		if azErr, ok := err.(management.AzureError); !ok || azErr.Code != "ConflictError" {
			panic(err)
		}
	}

	// create virtual machine
	role := vmutils.NewVMConfiguration(dnsName, vmSize)
	vmutils.ConfigureDeploymentFromPlatformImage(
		&role,
		vmImage,
		fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", storageAccount, dnsName),
		"")
	vmutils.ConfigureForLinux(&role, dnsName, userName, userPassword)
	vmutils.ConfigureWithPublicSSH(&role)

	operationID, err := virtualmachine.NewClient(client).
		CreateDeployment(role, dnsName, virtualmachine.CreateDeploymentOptions{})
	if err != nil {
		panic(err)
	}
	if err := client.WaitForOperation(operationID, nil); err != nil {
		panic(err)
	}
}
func resourceAzureInstanceCreate(d *schema.ResourceData, meta interface{}) (err error) {
	azureClient := meta.(*Client)
	mc := azureClient.mgmtClient
	hostedServiceClient := azureClient.hostedServiceClient
	vmClient := azureClient.vmClient

	name := d.Get("name").(string)

	// Compute/set the description
	description := d.Get("description").(string)
	if description == "" {
		description = name
	}

	// Retrieve the needed details of the image
	configureForImage, osType, err := retrieveImageDetails(
		meta,
		d.Get("image").(string),
		name,
		d.Get("storage_service_name").(string),
	)
	if err != nil {
		return err
	}

	// Verify if we have all required parameters
	if err := verifyInstanceParameters(d, osType); err != nil {
		return err
	}

	var hostedServiceName string
	// check if hosted service name parameter was given:
	if serviceName, ok := d.GetOk("hosted_service_name"); !ok {
		// if not provided; just use the name of the instance to create a new one:
		hostedServiceName = name
		d.Set("hosted_service_name", hostedServiceName)

		p := hostedservice.CreateHostedServiceParameters{
			ServiceName:    hostedServiceName,
			Label:          base64.StdEncoding.EncodeToString([]byte(name)),
			Description:    fmt.Sprintf("Cloud Service created automatically for instance %s", name),
			Location:       d.Get("location").(string),
			ReverseDNSFqdn: d.Get("reverse_dns").(string),
		}

		log.Printf("[DEBUG] Creating Cloud Service for instance: %s", name)
		err = hostedServiceClient.CreateHostedService(p)
		if err != nil {
			return fmt.Errorf("Error creating Cloud Service for instance %s: %s", name, err)
		}
	} else {
		// else; use the provided hosted service name:
		hostedServiceName = serviceName.(string)
	}

	// Create a new role for the instance
	role := vmutils.NewVMConfiguration(name, d.Get("size").(string))

	log.Printf("[DEBUG] Configuring deployment from image...")
	err = configureForImage(&role)
	if err != nil {
		return fmt.Errorf("Error configuring the deployment for %s: %s", name, err)
	}

	if osType == linux {
		// This is pretty ugly, but the Azure SDK leaves me no other choice...
		if tp, ok := d.GetOk("ssh_key_thumbprint"); ok {
			err = vmutils.ConfigureForLinux(
				&role,
				name,
				d.Get("username").(string),
				d.Get("password").(string),
				tp.(string),
			)
		} else {
			err = vmutils.ConfigureForLinux(
				&role,
				name,
				d.Get("username").(string),
				d.Get("password").(string),
			)
		}
		if err != nil {
			return fmt.Errorf("Error configuring %s for Linux: %s", name, err)
		}
	}

	if osType == windows {
		err = vmutils.ConfigureForWindows(
			&role,
			name,
			d.Get("username").(string),
			d.Get("password").(string),
			d.Get("automatic_updates").(bool),
			d.Get("time_zone").(string),
		)
		if err != nil {
			return fmt.Errorf("Error configuring %s for Windows: %s", name, err)
		}

		if domain_name, ok := d.GetOk("domain_name"); ok {
			err = vmutils.ConfigureWindowsToJoinDomain(
				&role,
				d.Get("domain_username").(string),
				d.Get("domain_password").(string),
				domain_name.(string),
				d.Get("domain_ou").(string),
			)
			if err != nil {
				return fmt.Errorf("Error configuring %s for WindowsToJoinDomain: %s", name, err)
			}
		}
	}

	if s := d.Get("endpoint").(*schema.Set); s.Len() > 0 {
		for _, v := range s.List() {
			m := v.(map[string]interface{})
			err := vmutils.ConfigureWithExternalPort(
				&role,
				m["name"].(string),
				m["private_port"].(int),
				m["public_port"].(int),
				endpointProtocol(m["protocol"].(string)),
			)
			if err != nil {
				return fmt.Errorf(
					"Error adding endpoint %s for instance %s: %s", m["name"].(string), name, err)
			}
		}
	}

	if subnet, ok := d.GetOk("subnet"); ok {
		err = vmutils.ConfigureWithSubnet(&role, subnet.(string))
		if err != nil {
			return fmt.Errorf(
				"Error associating subnet %s with instance %s: %s", d.Get("subnet").(string), name, err)
		}
	}

	if sg, ok := d.GetOk("security_group"); ok {
		err = vmutils.ConfigureWithSecurityGroup(&role, sg.(string))
		if err != nil {
			return fmt.Errorf(
				"Error associating security group %s with instance %s: %s", sg.(string), name, err)
		}
	}

	options := virtualmachine.CreateDeploymentOptions{
		VirtualNetworkName: d.Get("virtual_network").(string),
	}

	log.Printf("[DEBUG] Creating the new instance...")
	req, err := vmClient.CreateDeployment(role, hostedServiceName, options)
	if err != nil {
		return fmt.Errorf("Error creating instance %s: %s", name, err)
	}

	log.Printf("[DEBUG] Waiting for the new instance to be created...")
	if err := mc.WaitForOperation(req, nil); err != nil {
		return fmt.Errorf(
			"Error waiting for instance %s to be created: %s", name, err)
	}

	d.SetId(name)

	return resourceAzureInstanceRead(d, meta)
}
Beispiel #6
0
func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
	client := state.Get(constants.RequestManager).(management.Client)
	ui := state.Get(constants.Ui).(packer.Ui)
	config := state.Get(constants.Config).(*Config)

	ui.Say("Validating Azure options...")

	role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)

	ui.Message("Checking Storage Account...")
	destinationVhd, err := validateStorageAccount(config, client)
	if err != nil {
		err = fmt.Errorf("Error checking storage account: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}
	ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))

	if err := func() error {
		if config.RemoteSourceImageLink != "" {
			ui.Message("Checking remote image source link...")
			response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
			if response != nil && response.Body != nil {
				defer response.Body.Close()
			}
			if err != nil {
				log.Printf("HTTP client returned error: %s", err)
				return fmt.Errorf("error checking remote image source link: %v", err)
			}
			if response.StatusCode != 200 {
				return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
			}
			size := float64(response.ContentLength) / 1024 / 1024 / 1024
			ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))

			vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
			if config.ResizeOSVhdGB != nil {
				if float64(*config.ResizeOSVhdGB) < size {
					return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, size)
				}
				ui.Say(fmt.Sprintf("Remote image will be resized to %d GiB", *config.ResizeOSVhdGB))
				role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
			}

		} else {
			ui.Message("Checking image source...")
			imageList, err := osimage.NewClient(client).ListOSImages()
			if err != nil {
				log.Printf("OS image client returned error: %s", err)
				return err
			}

			if osImage, found := FindOSImage(imageList.OSImages, config.OSImageLabel, config.Location); found {
				vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
				ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
				if osImage.OS != config.OSType {
					return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
				}
				if config.ResizeOSVhdGB != nil {
					if float64(*config.ResizeOSVhdGB) < osImage.LogicalSizeInGB {
						return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, osImage.LogicalSizeInGB)
					}
					ui.Say(fmt.Sprintf("OS image will be resized to %d GiB", *config.ResizeOSVhdGB))
					role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
				}
			} else {
				imageList, err := vmimage.NewClient(client).ListVirtualMachineImages(
					vmimage.ListParameters{
						Location: config.Location,
					})
				if err != nil {
					log.Printf("VM image client returned error: %s", err)
					return err
				}

				if vmImage, found := FindVmImage(imageList.VMImages, "", config.OSImageLabel); found {
					if config.ResizeOSVhdGB != nil {
						return fmt.Errorf("Packer cannot resize VM images")
					}
					if vmImage.OSDiskConfiguration.OSState != vmimage.OSStateGeneralized {
						return fmt.Errorf("Packer can only use VM user images with a generalized OS so that it can be reprovisioned. The specified image OS is not in a generalized state.")
					}

					if vmImage.Category == vmimage.CategoryUser {
						//vmutils.ConfigureDeploymentFromUserVMImage(&role, vmImage.Name)
						role.VMImageName = vmImage.Name
					} else {
						vmutils.ConfigureDeploymentFromPublishedVMImage(&role, vmImage.Name, destinationVhd, true)
					}

					ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
					if vmImage.OSDiskConfiguration.OS != config.OSType {
						return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
					}
				} else {
					return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
				}
			}
		}
		return nil
	}(); err != nil {
		err = fmt.Errorf("Error determining deployment source: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	if config.OSType == constants.Target_Linux {
		certThumbprint := state.Get(constants.Thumbprint).(string)
		if len(certThumbprint) == 0 {
			err := fmt.Errorf("Certificate Thumbprint is empty")
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureForLinux(&role, config.tmpVmName, config.UserName, "", certThumbprint)

		// disallowing password login is irreversible on some images, see https://github.com/Azure/packer-azure/issues/62
		for i, _ := range role.ConfigurationSets {
			if role.ConfigurationSets[i].ConfigurationSetType == vm.ConfigurationSetTypeLinuxProvisioning {
				role.ConfigurationSets[i].DisableSSHPasswordAuthentication = "false"
			}
		}

		vmutils.ConfigureWithPublicSSH(&role)
	} else if config.OSType == constants.Target_Windows {
		password := common.RandomPassword()
		state.Put("password", password)
		vmutils.ConfigureForWindows(&role, config.tmpVmName, config.UserName, password, true, "")
		vmutils.ConfigureWithPublicRDP(&role)
		vmutils.ConfigureWithPublicPowerShell(&role)
	}

	if config.VNet != "" && config.Subnet != "" {
		ui.Message("Checking VNet...")
		if err := checkVirtualNetworkConfiguration(client, config.VNet, config.Subnet, config.Location); err != nil {
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureWithSubnet(&role, config.Subnet)
	}

	for n, d := range config.DataDisks {
		switch d := d.(type) {
		case int:
			ui.Message(fmt.Sprintf("Configuring datadisk %d: new disk with size %d GB...", n, d))
			destination := fmt.Sprintf("%s-data-%d.vhd", destinationVhd[:len(destinationVhd)-4], n)
			ui.Message(fmt.Sprintf("Destination VHD for data disk %s: %d", destinationVhd, n))
			vmutils.ConfigureWithNewDataDisk(&role, "", destination, d, vmdisk.HostCachingTypeNone)
		case string:
			ui.Message(fmt.Sprintf("Configuring datadisk %d: existing blob (%s)...", n, d))
			vmutils.ConfigureWithVhdDataDisk(&role, d, vmdisk.HostCachingTypeNone)
		default:
			err := fmt.Errorf("Datadisk %d is not a string nor a number", n)
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}

	}

	state.Put("role", &role)

	return multistep.ActionContinue
}
func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
	client := state.Get(constants.RequestManager).(management.Client)
	ui := state.Get(constants.Ui).(packer.Ui)
	config := state.Get(constants.Config).(*Config)

	ui.Say("Validating Azure options...")

	role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)

	ui.Message("Checking Storage Account...")
	destinationVhd, err := validateStorageAccount(config, client)
	if err != nil {
		err = fmt.Errorf("Error checking storage account: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}
	ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))

	if err := func() error {
		if config.RemoteSourceImageLink != "" {
			ui.Message("Checking remote image source link...")
			response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
			if response != nil && response.Body != nil {
				defer response.Body.Close()
			}
			if err != nil {
				log.Printf("HTTP client returned error: %s", err)
				return fmt.Errorf("error checking remote image source link: %v", err)
			}
			if response.StatusCode != 200 {
				return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
			}
			size := float64(response.ContentLength) / 1024 / 1024 / 1024
			ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))

			vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
		} else {
			ui.Message("Checking image source...")
			imageList, err := osimage.NewClient(client).ListOSImages()
			if err != nil {
				log.Printf("OS image client returned error: %s", err)
				return err
			}

			if osImage, found := FindOSImage(imageList.OSImages, config.OSImageLabel, config.Location); found {
				vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
				ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
				if osImage.OS != config.OSType {
					return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
				}
			} else {
				imageList, err := vmimage.NewClient(client).ListVirtualMachineImages()
				if err != nil {
					log.Printf("VM image client returned error: %s", err)
					return err
				}

				if vmImage, found := FindVmImage(imageList.VMImages, "", config.OSImageLabel, config.Location); found {
					vmutils.ConfigureDeploymentFromVMImage(&role, vmImage.Name, destinationVhd, true)
					ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
					if vmImage.OSDiskConfiguration.OS != config.OSType {
						return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
					}
				} else {
					return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
				}
			}
		}
		return nil
	}(); err != nil {
		err = fmt.Errorf("Error determining deployment source: %v", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	if config.OSType == constants.Target_Linux {
		certThumbprint := state.Get(constants.Thumbprint).(string)
		if len(certThumbprint) == 0 {
			err := fmt.Errorf("Certificate Thumbprint is empty")
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureForLinux(&role, config.tmpVmName, config.UserName, "", certThumbprint)
		vmutils.ConfigureWithPublicSSH(&role)
	} else if config.OSType == constants.Target_Windows {
		password := utils.RandomPassword()
		state.Put("password", password)
		vmutils.ConfigureForWindows(&role, config.tmpVmName, config.UserName, password, true, "")
		vmutils.ConfigureWithPublicRDP(&role)
		vmutils.ConfigureWithPublicPowerShell(&role)
	}

	if config.VNet != "" && config.Subnet != "" {
		ui.Message("Checking VNet...")
		if err := checkVirtualNetworkConfiguration(client, config.VNet, config.Subnet, config.Location); err != nil {
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
		vmutils.ConfigureWithSubnet(&role, config.Subnet)
	}

	state.Put("role", &role)

	return multistep.ActionContinue
}