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  }