func resourceCloudcaInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
	ccaClient := meta.(*cca.CcaClient)
	resources, _ := ccaClient.GetResources(d.Get("service_code").(string), d.Get("environment_name").(string))
	ccaResources := resources.(cloudca.Resources)

	d.Partial(true)

	if d.HasChange("compute_offering") || d.HasChange("cpu_count") || d.HasChange("memory_in_mb") {
		newComputeOffering := d.Get("compute_offering").(string)
		log.Printf("[DEBUG] Compute offering has changed for %s, changing compute offering...", newComputeOffering)
		newComputeOfferingId, ferr := retrieveComputeOfferingID(&ccaResources, newComputeOffering)
		if ferr != nil {
			return ferr
		}
		instanceToUpdate := cloudca.Instance{Id: d.Id(),
			ComputeOfferingId: newComputeOfferingId,
		}

		hasCustomFields := false
		if cpuCount, ok := d.GetOk("cpu_count"); ok {
			instanceToUpdate.CpuCount = cpuCount.(int)
			hasCustomFields = true
		}
		if memoryInMB, ok := d.GetOk("memory_in_mb"); ok {
			instanceToUpdate.MemoryInMB = memoryInMB.(int)
			hasCustomFields = true
		}

		computeOffering, cerr := ccaResources.ComputeOfferings.Get(newComputeOfferingId)
		if cerr != nil {
			return cerr
		} else if !computeOffering.Custom && hasCustomFields {
			return fmt.Errorf("Cannot have a CPU count or memory in MB because \"%s\" isn't a custom compute offering", computeOffering.Name)
		}

		_, err := ccaResources.Instances.ChangeComputeOffering(instanceToUpdate)
		if err != nil {
			return err
		}
		d.SetPartial("compute_offering")
	}

	if d.HasChange("ssh_key_name") {
		sshKeyName := d.Get("ssh_key_name").(string)
		log.Printf("[DEBUG] SSH key name has changed for %s, associating new SSH key...", sshKeyName)
		_, err := ccaResources.Instances.AssociateSSHKey(d.Id(), sshKeyName)
		if err != nil {
			return err
		}
		d.SetPartial("ssh_key_name")
	}

	d.Partial(false)

	return nil
}
func resourceCloudcaInstanceCreate(d *schema.ResourceData, meta interface{}) error {
	ccaClient := meta.(*cca.CcaClient)
	resources, _ := ccaClient.GetResources(d.Get("service_code").(string), d.Get("environment_name").(string))
	ccaResources := resources.(cloudca.Resources)

	computeOfferingId, cerr := retrieveComputeOfferingID(&ccaResources, d.Get("compute_offering").(string))

	if cerr != nil {
		return cerr
	}

	templateId, terr := retrieveTemplateID(&ccaResources, d.Get("template").(string))

	if terr != nil {
		return terr
	}

	instanceToCreate := cloudca.Instance{Name: d.Get("name").(string),
		ComputeOfferingId: computeOfferingId,
		TemplateId:        templateId,
		NetworkId:         d.Get("network_id").(string),
	}

	if sshKeyname, ok := d.GetOk("ssh_key_name"); ok {
		instanceToCreate.SSHKeyName = sshKeyname.(string)
	}
	if publicKey, ok := d.GetOk("public_key"); ok {
		instanceToCreate.PublicKey = publicKey.(string)
	}
	if userData, ok := d.GetOk("user_data"); ok {
		instanceToCreate.UserData = userData.(string)
	}

	hasCustomFields := false
	if cpuCount, ok := d.GetOk("cpu_count"); ok {
		instanceToCreate.CpuCount = cpuCount.(int)
		hasCustomFields = true
	}
	if memoryInMB, ok := d.GetOk("memory_in_mb"); ok {
		instanceToCreate.MemoryInMB = memoryInMB.(int)
		hasCustomFields = true
	}

	computeOffering, cerr := ccaResources.ComputeOfferings.Get(computeOfferingId)
	if cerr != nil {
		return cerr
	} else if !computeOffering.Custom && hasCustomFields {
		return fmt.Errorf("Cannot have a CPU count or memory in MB because \"%s\" isn't a custom compute offering", computeOffering.Name)
	}

	newInstance, err := ccaResources.Instances.Create(instanceToCreate)
	if err != nil {
		return fmt.Errorf("Error creating the new instance %s: %s", instanceToCreate.Name, err)
	}

	d.SetId(newInstance.Id)
	d.SetConnInfo(map[string]string{
		"host":     newInstance.IpAddress,
		"user":     newInstance.Username,
		"password": newInstance.Password,
	})

	return resourceCloudcaInstanceRead(d, meta)
}