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  }