github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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  		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  			"location": locationSchema(),
    33  
    34  			"resource_group_name": {
    35  				Type:     schema.TypeString,
    36  				Required: true,
    37  				ForceNew: true,
    38  			},
    39  
    40  			"frontend_ip_configuration": {
    41  				Type:     schema.TypeList,
    42  				Optional: true,
    43  				MinItems: 1,
    44  				Elem: &schema.Resource{
    45  					Schema: map[string]*schema.Schema{
    46  						"name": {
    47  							Type:     schema.TypeString,
    48  							Required: true,
    49  						},
    50  
    51  						"subnet_id": {
    52  							Type:     schema.TypeString,
    53  							Optional: true,
    54  							Computed: true,
    55  						},
    56  
    57  						"private_ip_address": {
    58  							Type:     schema.TypeString,
    59  							Optional: true,
    60  							Computed: true,
    61  						},
    62  
    63  						"public_ip_address_id": {
    64  							Type:     schema.TypeString,
    65  							Optional: true,
    66  							Computed: true,
    67  						},
    68  
    69  						"private_ip_address_allocation": {
    70  							Type:             schema.TypeString,
    71  							Optional:         true,
    72  							Computed:         true,
    73  							ValidateFunc:     validateLoadBalancerPrivateIpAddressAllocation,
    74  							StateFunc:        ignoreCaseStateFunc,
    75  							DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
    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  		LoadBalancerPropertiesFormat: &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  	id, err := parseAzureResourceID(d.Id())
   156  	if err != nil {
   157  		return err
   158  	}
   159  
   160  	loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
   161  	if err != nil {
   162  		return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
   163  	}
   164  	if !exists {
   165  		d.SetId("")
   166  		log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
   167  		return nil
   168  	}
   169  
   170  	d.Set("name", loadBalancer.Name)
   171  	d.Set("location", loadBalancer.Location)
   172  	d.Set("resource_group_name", id.ResourceGroup)
   173  
   174  	if loadBalancer.LoadBalancerPropertiesFormat != nil && loadBalancer.LoadBalancerPropertiesFormat.FrontendIPConfigurations != nil {
   175  		d.Set("frontend_ip_configuration", flattenLoadBalancerFrontendIpConfiguration(loadBalancer.LoadBalancerPropertiesFormat.FrontendIPConfigurations))
   176  	}
   177  
   178  	flattenAndSetTags(d, loadBalancer.Tags)
   179  
   180  	return nil
   181  }
   182  
   183  func resourceArmLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error {
   184  	loadBalancerClient := meta.(*ArmClient).loadBalancerClient
   185  
   186  	id, err := parseAzureResourceID(d.Id())
   187  	if err != nil {
   188  		return errwrap.Wrapf("Error Parsing Azure Resource ID {{err}}", err)
   189  	}
   190  	resGroup := id.ResourceGroup
   191  	name := id.Path["loadBalancers"]
   192  
   193  	_, err = loadBalancerClient.Delete(resGroup, name, make(chan struct{}))
   194  	if err != nil {
   195  		return errwrap.Wrapf("Error Deleting LoadBalancer {{err}}", err)
   196  	}
   197  
   198  	d.SetId("")
   199  	return nil
   200  }
   201  
   202  func expandAzureRmLoadBalancerFrontendIpConfigurations(d *schema.ResourceData) *[]network.FrontendIPConfiguration {
   203  	configs := d.Get("frontend_ip_configuration").([]interface{})
   204  	frontEndConfigs := make([]network.FrontendIPConfiguration, 0, len(configs))
   205  
   206  	for _, configRaw := range configs {
   207  		data := configRaw.(map[string]interface{})
   208  
   209  		private_ip_allocation_method := data["private_ip_address_allocation"].(string)
   210  		properties := network.FrontendIPConfigurationPropertiesFormat{
   211  			PrivateIPAllocationMethod: network.IPAllocationMethod(private_ip_allocation_method),
   212  		}
   213  
   214  		if v := data["private_ip_address"].(string); v != "" {
   215  			properties.PrivateIPAddress = &v
   216  		}
   217  
   218  		if v := data["public_ip_address_id"].(string); v != "" {
   219  			properties.PublicIPAddress = &network.PublicIPAddress{
   220  				ID: &v,
   221  			}
   222  		}
   223  
   224  		if v := data["subnet_id"].(string); v != "" {
   225  			properties.Subnet = &network.Subnet{
   226  				ID: &v,
   227  			}
   228  		}
   229  
   230  		name := data["name"].(string)
   231  		frontEndConfig := network.FrontendIPConfiguration{
   232  			Name: &name,
   233  			FrontendIPConfigurationPropertiesFormat: &properties,
   234  		}
   235  
   236  		frontEndConfigs = append(frontEndConfigs, frontEndConfig)
   237  	}
   238  
   239  	return &frontEndConfigs
   240  }
   241  
   242  func flattenLoadBalancerFrontendIpConfiguration(ipConfigs *[]network.FrontendIPConfiguration) []interface{} {
   243  	result := make([]interface{}, 0, len(*ipConfigs))
   244  	for _, config := range *ipConfigs {
   245  		ipConfig := make(map[string]interface{})
   246  		ipConfig["name"] = *config.Name
   247  		ipConfig["private_ip_address_allocation"] = config.FrontendIPConfigurationPropertiesFormat.PrivateIPAllocationMethod
   248  
   249  		if config.FrontendIPConfigurationPropertiesFormat.Subnet != nil {
   250  			ipConfig["subnet_id"] = *config.FrontendIPConfigurationPropertiesFormat.Subnet.ID
   251  		}
   252  
   253  		if config.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress != nil {
   254  			ipConfig["private_ip_address"] = *config.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress
   255  		}
   256  
   257  		if config.FrontendIPConfigurationPropertiesFormat.PublicIPAddress != nil {
   258  			ipConfig["public_ip_address_id"] = *config.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.ID
   259  		}
   260  
   261  		if config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules != nil {
   262  			load_balancing_rules := make([]string, 0, len(*config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules))
   263  			for _, rule := range *config.FrontendIPConfigurationPropertiesFormat.LoadBalancingRules {
   264  				load_balancing_rules = append(load_balancing_rules, *rule.ID)
   265  			}
   266  
   267  			ipConfig["load_balancer_rules"] = load_balancing_rules
   268  
   269  		}
   270  
   271  		if config.FrontendIPConfigurationPropertiesFormat.InboundNatRules != nil {
   272  			inbound_nat_rules := make([]string, 0, len(*config.FrontendIPConfigurationPropertiesFormat.InboundNatRules))
   273  			for _, rule := range *config.FrontendIPConfigurationPropertiesFormat.InboundNatRules {
   274  				inbound_nat_rules = append(inbound_nat_rules, *rule.ID)
   275  			}
   276  
   277  			ipConfig["inbound_nat_rules"] = inbound_nat_rules
   278  
   279  		}
   280  
   281  		result = append(result, ipConfig)
   282  	}
   283  	return result
   284  }