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