github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/azurerm/resource_arm_virtual_machine_extension.go (about)

     1  package azurerm
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"reflect"
     8  
     9  	"github.com/Azure/azure-sdk-for-go/arm/compute"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  )
    12  
    13  func resourceArmVirtualMachineExtensions() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceArmVirtualMachineExtensionsCreate,
    16  		Read:   resourceArmVirtualMachineExtensionsRead,
    17  		Update: resourceArmVirtualMachineExtensionsCreate,
    18  		Delete: resourceArmVirtualMachineExtensionsDelete,
    19  		Importer: &schema.ResourceImporter{
    20  			State: schema.ImportStatePassthrough,
    21  		},
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"name": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: true,
    28  			},
    29  
    30  			"location": locationSchema(),
    31  
    32  			"resource_group_name": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Required: true,
    35  				ForceNew: true,
    36  			},
    37  
    38  			"virtual_machine_name": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Required: true,
    41  				ForceNew: true,
    42  			},
    43  
    44  			"publisher": &schema.Schema{
    45  				Type:     schema.TypeString,
    46  				Required: true,
    47  			},
    48  
    49  			"type": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Required: true,
    52  			},
    53  
    54  			"type_handler_version": &schema.Schema{
    55  				Type:     schema.TypeString,
    56  				Required: true,
    57  			},
    58  
    59  			"auto_upgrade_minor_version": {
    60  				Type:     schema.TypeBool,
    61  				Optional: true,
    62  			},
    63  
    64  			"settings": &schema.Schema{
    65  				Type:             schema.TypeString,
    66  				Optional:         true,
    67  				ValidateFunc:     validateJsonString,
    68  				DiffSuppressFunc: suppressDiffVirtualMachineExtensionSettings,
    69  			},
    70  
    71  			// due to the sensitive nature, these are not returned by the API
    72  			"protected_settings": &schema.Schema{
    73  				Type:             schema.TypeString,
    74  				Optional:         true,
    75  				Sensitive:        true,
    76  				ValidateFunc:     validateJsonString,
    77  				DiffSuppressFunc: suppressDiffVirtualMachineExtensionSettings,
    78  			},
    79  
    80  			"tags": tagsSchema(),
    81  		},
    82  	}
    83  }
    84  
    85  func resourceArmVirtualMachineExtensionsCreate(d *schema.ResourceData, meta interface{}) error {
    86  	client := meta.(*ArmClient).vmExtensionClient
    87  
    88  	name := d.Get("name").(string)
    89  	location := d.Get("location").(string)
    90  	vmName := d.Get("virtual_machine_name").(string)
    91  	resGroup := d.Get("resource_group_name").(string)
    92  	publisher := d.Get("publisher").(string)
    93  	extensionType := d.Get("type").(string)
    94  	typeHandlerVersion := d.Get("type_handler_version").(string)
    95  	autoUpgradeMinor := d.Get("auto_upgrade_minor_version").(bool)
    96  	tags := d.Get("tags").(map[string]interface{})
    97  
    98  	extension := compute.VirtualMachineExtension{
    99  		Location: &location,
   100  		VirtualMachineExtensionProperties: &compute.VirtualMachineExtensionProperties{
   101  			Publisher:               &publisher,
   102  			Type:                    &extensionType,
   103  			TypeHandlerVersion:      &typeHandlerVersion,
   104  			AutoUpgradeMinorVersion: &autoUpgradeMinor,
   105  		},
   106  		Tags: expandTags(tags),
   107  	}
   108  
   109  	if settingsString := d.Get("settings").(string); settingsString != "" {
   110  		settings, err := expandArmVirtualMachineExtensionSettings(settingsString)
   111  		if err != nil {
   112  			return fmt.Errorf("unable to parse settings: %s", err)
   113  		}
   114  		extension.VirtualMachineExtensionProperties.Settings = &settings
   115  	}
   116  
   117  	if protectedSettingsString := d.Get("protected_settings").(string); protectedSettingsString != "" {
   118  		protectedSettings, err := expandArmVirtualMachineExtensionSettings(protectedSettingsString)
   119  		if err != nil {
   120  			return fmt.Errorf("unable to parse protected_settings: %s", err)
   121  		}
   122  		extension.VirtualMachineExtensionProperties.ProtectedSettings = &protectedSettings
   123  	}
   124  
   125  	_, err := client.CreateOrUpdate(resGroup, vmName, name, extension, make(chan struct{}))
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	read, err := client.Get(resGroup, vmName, name, "")
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	if read.ID == nil {
   136  		return fmt.Errorf("Cannot read  Virtual Machine Extension %s (resource group %s) ID", name, resGroup)
   137  	}
   138  
   139  	d.SetId(*read.ID)
   140  
   141  	return resourceArmVirtualMachineExtensionsRead(d, meta)
   142  }
   143  
   144  func resourceArmVirtualMachineExtensionsRead(d *schema.ResourceData, meta interface{}) error {
   145  	client := meta.(*ArmClient).vmExtensionClient
   146  
   147  	id, err := parseAzureResourceID(d.Id())
   148  	if err != nil {
   149  		return err
   150  	}
   151  	resGroup := id.ResourceGroup
   152  	vmName := id.Path["virtualMachines"]
   153  	name := id.Path["extensions"]
   154  
   155  	resp, err := client.Get(resGroup, vmName, name, "")
   156  
   157  	if err != nil {
   158  		if resp.StatusCode == http.StatusNotFound {
   159  			d.SetId("")
   160  			return nil
   161  		}
   162  		return fmt.Errorf("Error making Read request on Virtual Machine Extension %s: %s", name, err)
   163  	}
   164  
   165  	d.Set("name", resp.Name)
   166  	d.Set("location", azureRMNormalizeLocation(*resp.Location))
   167  	d.Set("virtual_machine_name", vmName)
   168  	d.Set("resource_group_name", resGroup)
   169  	d.Set("publisher", resp.VirtualMachineExtensionProperties.Publisher)
   170  	d.Set("type", resp.VirtualMachineExtensionProperties.Type)
   171  	d.Set("type_handler_version", resp.VirtualMachineExtensionProperties.TypeHandlerVersion)
   172  	d.Set("auto_upgrade_minor_version", resp.VirtualMachineExtensionProperties.AutoUpgradeMinorVersion)
   173  
   174  	if resp.VirtualMachineExtensionProperties.Settings != nil {
   175  		settings, err := flattenArmVirtualMachineExtensionSettings(*resp.VirtualMachineExtensionProperties.Settings)
   176  		if err != nil {
   177  			return fmt.Errorf("unable to parse settings from response: %s", err)
   178  		}
   179  		d.Set("settings", settings)
   180  	}
   181  
   182  	flattenAndSetTags(d, resp.Tags)
   183  
   184  	return nil
   185  }
   186  
   187  func resourceArmVirtualMachineExtensionsDelete(d *schema.ResourceData, meta interface{}) error {
   188  	client := meta.(*ArmClient).vmExtensionClient
   189  
   190  	id, err := parseAzureResourceID(d.Id())
   191  	if err != nil {
   192  		return err
   193  	}
   194  	resGroup := id.ResourceGroup
   195  	name := id.Path["extensions"]
   196  	vmName := id.Path["virtualMachines"]
   197  
   198  	_, err = client.Delete(resGroup, vmName, name, make(chan struct{}))
   199  
   200  	return nil
   201  }
   202  
   203  func expandArmVirtualMachineExtensionSettings(jsonString string) (map[string]interface{}, error) {
   204  	var result map[string]interface{}
   205  
   206  	err := json.Unmarshal([]byte(jsonString), &result)
   207  
   208  	return result, err
   209  }
   210  
   211  func flattenArmVirtualMachineExtensionSettings(settingsMap map[string]interface{}) (string, error) {
   212  	result, err := json.Marshal(settingsMap)
   213  	if err != nil {
   214  		return "", err
   215  	}
   216  
   217  	return string(result), nil
   218  }
   219  
   220  func suppressDiffVirtualMachineExtensionSettings(k, old, new string, d *schema.ResourceData) bool {
   221  	oldMap, err := expandArmVirtualMachineExtensionSettings(old)
   222  	if err != nil {
   223  		return false
   224  	}
   225  
   226  	newMap, err := expandArmVirtualMachineExtensionSettings(new)
   227  	if err != nil {
   228  		return false
   229  	}
   230  
   231  	return reflect.DeepEqual(oldMap, newMap)
   232  }