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 }