diff --git a/builtin/providers/azurerm/config.go b/builtin/providers/azurerm/config.go index 43655b6cf..e25cd96fe 100644 --- a/builtin/providers/azurerm/config.go +++ b/builtin/providers/azurerm/config.go @@ -56,7 +56,11 @@ func withRequestLogging() autorest.SendDecorator { return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) { log.Printf("[DEBUG] Sending Azure RM Request %s to %s\n", r.Method, r.URL) resp, err := s.Do(r) - log.Printf("[DEBUG] Received Azure RM Request status code %s for %s\n", resp.Status, r.URL) + if resp != nil { + log.Printf("[DEBUG] Received Azure RM Request status code %s for %s\n", resp.Status, r.URL) + } else { + log.Printf("[DEBUG] Request to %s completed with no response", r.URL) + } return resp, err }) } diff --git a/builtin/providers/azurerm/resource_arm_availability_set.go b/builtin/providers/azurerm/resource_arm_availability_set.go index 3eb7c8506..74efc886d 100644 --- a/builtin/providers/azurerm/resource_arm_availability_set.go +++ b/builtin/providers/azurerm/resource_arm_availability_set.go @@ -23,6 +23,12 @@ func resourceArmAvailabilitySet() *schema.Resource { ForceNew: true, }, + "resource_group_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "location": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -58,11 +64,7 @@ func resourceArmAvailabilitySet() *schema.Resource { }, }, - "resource_group_name": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, + "tags": tagsSchema(), }, } } @@ -78,6 +80,7 @@ func resourceArmAvailabilitySetCreate(d *schema.ResourceData, meta interface{}) resGroup := d.Get("resource_group_name").(string) updateDomainCount := d.Get("platform_update_domain_count").(int) faultDomainCount := d.Get("platform_fault_domain_count").(int) + tags := d.Get("tags").(map[string]interface{}) availSet := compute.AvailabilitySet{ Name: &name, @@ -86,6 +89,7 @@ func resourceArmAvailabilitySetCreate(d *schema.ResourceData, meta interface{}) PlatformFaultDomainCount: &faultDomainCount, PlatformUpdateDomainCount: &updateDomainCount, }, + Tags: expandTags(tags), } resp, err := availSetClient.CreateOrUpdate(resGroup, name, availSet) @@ -121,6 +125,8 @@ func resourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) er d.Set("platform_update_domain_count", availSet.PlatformUpdateDomainCount) d.Set("platform_fault_domain_count", availSet.PlatformFaultDomainCount) + flattenAndSetTags(d, resp.Tags) + return nil } diff --git a/builtin/providers/azurerm/tags.go b/builtin/providers/azurerm/tags.go new file mode 100644 index 000000000..60255a323 --- /dev/null +++ b/builtin/providers/azurerm/tags.go @@ -0,0 +1,76 @@ +package azurerm + +import ( + "errors" + "fmt" + + "github.com/hashicorp/terraform/helper/schema" +) + +func tagsSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + ValidateFunc: validateAzureRMTags, + } +} + +func tagValueToString(v interface{}) (string, error) { + switch value := v.(type) { + case string: + return value, nil + case int: + return fmt.Sprintf("%d", value), nil + default: + return "", fmt.Errorf("unknown tag type %T in tag value", value) + } +} + +func validateAzureRMTags(v interface{}, k string) (ws []string, es []error) { + tagsMap := v.(map[string]interface{}) + + if len(tagsMap) > 15 { + es = append(es, errors.New("a maximum of 15 tags can be applied to each ARM resource")) + } + + for k, v := range tagsMap { + if len(k) > 512 { + es = append(es, fmt.Errorf("the maximum length for a tag key is 512 characters: %q is %d characters", k, len(k))) + } + + value, err := tagValueToString(v) + if err != nil { + es = append(es, err) + } else if len(value) > 256 { + es = append(es, fmt.Errorf("the maximum length for a tag value is 256 characters: the value for %q is %d characters", k, len(value))) + } + } + + return +} + +func expandTags(tagsMap map[string]interface{}) *map[string]*string { + output := make(map[string]*string, len(tagsMap)) + + for i, v := range tagsMap { + //Validate should have ignored this error already + value, _ := tagValueToString(v) + output[i] = &value + } + + return &output +} + +func flattenAndSetTags(d *schema.ResourceData, tagsMap *map[string]*string) { + if tagsMap == nil { + return + } + + output := make(map[string]interface{}, len(*tagsMap)) + + for i, v := range *tagsMap { + output[i] = *v + } + + d.Set("tags", output) +}