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

     1  package azurerm
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"net/http"
     8  	"strings"
     9  
    10  	"github.com/Azure/azure-sdk-for-go/arm/trafficmanager"
    11  	"github.com/hashicorp/terraform/helper/hashcode"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  	"github.com/hashicorp/terraform/helper/validation"
    14  )
    15  
    16  func resourceArmTrafficManagerProfile() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceArmTrafficManagerProfileCreate,
    19  		Read:   resourceArmTrafficManagerProfileRead,
    20  		Update: resourceArmTrafficManagerProfileCreate,
    21  		Delete: resourceArmTrafficManagerProfileDelete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"name": {
    28  				Type:     schema.TypeString,
    29  				Required: true,
    30  				ForceNew: true,
    31  			},
    32  
    33  			"profile_status": {
    34  				Type:         schema.TypeString,
    35  				Optional:     true,
    36  				Computed:     true,
    37  				ValidateFunc: validation.StringInSlice([]string{"Enabled", "Disabled"}, true),
    38  			},
    39  
    40  			"traffic_routing_method": {
    41  				Type:         schema.TypeString,
    42  				Required:     true,
    43  				ValidateFunc: validation.StringInSlice([]string{"Performance", "Weighted", "Priority"}, false),
    44  			},
    45  
    46  			"dns_config": {
    47  				Type:     schema.TypeSet,
    48  				Required: true,
    49  				Elem: &schema.Resource{
    50  					Schema: map[string]*schema.Schema{
    51  						"relative_name": {
    52  							Type:     schema.TypeString,
    53  							ForceNew: true,
    54  							Required: true,
    55  						},
    56  						"ttl": {
    57  							Type:         schema.TypeInt,
    58  							Required:     true,
    59  							ValidateFunc: validation.IntBetween(30, 999999),
    60  						},
    61  					},
    62  				},
    63  				Set: resourceAzureRMTrafficManagerDNSConfigHash,
    64  			},
    65  
    66  			// inlined from dns_config for ease of use
    67  			"fqdn": {
    68  				Type:     schema.TypeString,
    69  				Computed: true,
    70  			},
    71  
    72  			"monitor_config": {
    73  				Type:     schema.TypeSet,
    74  				Required: true,
    75  				Elem: &schema.Resource{
    76  					Schema: map[string]*schema.Schema{
    77  						"protocol": {
    78  							Type:         schema.TypeString,
    79  							Required:     true,
    80  							ValidateFunc: validation.StringInSlice([]string{"http", "https"}, false),
    81  						},
    82  						"port": {
    83  							Type:         schema.TypeInt,
    84  							Required:     true,
    85  							ValidateFunc: validation.IntBetween(1, 65535),
    86  						},
    87  						"path": {
    88  							Type:     schema.TypeString,
    89  							Required: true,
    90  						},
    91  					},
    92  				},
    93  				Set: resourceAzureRMTrafficManagerMonitorConfigHash,
    94  			},
    95  
    96  			"resource_group_name": {
    97  				Type:             schema.TypeString,
    98  				Required:         true,
    99  				ForceNew:         true,
   100  				DiffSuppressFunc: resourceAzurermResourceGroupNameDiffSuppress,
   101  			},
   102  
   103  			"tags": tagsSchema(),
   104  		},
   105  	}
   106  }
   107  
   108  func resourceArmTrafficManagerProfileCreate(d *schema.ResourceData, meta interface{}) error {
   109  	client := meta.(*ArmClient).trafficManagerProfilesClient
   110  
   111  	log.Printf("[INFO] preparing arguments for Azure ARM virtual network creation.")
   112  
   113  	name := d.Get("name").(string)
   114  	// must be provided in request
   115  	location := "global"
   116  	resGroup := d.Get("resource_group_name").(string)
   117  	tags := d.Get("tags").(map[string]interface{})
   118  
   119  	profile := trafficmanager.Profile{
   120  		Name:              &name,
   121  		Location:          &location,
   122  		ProfileProperties: getArmTrafficManagerProfileProperties(d),
   123  		Tags:              expandTags(tags),
   124  	}
   125  
   126  	_, err := client.CreateOrUpdate(resGroup, name, profile)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	read, err := client.Get(resGroup, name)
   132  	if err != nil {
   133  		return err
   134  	}
   135  	if read.ID == nil {
   136  		return fmt.Errorf("Cannot read TrafficManager profile %s (resource group %s) ID", name, resGroup)
   137  	}
   138  
   139  	d.SetId(*read.ID)
   140  
   141  	return resourceArmTrafficManagerProfileRead(d, meta)
   142  }
   143  
   144  func resourceArmTrafficManagerProfileRead(d *schema.ResourceData, meta interface{}) error {
   145  	client := meta.(*ArmClient).trafficManagerProfilesClient
   146  
   147  	id, err := parseAzureResourceID(d.Id())
   148  	if err != nil {
   149  		return err
   150  	}
   151  	resGroup := id.ResourceGroup
   152  	name := id.Path["trafficManagerProfiles"]
   153  
   154  	resp, err := client.Get(resGroup, name)
   155  	if err != nil {
   156  		if resp.StatusCode == http.StatusNotFound {
   157  			d.SetId("")
   158  			return nil
   159  		}
   160  		return fmt.Errorf("Error making Read request on Traffic Manager Profile %s: %s", name, err)
   161  	}
   162  
   163  	profile := *resp.ProfileProperties
   164  
   165  	// update appropriate values
   166  	d.Set("resource_group_name", resGroup)
   167  	d.Set("name", resp.Name)
   168  	d.Set("profile_status", profile.ProfileStatus)
   169  	d.Set("traffic_routing_method", profile.TrafficRoutingMethod)
   170  
   171  	dnsFlat := flattenAzureRMTrafficManagerProfileDNSConfig(profile.DNSConfig)
   172  	d.Set("dns_config", schema.NewSet(resourceAzureRMTrafficManagerDNSConfigHash, dnsFlat))
   173  
   174  	// fqdn is actually inside DNSConfig, inlined for simpler reference
   175  	d.Set("fqdn", profile.DNSConfig.Fqdn)
   176  
   177  	monitorFlat := flattenAzureRMTrafficManagerProfileMonitorConfig(profile.MonitorConfig)
   178  	d.Set("monitor_config", schema.NewSet(resourceAzureRMTrafficManagerMonitorConfigHash, monitorFlat))
   179  
   180  	flattenAndSetTags(d, resp.Tags)
   181  
   182  	return nil
   183  }
   184  
   185  func resourceArmTrafficManagerProfileDelete(d *schema.ResourceData, meta interface{}) error {
   186  	client := meta.(*ArmClient).trafficManagerProfilesClient
   187  
   188  	id, err := parseAzureResourceID(d.Id())
   189  	if err != nil {
   190  		return err
   191  	}
   192  	resGroup := id.ResourceGroup
   193  	name := id.Path["trafficManagerProfiles"]
   194  
   195  	_, err = client.Delete(resGroup, name)
   196  
   197  	return err
   198  }
   199  
   200  func getArmTrafficManagerProfileProperties(d *schema.ResourceData) *trafficmanager.ProfileProperties {
   201  	routingMethod := d.Get("traffic_routing_method").(string)
   202  	props := &trafficmanager.ProfileProperties{
   203  		TrafficRoutingMethod: &routingMethod,
   204  		DNSConfig:            expandArmTrafficManagerDNSConfig(d),
   205  		MonitorConfig:        expandArmTrafficManagerMonitorConfig(d),
   206  	}
   207  
   208  	if status, ok := d.GetOk("profile_status"); ok {
   209  		s := status.(string)
   210  		props.ProfileStatus = &s
   211  	}
   212  
   213  	return props
   214  }
   215  
   216  func expandArmTrafficManagerMonitorConfig(d *schema.ResourceData) *trafficmanager.MonitorConfig {
   217  	monitorSets := d.Get("monitor_config").(*schema.Set).List()
   218  	monitor := monitorSets[0].(map[string]interface{})
   219  
   220  	proto := monitor["protocol"].(string)
   221  	port := int64(monitor["port"].(int))
   222  	path := monitor["path"].(string)
   223  
   224  	return &trafficmanager.MonitorConfig{
   225  		Protocol: &proto,
   226  		Port:     &port,
   227  		Path:     &path,
   228  	}
   229  }
   230  
   231  func expandArmTrafficManagerDNSConfig(d *schema.ResourceData) *trafficmanager.DNSConfig {
   232  	dnsSets := d.Get("dns_config").(*schema.Set).List()
   233  	dns := dnsSets[0].(map[string]interface{})
   234  
   235  	name := dns["relative_name"].(string)
   236  	ttl := int64(dns["ttl"].(int))
   237  
   238  	return &trafficmanager.DNSConfig{
   239  		RelativeName: &name,
   240  		TTL:          &ttl,
   241  	}
   242  }
   243  
   244  func flattenAzureRMTrafficManagerProfileDNSConfig(dns *trafficmanager.DNSConfig) []interface{} {
   245  	result := make(map[string]interface{})
   246  
   247  	result["relative_name"] = *dns.RelativeName
   248  	result["ttl"] = int(*dns.TTL)
   249  
   250  	return []interface{}{result}
   251  }
   252  
   253  func flattenAzureRMTrafficManagerProfileMonitorConfig(cfg *trafficmanager.MonitorConfig) []interface{} {
   254  	result := make(map[string]interface{})
   255  
   256  	result["protocol"] = *cfg.Protocol
   257  	result["port"] = int(*cfg.Port)
   258  	result["path"] = *cfg.Path
   259  
   260  	return []interface{}{result}
   261  }
   262  
   263  func resourceAzureRMTrafficManagerDNSConfigHash(v interface{}) int {
   264  	var buf bytes.Buffer
   265  	m := v.(map[string]interface{})
   266  
   267  	buf.WriteString(fmt.Sprintf("%s-", m["relative_name"].(string)))
   268  	buf.WriteString(fmt.Sprintf("%d-", m["ttl"].(int)))
   269  
   270  	return hashcode.String(buf.String())
   271  }
   272  
   273  func resourceAzureRMTrafficManagerMonitorConfigHash(v interface{}) int {
   274  	var buf bytes.Buffer
   275  	m := v.(map[string]interface{})
   276  
   277  	buf.WriteString(fmt.Sprintf("%s-", strings.ToLower(m["protocol"].(string))))
   278  	buf.WriteString(fmt.Sprintf("%d-", m["port"].(int)))
   279  	buf.WriteString(fmt.Sprintf("%s-", m["path"].(string)))
   280  
   281  	return hashcode.String(buf.String())
   282  }