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