github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/builtin/providers/azurerm/resource_arm_loadbalancer.go (about) 1 package azurerm 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/Azure/azure-sdk-for-go/arm/network" 9 "github.com/hashicorp/errwrap" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 "github.com/jen20/riviera/azure" 13 ) 14 15 func resourceArmLoadBalancer() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceArmLoadBalancerCreate, 18 Read: resourecArmLoadBalancerRead, 19 Update: resourceArmLoadBalancerCreate, 20 Delete: resourceArmLoadBalancerDelete, 21 22 Schema: map[string]*schema.Schema{ 23 "name": { 24 Type: schema.TypeString, 25 Required: true, 26 ForceNew: true, 27 }, 28 29 "location": locationSchema(), 30 31 "resource_group_name": { 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 37 "frontend_ip_configuration": { 38 Type: schema.TypeList, 39 Optional: true, 40 MinItems: 1, 41 Elem: &schema.Resource{ 42 Schema: map[string]*schema.Schema{ 43 "name": { 44 Type: schema.TypeString, 45 Required: true, 46 }, 47 48 "subnet_id": { 49 Type: schema.TypeString, 50 Optional: true, 51 Computed: true, 52 }, 53 54 "private_ip_address": { 55 Type: schema.TypeString, 56 Optional: true, 57 Computed: true, 58 }, 59 60 "public_ip_address_id": { 61 Type: schema.TypeString, 62 Optional: true, 63 Computed: true, 64 }, 65 66 "private_ip_address_allocation": { 67 Type: schema.TypeString, 68 Optional: true, 69 Computed: true, 70 ValidateFunc: validateLoadBalancerPrivateIpAddressAllocation, 71 }, 72 73 "load_balancer_rules": { 74 Type: schema.TypeSet, 75 Computed: true, 76 Elem: &schema.Schema{Type: schema.TypeString}, 77 Set: schema.HashString, 78 }, 79 80 "inbound_nat_rules": { 81 Type: schema.TypeSet, 82 Computed: true, 83 Elem: &schema.Schema{Type: schema.TypeString}, 84 Set: schema.HashString, 85 }, 86 }, 87 }, 88 }, 89 90 "tags": tagsSchema(), 91 }, 92 } 93 } 94 95 func resourceArmLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error { 96 client := meta.(*ArmClient) 97 loadBalancerClient := client.loadBalancerClient 98 99 log.Printf("[INFO] preparing arguments for Azure ARM LoadBalancer creation.") 100 101 name := d.Get("name").(string) 102 location := d.Get("location").(string) 103 resGroup := d.Get("resource_group_name").(string) 104 tags := d.Get("tags").(map[string]interface{}) 105 expandedTags := expandTags(tags) 106 107 properties := network.LoadBalancerPropertiesFormat{} 108 109 if _, ok := d.GetOk("frontend_ip_configuration"); ok { 110 properties.FrontendIPConfigurations = expandAzureRmLoadBalancerFrontendIpConfigurations(d) 111 } 112 113 loadbalancer := network.LoadBalancer{ 114 Name: azure.String(name), 115 Location: azure.String(location), 116 Tags: expandedTags, 117 LoadBalancerPropertiesFormat: &properties, 118 } 119 120 _, err := loadBalancerClient.CreateOrUpdate(resGroup, name, loadbalancer, make(chan struct{})) 121 if err != nil { 122 return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err) 123 } 124 125 read, err := loadBalancerClient.Get(resGroup, name, "") 126 if err != nil { 127 return errwrap.Wrapf("Error Getting LoadBalancer {{err}", err) 128 } 129 if read.ID == nil { 130 return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", name, resGroup) 131 } 132 133 d.SetId(*read.ID) 134 135 log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", name) 136 stateConf := &resource.StateChangeConf{ 137 Pending: []string{"Accepted", "Updating"}, 138 Target: []string{"Succeeded"}, 139 Refresh: loadbalancerStateRefreshFunc(client, resGroup, name), 140 Timeout: 10 * time.Minute, 141 } 142 if _, err := stateConf.WaitForState(); err != nil { 143 return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", name, err) 144 } 145 146 return resourecArmLoadBalancerRead(d, meta) 147 } 148 149 func resourecArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) error { 150 loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta) 151 if err != nil { 152 return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err) 153 } 154 if !exists { 155 d.SetId("") 156 log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string)) 157 return nil 158 } 159 160 if loadBalancer.LoadBalancerPropertiesFormat != nil && loadBalancer.LoadBalancerPropertiesFormat.FrontendIPConfigurations != nil { 161 d.Set("frontend_ip_configuration", flattenLoadBalancerFrontendIpConfiguration(loadBalancer.LoadBalancerPropertiesFormat.FrontendIPConfigurations)) 162 } 163 164 flattenAndSetTags(d, loadBalancer.Tags) 165 166 return nil 167 } 168 169 func resourceArmLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error { 170 loadBalancerClient := meta.(*ArmClient).loadBalancerClient 171 172 id, err := parseAzureResourceID(d.Id()) 173 if err != nil { 174 return errwrap.Wrapf("Error Parsing Azure Resource ID {{err}}", err) 175 } 176 resGroup := id.ResourceGroup 177 name := id.Path["loadBalancers"] 178 179 _, err = loadBalancerClient.Delete(resGroup, name, make(chan struct{})) 180 if err != nil { 181 return errwrap.Wrapf("Error Deleting LoadBalancer {{err}}", err) 182 } 183 184 d.SetId("") 185 return nil 186 } 187 188 func expandAzureRmLoadBalancerFrontendIpConfigurations(d *schema.ResourceData) *[]network.FrontendIPConfiguration { 189 configs := d.Get("frontend_ip_configuration").([]interface{}) 190 frontEndConfigs := make([]network.FrontendIPConfiguration, 0, len(configs)) 191 192 for _, configRaw := range configs { 193 data := configRaw.(map[string]interface{}) 194 195 private_ip_allocation_method := data["private_ip_address_allocation"].(string) 196 properties := network.FrontendIPConfigurationPropertiesFormat{ 197 PrivateIPAllocationMethod: network.IPAllocationMethod(private_ip_allocation_method), 198 } 199 200 if v := data["private_ip_address"].(string); v != "" { 201 properties.PrivateIPAddress = &v 202 } 203 204 if v := data["public_ip_address_id"].(string); v != "" { 205 properties.PublicIPAddress = &network.PublicIPAddress{ 206 ID: &v, 207 } 208 } 209 210 if v := data["subnet_id"].(string); v != "" { 211 properties.Subnet = &network.Subnet{ 212 ID: &v, 213 } 214 } 215 216 name := data["name"].(string) 217 frontEndConfig := network.FrontendIPConfiguration{ 218 Name: &name, 219 FrontendIPConfigurationPropertiesFormat: &properties, 220 } 221 222 frontEndConfigs = append(frontEndConfigs, frontEndConfig) 223 } 224 225 return &frontEndConfigs 226 } 227 228 func flattenLoadBalancerFrontendIpConfiguration(ipConfigs *[]network.FrontendIPConfiguration) []interface{} { 229 result := make([]interface{}, 0, len(*ipConfigs)) 230 for _, config := range *ipConfigs { 231 ipConfig := make(map[string]interface{}) 232 ipConfig["name"] = *config.Name 233 ipConfig["private_ip_address_allocation"] = config.FrontendIPConfigurationPropertiesFormat.PrivateIPAllocationMethod 234 235 if config.FrontendIPConfigurationPropertiesFormat.Subnet != nil { 236 ipConfig["subnet_id"] = *config.FrontendIPConfigurationPropertiesFormat.Subnet.ID 237 } 238 239 if config.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress != nil { 240 ipConfig["private_ip_address"] = *config.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress 241 } 242 243 if config.FrontendIPConfigurationPropertiesFormat.PublicIPAddress != nil { 244 ipConfig["public_ip_address_id"] = *config.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.ID 245 } 246 247 if config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules != nil { 248 load_balancing_rules := make([]string, 0, len(*config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules)) 249 for _, rule := range *config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules { 250 load_balancing_rules = append(load_balancing_rules, *rule.ID) 251 } 252 253 ipConfig["load_balancer_rules"] = load_balancing_rules 254 255 } 256 257 if config.FrontendIPConfigurationPropertiesFormat.InboundNatRules != nil { 258 inbound_nat_rules := make([]string, 0, len(*config.FrontendIPConfigurationPropertiesFormat.InboundNatRules)) 259 for _, rule := range *config.FrontendIPConfigurationPropertiesFormat.InboundNatRules { 260 inbound_nat_rules = append(inbound_nat_rules, *rule.ID) 261 } 262 263 ipConfig["inbound_nat_rules"] = inbound_nat_rules 264 265 } 266 267 result = append(result, ipConfig) 268 } 269 return result 270 }