provider/azurerm: Add Load Balancer resources (#9199)
* provider/azurerm: Add AzureRM Loadbalancer resource Adds support for the elusive Azure LoadBalancer * [x] `azurerm_lb` * [x] `azurerm_lb_backend_address_pool` * [x] `azurerm_lb_rule` * [x] `azurerm_lb_nat_rule` * [x] `azurerm_lb_probe` * [x] `azurerm_lb_nat_pool` Test Results: ``` make testacc TEST=./builtin/providers/azurerm TESTARGS='-run=TestAccAzureRMLoadbalancer' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) TF_ACC=1 go test ./builtin/providers/azurerm -v -run=TestAccAzureRMLoadbalancer -timeout 120m === RUN TestAccAzureRMLoadbalancerBackEndAddressPool_basic --- PASS: TestAccAzureRMLoadbalancerBackEndAddressPool_basic (207.26s) === RUN TestAccAzureRMLoadbalancerBackEndAddressPool_removal --- PASS: TestAccAzureRMLoadbalancerBackEndAddressPool_removal (165.89s) === RUN TestAccAzureRMLoadbalancerNatRule_basic --- PASS: TestAccAzureRMLoadbalancerNatRule_basic (179.30s) === RUN TestAccAzureRMLoadbalancerNatRule_removal --- PASS: TestAccAzureRMLoadbalancerNatRule_removal (180.73s) === RUN TestAccAzureRMLoadbalancerRule_basic --- PASS: TestAccAzureRMLoadbalancerRule_basic (170.40s) === RUN TestAccAzureRMLoadbalancerRule_removal --- PASS: TestAccAzureRMLoadbalancerRule_removal (204.23s) === RUN TestAccAzureRMLoadbalancer_basic --- PASS: TestAccAzureRMLoadbalancer_basic (136.03s) === RUN TestAccAzureRMLoadbalancer_frontEndConfig --- PASS: TestAccAzureRMLoadbalancer_frontEndConfig (214.47s) === RUN TestAccAzureRMLoadbalancer_tags --- PASS: TestAccAzureRMLoadbalancer_tags (215.52s) === RUN TestAccAzureRMLoadbalancerProbe_basic --- PASS: TestAccAzureRMLoadbalancerProbe_basic (183.36s) === RUN TestAccAzureRMLoadbalancerProbe_removal --- PASS: TestAccAzureRMLoadbalancerProbe_removal (185.86s) === RUN TestAccAzureRMLoadbalancerNatPool_basic --- PASS: TestAccAzureRMLoadbalancerNatPool_basic (161.47s) === RUN TestAccAzureRMLoadbalancerNatPool_removal --- PASS: TestAccAzureRMLoadbalancerNatPool_removal (167.38s) PASS ok github.com/hashicorp/terraform/builtin/providers/azurerm 1673.852s ``` * provider/azurerm: Documentation for the ARM LB resources
This commit is contained in:
parent
42c2fe5c85
commit
a085c8d71e
|
@ -0,0 +1,144 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func resourceGroupAndLBNameFromId(loadBalancerId string) (string, string, error) {
|
||||
id, err := parseAzureResourceID(loadBalancerId)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
name := id.Path["loadBalancers"]
|
||||
resGroup := id.ResourceGroup
|
||||
|
||||
return resGroup, name, nil
|
||||
}
|
||||
|
||||
func retrieveLoadBalancerById(loadBalancerId string, meta interface{}) (*network.LoadBalancer, bool, error) {
|
||||
loadBalancerClient := meta.(*ArmClient).loadBalancerClient
|
||||
|
||||
resGroup, name, err := resourceGroupAndLBNameFromId(loadBalancerId)
|
||||
if err != nil {
|
||||
return nil, false, errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
resp, err := loadBalancerClient.Get(resGroup, name, "")
|
||||
if err != nil {
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, fmt.Errorf("Error making Read request on Azure LoadBalancer %s: %s", name, err)
|
||||
}
|
||||
|
||||
return &resp, true, nil
|
||||
}
|
||||
|
||||
func findLoadBalancerBackEndAddressPoolByName(lb *network.LoadBalancer, name string) (*network.BackendAddressPool, int, bool) {
|
||||
if lb == nil || lb.Properties == nil || lb.Properties.BackendAddressPools == nil {
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
for i, apc := range *lb.Properties.BackendAddressPools {
|
||||
if apc.Name != nil && *apc.Name == name {
|
||||
return &apc, i, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
func findLoadBalancerFrontEndIpConfigurationByName(lb *network.LoadBalancer, name string) (*network.FrontendIPConfiguration, int, bool) {
|
||||
if lb == nil || lb.Properties == nil || lb.Properties.FrontendIPConfigurations == nil {
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
for i, feip := range *lb.Properties.FrontendIPConfigurations {
|
||||
if feip.Name != nil && *feip.Name == name {
|
||||
return &feip, i, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
func findLoadBalancerRuleByName(lb *network.LoadBalancer, name string) (*network.LoadBalancingRule, int, bool) {
|
||||
if lb == nil || lb.Properties == nil || lb.Properties.LoadBalancingRules == nil {
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
for i, lbr := range *lb.Properties.LoadBalancingRules {
|
||||
if lbr.Name != nil && *lbr.Name == name {
|
||||
return &lbr, i, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
func findLoadBalancerNatRuleByName(lb *network.LoadBalancer, name string) (*network.InboundNatRule, int, bool) {
|
||||
if lb == nil || lb.Properties == nil || lb.Properties.InboundNatRules == nil {
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
for i, nr := range *lb.Properties.InboundNatRules {
|
||||
if nr.Name != nil && *nr.Name == name {
|
||||
return &nr, i, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
func findLoadBalancerNatPoolByName(lb *network.LoadBalancer, name string) (*network.InboundNatPool, int, bool) {
|
||||
if lb == nil || lb.Properties == nil || lb.Properties.InboundNatPools == nil {
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
for i, np := range *lb.Properties.InboundNatPools {
|
||||
if np.Name != nil && *np.Name == name {
|
||||
return &np, i, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
func findLoadBalancerProbeByName(lb *network.LoadBalancer, name string) (*network.Probe, int, bool) {
|
||||
if lb == nil || lb.Properties == nil || lb.Properties.Probes == nil {
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
for i, p := range *lb.Properties.Probes {
|
||||
if p.Name != nil && *p.Name == name {
|
||||
return &p, i, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1, false
|
||||
}
|
||||
|
||||
func loadbalancerStateRefreshFunc(client *ArmClient, resourceGroupName string, loadbalancer string) resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
res, err := client.loadBalancerClient.Get(resourceGroupName, loadbalancer, "")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("Error issuing read request in loadbalancerStateRefreshFunc to Azure ARM for LoadBalancer '%s' (RG: '%s'): %s", loadbalancer, resourceGroupName, err)
|
||||
}
|
||||
|
||||
return res, *res.Properties.ProvisioningState, nil
|
||||
}
|
||||
}
|
||||
|
||||
func validateLoadBalancerPrivateIpAddressAllocation(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := strings.ToLower(v.(string))
|
||||
if value != "static" && value != "dynamic" {
|
||||
errors = append(errors, fmt.Errorf("LoadBalancer Allocations can only be Static or Dynamic"))
|
||||
}
|
||||
return
|
||||
}
|
|
@ -46,9 +46,17 @@ func Provider() terraform.ResourceProvider {
|
|||
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
// These resources use the Azure ARM SDK
|
||||
"azurerm_availability_set": resourceArmAvailabilitySet(),
|
||||
"azurerm_cdn_endpoint": resourceArmCdnEndpoint(),
|
||||
"azurerm_cdn_profile": resourceArmCdnProfile(),
|
||||
"azurerm_availability_set": resourceArmAvailabilitySet(),
|
||||
"azurerm_cdn_endpoint": resourceArmCdnEndpoint(),
|
||||
"azurerm_cdn_profile": resourceArmCdnProfile(),
|
||||
|
||||
"azurerm_lb": resourceArmLoadBalancer(),
|
||||
"azurerm_lb_backend_address_pool": resourceArmLoadBalancerBackendAddressPool(),
|
||||
"azurerm_lb_nat_rule": resourceArmLoadBalancerNatRule(),
|
||||
"azurerm_lb_nat_pool": resourceArmLoadBalancerNatPool(),
|
||||
"azurerm_lb_probe": resourceArmLoadBalancerProbe(),
|
||||
"azurerm_lb_rule": resourceArmLoadBalancerRule(),
|
||||
|
||||
"azurerm_local_network_gateway": resourceArmLocalNetworkGateway(),
|
||||
"azurerm_network_interface": resourceArmNetworkInterface(),
|
||||
"azurerm_network_security_group": resourceArmNetworkSecurityGroup(),
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/jen20/riviera/azure"
|
||||
)
|
||||
|
||||
func resourceArmLoadBalancer() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceArmLoadBalancerCreate,
|
||||
Read: resourecArmLoadBalancerRead,
|
||||
Update: resourceArmLoadBalancerCreate,
|
||||
Delete: resourceArmLoadBalancerDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: azureRMNormalizeLocation,
|
||||
},
|
||||
|
||||
"resource_group_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MinItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"subnet_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"private_ip_address": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"public_ip_address_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"private_ip_address_allocation": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateFunc: validateLoadBalancerPrivateIpAddressAllocation,
|
||||
},
|
||||
|
||||
"load_balancer_rules": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
|
||||
"inbound_nat_rules": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"tags": tagsSchema(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
loadBalancerClient := client.loadBalancerClient
|
||||
|
||||
log.Printf("[INFO] preparing arguments for Azure ARM LoadBalancer creation.")
|
||||
|
||||
name := d.Get("name").(string)
|
||||
location := d.Get("location").(string)
|
||||
resGroup := d.Get("resource_group_name").(string)
|
||||
tags := d.Get("tags").(map[string]interface{})
|
||||
expandedTags := expandTags(tags)
|
||||
|
||||
properties := network.LoadBalancerPropertiesFormat{}
|
||||
|
||||
if _, ok := d.GetOk("frontend_ip_configuration"); ok {
|
||||
properties.FrontendIPConfigurations = expandAzureRmLoadBalancerFrontendIpConfigurations(d)
|
||||
}
|
||||
|
||||
loadbalancer := network.LoadBalancer{
|
||||
Name: azure.String(name),
|
||||
Location: azure.String(location),
|
||||
Tags: expandedTags,
|
||||
Properties: &properties,
|
||||
}
|
||||
|
||||
_, err := loadBalancerClient.CreateOrUpdate(resGroup, name, loadbalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := loadBalancerClient.Get(resGroup, name, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", name, resGroup)
|
||||
}
|
||||
|
||||
d.SetId(*read.ID)
|
||||
|
||||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", name)
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: []string{"Accepted", "Updating"},
|
||||
Target: []string{"Succeeded"},
|
||||
Refresh: loadbalancerStateRefreshFunc(client, resGroup, name),
|
||||
Timeout: 10 * time.Minute,
|
||||
}
|
||||
if _, err := stateConf.WaitForState(); err != nil {
|
||||
return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", name, err)
|
||||
}
|
||||
|
||||
return resourecArmLoadBalancerRead(d, meta)
|
||||
}
|
||||
|
||||
func resourecArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
if loadBalancer.Properties != nil && loadBalancer.Properties.FrontendIPConfigurations != nil {
|
||||
d.Set("frontend_ip_configuration", flattenLoadBalancerFrontendIpConfiguration(loadBalancer.Properties.FrontendIPConfigurations))
|
||||
}
|
||||
|
||||
flattenAndSetTags(d, loadBalancer.Tags)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancerClient := meta.(*ArmClient).loadBalancerClient
|
||||
|
||||
id, err := parseAzureResourceID(d.Id())
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Parsing Azure Resource ID {{err}}", err)
|
||||
}
|
||||
resGroup := id.ResourceGroup
|
||||
name := id.Path["loadBalancers"]
|
||||
|
||||
_, err = loadBalancerClient.Delete(resGroup, name, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Deleting LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAzureRmLoadBalancerFrontendIpConfigurations(d *schema.ResourceData) *[]network.FrontendIPConfiguration {
|
||||
configs := d.Get("frontend_ip_configuration").([]interface{})
|
||||
frontEndConfigs := make([]network.FrontendIPConfiguration, 0, len(configs))
|
||||
|
||||
for _, configRaw := range configs {
|
||||
data := configRaw.(map[string]interface{})
|
||||
|
||||
private_ip_allocation_method := data["private_ip_address_allocation"].(string)
|
||||
properties := network.FrontendIPConfigurationPropertiesFormat{
|
||||
PrivateIPAllocationMethod: network.IPAllocationMethod(private_ip_allocation_method),
|
||||
}
|
||||
|
||||
if v := data["private_ip_address"].(string); v != "" {
|
||||
properties.PrivateIPAddress = &v
|
||||
}
|
||||
|
||||
if v := data["public_ip_address_id"].(string); v != "" {
|
||||
properties.PublicIPAddress = &network.PublicIPAddress{
|
||||
ID: &v,
|
||||
}
|
||||
}
|
||||
|
||||
if v := data["subnet_id"].(string); v != "" {
|
||||
properties.Subnet = &network.Subnet{
|
||||
ID: &v,
|
||||
}
|
||||
}
|
||||
|
||||
name := data["name"].(string)
|
||||
frontEndConfig := network.FrontendIPConfiguration{
|
||||
Name: &name,
|
||||
Properties: &properties,
|
||||
}
|
||||
|
||||
frontEndConfigs = append(frontEndConfigs, frontEndConfig)
|
||||
}
|
||||
|
||||
return &frontEndConfigs
|
||||
}
|
||||
|
||||
func flattenLoadBalancerFrontendIpConfiguration(ipConfigs *[]network.FrontendIPConfiguration) []interface{} {
|
||||
result := make([]interface{}, 0, len(*ipConfigs))
|
||||
for _, config := range *ipConfigs {
|
||||
ipConfig := make(map[string]interface{})
|
||||
ipConfig["name"] = *config.Name
|
||||
ipConfig["private_ip_address_allocation"] = config.Properties.PrivateIPAllocationMethod
|
||||
|
||||
if config.Properties.Subnet != nil {
|
||||
ipConfig["subnet_id"] = *config.Properties.Subnet.ID
|
||||
}
|
||||
|
||||
if config.Properties.PrivateIPAddress != nil {
|
||||
ipConfig["private_ip_address"] = *config.Properties.PrivateIPAddress
|
||||
}
|
||||
|
||||
if config.Properties.PublicIPAddress != nil {
|
||||
ipConfig["public_ip_address_id"] = *config.Properties.PublicIPAddress.ID
|
||||
}
|
||||
|
||||
if config.Properties.LoadBalancingRules != nil {
|
||||
load_balancing_rules := make([]string, 0, len(*config.Properties.LoadBalancingRules))
|
||||
for _, rule := range *config.Properties.LoadBalancingRules {
|
||||
load_balancing_rules = append(load_balancing_rules, *rule.ID)
|
||||
}
|
||||
|
||||
ipConfig["load_balancer_rules"] = load_balancing_rules
|
||||
|
||||
}
|
||||
|
||||
if config.Properties.InboundNatRules != nil {
|
||||
inbound_nat_rules := make([]string, 0, len(*config.Properties.InboundNatRules))
|
||||
for _, rule := range *config.Properties.InboundNatRules {
|
||||
inbound_nat_rules = append(inbound_nat_rules, *rule.ID)
|
||||
}
|
||||
|
||||
ipConfig["inbound_nat_rules"] = inbound_nat_rules
|
||||
|
||||
}
|
||||
|
||||
result = append(result, ipConfig)
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/jen20/riviera/azure"
|
||||
)
|
||||
|
||||
func resourceArmLoadBalancerBackendAddressPool() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceArmLoadBalancerBackendAddressPoolCreate,
|
||||
Read: resourceArmLoadBalancerBackendAddressPoolRead,
|
||||
Delete: resourceArmLoadBalancerBackendAddressPoolDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: azureRMNormalizeLocation,
|
||||
},
|
||||
|
||||
"resource_group_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"loadbalancer_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"backend_ip_configurations": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
|
||||
"load_balancing_rules": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerBackendAddressPoolCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, _, exists = findLoadBalancerBackEndAddressPoolByName(loadBalancer, d.Get("name").(string))
|
||||
if exists {
|
||||
return fmt.Errorf("A BackEnd Address Pool with name %q already exists.", d.Get("name").(string))
|
||||
}
|
||||
|
||||
backendAddressPools := append(*loadBalancer.Properties.BackendAddressPools, expandAzureRmLoadBalancerBackendAddressPools(d))
|
||||
loadBalancer.Properties.BackendAddressPools = &backendAddressPools
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
d.SetId(*read.ID)
|
||||
|
||||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName)
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: []string{"Accepted", "Updating"},
|
||||
Target: []string{"Succeeded"},
|
||||
Refresh: loadbalancerStateRefreshFunc(client, resGroup, loadBalancerName),
|
||||
Timeout: 10 * time.Minute,
|
||||
}
|
||||
if _, err := stateConf.WaitForState(); err != nil {
|
||||
return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", loadBalancerName, err)
|
||||
}
|
||||
|
||||
return resourceArmLoadBalancerBackendAddressPoolRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerBackendAddressPoolRead(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
configs := *loadBalancer.Properties.BackendAddressPools
|
||||
for _, config := range configs {
|
||||
if *config.Name == d.Get("name").(string) {
|
||||
d.Set("name", config.Name)
|
||||
|
||||
if config.Properties.BackendIPConfigurations != nil {
|
||||
backend_ip_configurations := make([]string, 0, len(*config.Properties.BackendIPConfigurations))
|
||||
for _, backendConfig := range *config.Properties.BackendIPConfigurations {
|
||||
backend_ip_configurations = append(backend_ip_configurations, *backendConfig.ID)
|
||||
}
|
||||
|
||||
d.Set("backend_ip_configurations", backend_ip_configurations)
|
||||
}
|
||||
|
||||
if config.Properties.LoadBalancingRules != nil {
|
||||
load_balancing_rules := make([]string, 0, len(*config.Properties.LoadBalancingRules))
|
||||
for _, rule := range *config.Properties.LoadBalancingRules {
|
||||
load_balancing_rules = append(load_balancing_rules, *rule.ID)
|
||||
}
|
||||
|
||||
d.Set("backend_ip_configurations", load_balancing_rules)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerBackendAddressPoolDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
_, index, exists := findLoadBalancerBackEndAddressPoolByName(loadBalancer, d.Get("name").(string))
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldBackEndPools := *loadBalancer.Properties.BackendAddressPools
|
||||
newBackEndPools := append(oldBackEndPools[:index], oldBackEndPools[index+1:]...)
|
||||
loadBalancer.Properties.BackendAddressPools = &newBackEndPools
|
||||
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAzureRmLoadBalancerBackendAddressPools(d *schema.ResourceData) network.BackendAddressPool {
|
||||
return network.BackendAddressPool{
|
||||
Name: azure.String(d.Get("name").(string)),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAzureRMLoadBalancerBackEndAddressPool_basic(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
addressPoolName := fmt.Sprintf("%d-address-pool", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerBackEndAddressPool_basic(ri, addressPoolName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerBackEndAddressPoolExists(addressPoolName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancerBackEndAddressPool_removal(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
addressPoolName := fmt.Sprintf("%d-address-pool", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerBackEndAddressPool_removal(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerBackEndAddressPoolNotExists(addressPoolName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerBackEndAddressPoolExists(addressPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerBackEndAddressPoolByName(lb, addressPoolName)
|
||||
if !exists {
|
||||
return fmt.Errorf("A BackEnd Address Pool with name %q cannot be found.", addressPoolName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerBackEndAddressPoolNotExists(addressPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerBackEndAddressPoolByName(lb, addressPoolName)
|
||||
if exists {
|
||||
return fmt.Errorf("A BackEnd Address Pool with name %q has been found.", addressPoolName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerBackEndAddressPool_basic(rInt int, addressPoolName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_backend_address_pool" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "%s"
|
||||
}
|
||||
|
||||
`, rInt, rInt, rInt, rInt, addressPoolName)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerBackEndAddressPool_removal(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
`, rInt, rInt, rInt, rInt)
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/jen20/riviera/azure"
|
||||
)
|
||||
|
||||
func resourceArmLoadBalancerNatPool() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceArmLoadBalancerNatPoolCreate,
|
||||
Read: resourceArmLoadBalancerNatPoolRead,
|
||||
Update: resourceArmLoadBalancerNatPoolCreate,
|
||||
Delete: resourceArmLoadBalancerNatPoolDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: azureRMNormalizeLocation,
|
||||
},
|
||||
|
||||
"resource_group_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"loadbalancer_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"protocol": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_port_start": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_port_end": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"backend_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerNatPoolCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, _, exists = findLoadBalancerNatPoolByName(loadBalancer, d.Get("name").(string))
|
||||
if exists {
|
||||
return fmt.Errorf("A NAT Pool with name %q already exists.", d.Get("name").(string))
|
||||
}
|
||||
|
||||
newNatPool, err := expandAzureRmLoadBalancerNatPool(d, loadBalancer)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Expanding NAT Pool {{err}}", err)
|
||||
}
|
||||
|
||||
natPools := append(*loadBalancer.Properties.InboundNatPools, *newNatPool)
|
||||
loadBalancer.Properties.InboundNatPools = &natPools
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
d.SetId(*read.ID)
|
||||
|
||||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName)
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: []string{"Accepted", "Updating"},
|
||||
Target: []string{"Succeeded"},
|
||||
Refresh: loadbalancerStateRefreshFunc(client, resGroup, loadBalancerName),
|
||||
Timeout: 10 * time.Minute,
|
||||
}
|
||||
if _, err := stateConf.WaitForState(); err != nil {
|
||||
return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", loadBalancerName, err)
|
||||
}
|
||||
|
||||
return resourceArmLoadBalancerNatPoolRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerNatPoolRead(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
configs := *loadBalancer.Properties.InboundNatPools
|
||||
for _, config := range configs {
|
||||
if *config.Name == d.Get("name").(string) {
|
||||
d.Set("name", config.Name)
|
||||
|
||||
d.Set("protocol", config.Properties.Protocol)
|
||||
d.Set("frontend_port_start", config.Properties.FrontendPortRangeStart)
|
||||
d.Set("frontend_port_end", config.Properties.FrontendPortRangeEnd)
|
||||
d.Set("backend_port", config.Properties.BackendPort)
|
||||
|
||||
if config.Properties.FrontendIPConfiguration != nil {
|
||||
d.Set("frontend_ip_configuration_id", config.Properties.FrontendIPConfiguration.ID)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerNatPoolDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
_, index, exists := findLoadBalancerNatPoolByName(loadBalancer, d.Get("name").(string))
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldNatPools := *loadBalancer.Properties.InboundNatPools
|
||||
newNatPools := append(oldNatPools[:index], oldNatPools[index+1:]...)
|
||||
loadBalancer.Properties.InboundNatPools = &newNatPools
|
||||
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAzureRmLoadBalancerNatPool(d *schema.ResourceData, lb *network.LoadBalancer) (*network.InboundNatPool, error) {
|
||||
|
||||
properties := network.InboundNatPoolPropertiesFormat{
|
||||
Protocol: network.TransportProtocol(d.Get("protocol").(string)),
|
||||
FrontendPortRangeStart: azure.Int32(int32(d.Get("frontend_port_start").(int))),
|
||||
FrontendPortRangeEnd: azure.Int32(int32(d.Get("frontend_port_end").(int))),
|
||||
BackendPort: azure.Int32(int32(d.Get("backend_port").(int))),
|
||||
}
|
||||
|
||||
if v := d.Get("frontend_ip_configuration_name").(string); v != "" {
|
||||
rule, _, exists := findLoadBalancerFrontEndIpConfigurationByName(lb, v)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("[ERROR] Cannot find FrontEnd IP Configuration with the name %s", v)
|
||||
}
|
||||
|
||||
feip := network.SubResource{
|
||||
ID: rule.ID,
|
||||
}
|
||||
|
||||
properties.FrontendIPConfiguration = &feip
|
||||
}
|
||||
|
||||
natPool := network.InboundNatPool{
|
||||
Name: azure.String(d.Get("name").(string)),
|
||||
Properties: &properties,
|
||||
}
|
||||
|
||||
return &natPool, nil
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAzureRMLoadBalancerNatPool_basic(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
natPoolName := fmt.Sprintf("NatPool-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerNatPool_basic(ri, natPoolName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerNatPoolExists(natPoolName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancerNatPool_removal(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
natPoolName := fmt.Sprintf("NatPool-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerNatPool_basic(ri, natPoolName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerNatPoolExists(natPoolName, &lb),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerNatPool_removal(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerNatPoolNotExists(natPoolName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerNatPoolExists(natPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerNatPoolByName(lb, natPoolName)
|
||||
if !exists {
|
||||
return fmt.Errorf("A NAT Pool with name %q cannot be found.", natPoolName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerNatPoolNotExists(natPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerNatPoolByName(lb, natPoolName)
|
||||
if exists {
|
||||
return fmt.Errorf("A NAT Pool with name %q has been found.", natPoolName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerNatPool_basic(rInt int, natPoolName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_nat_pool" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "%s"
|
||||
protocol = "Tcp"
|
||||
frontend_port_start = 80
|
||||
frontend_port_end = 81
|
||||
backend_port = 3389
|
||||
frontend_ip_configuration_name = "one-%d"
|
||||
}
|
||||
|
||||
`, rInt, rInt, rInt, rInt, natPoolName, rInt)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerNatPool_removal(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
`, rInt, rInt, rInt, rInt)
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/jen20/riviera/azure"
|
||||
)
|
||||
|
||||
func resourceArmLoadBalancerNatRule() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceArmLoadBalancerNatRuleCreate,
|
||||
Read: resourceArmLoadBalancerNatRuleRead,
|
||||
Update: resourceArmLoadBalancerNatRuleCreate,
|
||||
Delete: resourceArmLoadBalancerNatRuleDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: azureRMNormalizeLocation,
|
||||
},
|
||||
|
||||
"resource_group_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"loadbalancer_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"protocol": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"backend_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"backend_ip_configuration_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerNatRuleCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, _, exists = findLoadBalancerNatRuleByName(loadBalancer, d.Get("name").(string))
|
||||
if exists {
|
||||
return fmt.Errorf("A NAT Rule with name %q already exists.", d.Get("name").(string))
|
||||
}
|
||||
|
||||
newNatRule, err := expandAzureRmLoadBalancerNatRule(d, loadBalancer)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Expanding NAT Rule {{err}}", err)
|
||||
}
|
||||
|
||||
natRules := append(*loadBalancer.Properties.InboundNatRules, *newNatRule)
|
||||
loadBalancer.Properties.InboundNatRules = &natRules
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating / Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
d.SetId(*read.ID)
|
||||
|
||||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName)
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: []string{"Accepted", "Updating"},
|
||||
Target: []string{"Succeeded"},
|
||||
Refresh: loadbalancerStateRefreshFunc(client, resGroup, loadBalancerName),
|
||||
Timeout: 10 * time.Minute,
|
||||
}
|
||||
if _, err := stateConf.WaitForState(); err != nil {
|
||||
return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", loadBalancerName, err)
|
||||
}
|
||||
|
||||
return resourceArmLoadBalancerNatRuleRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerNatRuleRead(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
configs := *loadBalancer.Properties.InboundNatRules
|
||||
for _, config := range configs {
|
||||
if *config.Name == d.Get("name").(string) {
|
||||
d.Set("name", config.Name)
|
||||
|
||||
d.Set("protocol", config.Properties.Protocol)
|
||||
d.Set("frontend_port", config.Properties.FrontendPort)
|
||||
d.Set("backend_port", config.Properties.BackendPort)
|
||||
|
||||
if config.Properties.FrontendIPConfiguration != nil {
|
||||
d.Set("frontend_ip_configuration_id", config.Properties.FrontendIPConfiguration.ID)
|
||||
}
|
||||
|
||||
if config.Properties.BackendIPConfiguration != nil {
|
||||
d.Set("backend_ip_configuration_id", config.Properties.BackendIPConfiguration.ID)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerNatRuleDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
_, index, exists := findLoadBalancerNatRuleByName(loadBalancer, d.Get("name").(string))
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldNatRules := *loadBalancer.Properties.InboundNatRules
|
||||
newNatRules := append(oldNatRules[:index], oldNatRules[index+1:]...)
|
||||
loadBalancer.Properties.InboundNatRules = &newNatRules
|
||||
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAzureRmLoadBalancerNatRule(d *schema.ResourceData, lb *network.LoadBalancer) (*network.InboundNatRule, error) {
|
||||
|
||||
properties := network.InboundNatRulePropertiesFormat{
|
||||
Protocol: network.TransportProtocol(d.Get("protocol").(string)),
|
||||
FrontendPort: azure.Int32(int32(d.Get("frontend_port").(int))),
|
||||
BackendPort: azure.Int32(int32(d.Get("backend_port").(int))),
|
||||
}
|
||||
|
||||
if v := d.Get("frontend_ip_configuration_name").(string); v != "" {
|
||||
rule, _, exists := findLoadBalancerFrontEndIpConfigurationByName(lb, v)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("[ERROR] Cannot find FrontEnd IP Configuration with the name %s", v)
|
||||
}
|
||||
|
||||
feip := network.SubResource{
|
||||
ID: rule.ID,
|
||||
}
|
||||
|
||||
properties.FrontendIPConfiguration = &feip
|
||||
}
|
||||
|
||||
natRule := network.InboundNatRule{
|
||||
Name: azure.String(d.Get("name").(string)),
|
||||
Properties: &properties,
|
||||
}
|
||||
|
||||
return &natRule, nil
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAzureRMLoadBalancerNatRule_basic(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
natRuleName := fmt.Sprintf("NatRule-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerNatRule_basic(ri, natRuleName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerNatRuleExists(natRuleName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancerNatRule_removal(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
natRuleName := fmt.Sprintf("NatRule-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerNatRule_basic(ri, natRuleName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerNatRuleExists(natRuleName, &lb),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerNatRule_removal(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerNatRuleNotExists(natRuleName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerNatRuleExists(natRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerNatRuleByName(lb, natRuleName)
|
||||
if !exists {
|
||||
return fmt.Errorf("A NAT Rule with name %q cannot be found.", natRuleName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerNatRuleNotExists(natRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerNatRuleByName(lb, natRuleName)
|
||||
if exists {
|
||||
return fmt.Errorf("A NAT Rule with name %q has been found.", natRuleName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerNatRule_basic(rInt int, natRuleName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_nat_rule" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "%s"
|
||||
protocol = "Tcp"
|
||||
frontend_port = 3389
|
||||
backend_port = 3389
|
||||
frontend_ip_configuration_name = "one-%d"
|
||||
}
|
||||
|
||||
`, rInt, rInt, rInt, rInt, natRuleName, rInt)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerNatRule_removal(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
`, rInt, rInt, rInt, rInt)
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/jen20/riviera/azure"
|
||||
)
|
||||
|
||||
func resourceArmLoadBalancerProbe() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceArmLoadBalancerProbeCreate,
|
||||
Read: resourceArmLoadBalancerProbeRead,
|
||||
Update: resourceArmLoadBalancerProbeCreate,
|
||||
Delete: resourceArmLoadBalancerProbeDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: azureRMNormalizeLocation,
|
||||
},
|
||||
|
||||
"resource_group_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"loadbalancer_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"protocol": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"request_path": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"interval_in_seconds": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 15,
|
||||
},
|
||||
|
||||
"number_of_probes": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 2,
|
||||
},
|
||||
|
||||
"load_balance_rules": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerProbeCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, _, exists = findLoadBalancerProbeByName(loadBalancer, d.Get("name").(string))
|
||||
if exists {
|
||||
return fmt.Errorf("A Probe with name %q already exists.", d.Get("name").(string))
|
||||
}
|
||||
|
||||
newProbe, err := expandAzureRmLoadBalancerProbe(d, loadBalancer)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Expanding Probe {{err}}", err)
|
||||
}
|
||||
|
||||
probes := append(*loadBalancer.Properties.Probes, *newProbe)
|
||||
loadBalancer.Properties.Probes = &probes
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
d.SetId(*read.ID)
|
||||
|
||||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName)
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: []string{"Accepted", "Updating"},
|
||||
Target: []string{"Succeeded"},
|
||||
Refresh: loadbalancerStateRefreshFunc(client, resGroup, loadBalancerName),
|
||||
Timeout: 10 * time.Minute,
|
||||
}
|
||||
if _, err := stateConf.WaitForState(); err != nil {
|
||||
return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", loadBalancerName, err)
|
||||
}
|
||||
|
||||
return resourceArmLoadBalancerProbeRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerProbeRead(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
configs := *loadBalancer.Properties.Probes
|
||||
for _, config := range configs {
|
||||
if *config.Name == d.Get("name").(string) {
|
||||
d.Set("name", config.Name)
|
||||
|
||||
d.Set("protocol", config.Properties.Protocol)
|
||||
d.Set("interval_in_seconds", config.Properties.IntervalInSeconds)
|
||||
d.Set("number_of_probes", config.Properties.NumberOfProbes)
|
||||
d.Set("port", config.Properties.Port)
|
||||
d.Set("request_path", config.Properties.RequestPath)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerProbeDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
_, index, exists := findLoadBalancerProbeByName(loadBalancer, d.Get("name").(string))
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldProbes := *loadBalancer.Properties.Probes
|
||||
newProbes := append(oldProbes[:index], oldProbes[index+1:]...)
|
||||
loadBalancer.Properties.Probes = &newProbes
|
||||
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAzureRmLoadBalancerProbe(d *schema.ResourceData, lb *network.LoadBalancer) (*network.Probe, error) {
|
||||
|
||||
properties := network.ProbePropertiesFormat{
|
||||
NumberOfProbes: azure.Int32(int32(d.Get("number_of_probes").(int))),
|
||||
IntervalInSeconds: azure.Int32(int32(d.Get("interval_in_seconds").(int))),
|
||||
Port: azure.Int32(int32(d.Get("port").(int))),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("protocol"); ok {
|
||||
properties.Protocol = network.ProbeProtocol(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("request_path"); ok {
|
||||
properties.RequestPath = azure.String(v.(string))
|
||||
}
|
||||
|
||||
probe := network.Probe{
|
||||
Name: azure.String(d.Get("name").(string)),
|
||||
Properties: &properties,
|
||||
}
|
||||
|
||||
return &probe, nil
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAzureRMLoadBalancerProbe_basic(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
probeName := fmt.Sprintf("probe-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerProbe_basic(ri, probeName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerProbeExists(probeName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancerProbe_removal(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
probeName := fmt.Sprintf("probe-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerProbe_basic(ri, probeName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerProbeExists(probeName, &lb),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerProbe_removal(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerProbeNotExists(probeName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerProbeExists(natRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerProbeByName(lb, natRuleName)
|
||||
if !exists {
|
||||
return fmt.Errorf("A Probe with name %q cannot be found.", natRuleName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerProbeNotExists(natRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerProbeByName(lb, natRuleName)
|
||||
if exists {
|
||||
return fmt.Errorf("A Probe with name %q has been found.", natRuleName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerProbe_basic(rInt int, probeName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_probe" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "%s"
|
||||
port = 22
|
||||
}
|
||||
`, rInt, rInt, rInt, rInt, probeName)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerProbe_removal(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
`, rInt, rInt, rInt, rInt)
|
||||
}
|
|
@ -0,0 +1,342 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/jen20/riviera/azure"
|
||||
)
|
||||
|
||||
func resourceArmLoadBalancerRule() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceArmLoadBalancerRuleCreate,
|
||||
Read: resourceArmLoadBalancerRuleRead,
|
||||
Update: resourceArmLoadBalancerRuleCreate,
|
||||
Delete: resourceArmLoadBalancerRuleDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validateArmLoadBalancerRuleName,
|
||||
},
|
||||
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: azureRMNormalizeLocation,
|
||||
},
|
||||
|
||||
"resource_group_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"loadbalancer_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_ip_configuration_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"backend_address_pool_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"protocol": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"frontend_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"backend_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"probe_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"enable_floating_ip": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
},
|
||||
|
||||
"idle_timeout_in_minutes": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"load_distribution": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerRuleCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, _, exists = findLoadBalancerRuleByName(loadBalancer, d.Get("name").(string))
|
||||
if exists {
|
||||
return fmt.Errorf("A LoadBalancer Rule with name %q already exists.", d.Get("name").(string))
|
||||
}
|
||||
|
||||
newLbRule, err := expandAzureRmLoadBalancerRule(d, loadBalancer)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Exanding LoadBalancer Rule {{err}}", err)
|
||||
}
|
||||
|
||||
lbRules := append(*loadBalancer.Properties.LoadBalancingRules, *newLbRule)
|
||||
loadBalancer.Properties.LoadBalancingRules = &lbRules
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
d.SetId(*read.ID)
|
||||
|
||||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName)
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: []string{"Accepted", "Updating"},
|
||||
Target: []string{"Succeeded"},
|
||||
Refresh: loadbalancerStateRefreshFunc(client, resGroup, loadBalancerName),
|
||||
Timeout: 10 * time.Minute,
|
||||
}
|
||||
if _, err := stateConf.WaitForState(); err != nil {
|
||||
return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", loadBalancerName, err)
|
||||
}
|
||||
|
||||
return resourceArmLoadBalancerRuleRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) error {
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Id(), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string))
|
||||
return nil
|
||||
}
|
||||
|
||||
configs := *loadBalancer.Properties.LoadBalancingRules
|
||||
for _, config := range configs {
|
||||
if *config.Name == d.Get("name").(string) {
|
||||
d.Set("name", config.Name)
|
||||
|
||||
d.Set("protocol", config.Properties.Protocol)
|
||||
d.Set("frontend_port", config.Properties.FrontendPort)
|
||||
d.Set("backend_port", config.Properties.BackendPort)
|
||||
|
||||
if config.Properties.EnableFloatingIP != nil {
|
||||
d.Set("enable_floating_ip", config.Properties.EnableFloatingIP)
|
||||
}
|
||||
|
||||
if config.Properties.IdleTimeoutInMinutes != nil {
|
||||
d.Set("idle_timeout_in_minutes", config.Properties.IdleTimeoutInMinutes)
|
||||
}
|
||||
|
||||
if config.Properties.FrontendIPConfiguration != nil {
|
||||
d.Set("frontend_ip_configuration_id", config.Properties.FrontendIPConfiguration.ID)
|
||||
}
|
||||
|
||||
if config.Properties.BackendAddressPool != nil {
|
||||
d.Set("backend_address_pool_id", config.Properties.BackendAddressPool.ID)
|
||||
}
|
||||
|
||||
if config.Properties.Probe != nil {
|
||||
d.Set("probe_id", config.Properties.Probe.ID)
|
||||
}
|
||||
|
||||
if config.Properties.LoadDistribution != "" {
|
||||
d.Set("load_distribution", config.Properties.LoadDistribution)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceArmLoadBalancerRuleDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ArmClient)
|
||||
lbClient := client.loadBalancerClient
|
||||
|
||||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err)
|
||||
}
|
||||
if !exists {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
_, index, exists := findLoadBalancerRuleByName(loadBalancer, d.Get("name").(string))
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldLbRules := *loadBalancer.Properties.LoadBalancingRules
|
||||
newLbRules := append(oldLbRules[:index], oldLbRules[index+1:]...)
|
||||
loadBalancer.Properties.LoadBalancingRules = &newLbRules
|
||||
|
||||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err)
|
||||
}
|
||||
|
||||
_, err = lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{}))
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err)
|
||||
}
|
||||
|
||||
read, err := lbClient.Get(resGroup, loadBalancerName, "")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err)
|
||||
}
|
||||
if read.ID == nil {
|
||||
return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAzureRmLoadBalancerRule(d *schema.ResourceData, lb *network.LoadBalancer) (*network.LoadBalancingRule, error) {
|
||||
|
||||
properties := network.LoadBalancingRulePropertiesFormat{
|
||||
Protocol: network.TransportProtocol(d.Get("protocol").(string)),
|
||||
FrontendPort: azure.Int32(int32(d.Get("frontend_port").(int))),
|
||||
BackendPort: azure.Int32(int32(d.Get("backend_port").(int))),
|
||||
EnableFloatingIP: azure.Bool(d.Get("enable_floating_ip").(bool)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("idle_timeout_in_minutes"); ok {
|
||||
properties.IdleTimeoutInMinutes = azure.Int32(int32(v.(int)))
|
||||
}
|
||||
|
||||
if v := d.Get("load_distribution").(string); v != "" {
|
||||
properties.LoadDistribution = network.LoadDistribution(v)
|
||||
}
|
||||
|
||||
if v := d.Get("frontend_ip_configuration_name").(string); v != "" {
|
||||
rule, _, exists := findLoadBalancerFrontEndIpConfigurationByName(lb, v)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("[ERROR] Cannot find FrontEnd IP Configuration with the name %s", v)
|
||||
}
|
||||
|
||||
feip := network.SubResource{
|
||||
ID: rule.ID,
|
||||
}
|
||||
|
||||
properties.FrontendIPConfiguration = &feip
|
||||
}
|
||||
|
||||
if v := d.Get("backend_address_pool_id").(string); v != "" {
|
||||
beAP := network.SubResource{
|
||||
ID: &v,
|
||||
}
|
||||
|
||||
properties.BackendAddressPool = &beAP
|
||||
}
|
||||
|
||||
if v := d.Get("probe_id").(string); v != "" {
|
||||
pid := network.SubResource{
|
||||
ID: &v,
|
||||
}
|
||||
|
||||
properties.Probe = &pid
|
||||
}
|
||||
|
||||
lbRule := network.LoadBalancingRule{
|
||||
Name: azure.String(d.Get("name").(string)),
|
||||
Properties: &properties,
|
||||
}
|
||||
|
||||
return &lbRule, nil
|
||||
}
|
||||
|
||||
func validateArmLoadBalancerRuleName(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(string)
|
||||
if !regexp.MustCompile(`^[a-zA-Z._-]+$`).MatchString(value) {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"only word characters and hyphens allowed in %q: %q",
|
||||
k, value))
|
||||
}
|
||||
|
||||
if len(value) > 80 {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"%q cannot be longer than 80 characters: %q", k, value))
|
||||
}
|
||||
|
||||
if len(value) == 0 {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"%q cannot be an empty string: %q", k, value))
|
||||
}
|
||||
if !regexp.MustCompile(`[a-zA-Z]$`).MatchString(value) {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"%q must end with a word character: %q", k, value))
|
||||
}
|
||||
|
||||
if !regexp.MustCompile(`^[a-zA-Z]`).MatchString(value) {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"%q must start with a word character: %q", k, value))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestResourceAzureRMLoadBalancerRuleNameLabel_validation(t *testing.T) {
|
||||
cases := []struct {
|
||||
Value string
|
||||
ErrCount int
|
||||
}{
|
||||
{
|
||||
Value: "-word",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
Value: "testing-",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
Value: "test123test",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
Value: acctest.RandStringFromCharSet(81, "abcdedfed"),
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
Value: "test.rule",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "test_rule",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "test-rule",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "TestRule",
|
||||
ErrCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
_, errors := validateArmLoadBalancerRuleName(tc.Value, "azurerm_lb_rule")
|
||||
|
||||
if len(errors) != tc.ErrCount {
|
||||
t.Fatalf("Expected the Azure RM LoadBalancer Rule Name Label to trigger a validation error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancerRule_basic(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
lbRuleName := fmt.Sprintf("LbRule-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerRule_basic(ri, lbRuleName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerRuleExists(lbRuleName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancerRule_removal(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
lbRuleName := fmt.Sprintf("LbRule-%d", ri)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerRule_basic(ri, lbRuleName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerRuleExists(lbRuleName, &lb),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancerRule_removal(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
testCheckAzureRMLoadBalancerRuleNotExists(lbRuleName, &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerRuleExists(lbRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerRuleByName(lb, lbRuleName)
|
||||
if !exists {
|
||||
return fmt.Errorf("A LoadBalancer Rule with name %q cannot be found.", lbRuleName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerRuleNotExists(lbRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
_, _, exists := findLoadBalancerRuleByName(lb, lbRuleName)
|
||||
if exists {
|
||||
return fmt.Errorf("A LoadBalancer Rule with name %q has been found.", lbRuleName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerRule_basic(rInt int, lbRuleName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_rule" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "%s"
|
||||
protocol = "Tcp"
|
||||
frontend_port = 3389
|
||||
backend_port = 3389
|
||||
frontend_ip_configuration_name = "one-%d"
|
||||
}
|
||||
|
||||
`, rInt, rInt, rInt, rInt, lbRuleName, rInt)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancerRule_removal(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
`, rInt, rInt, rInt, rInt)
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
package azurerm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/network"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestResourceAzureRMLoadBalancerPrivateIpAddressAllocation_validation(t *testing.T) {
|
||||
cases := []struct {
|
||||
Value string
|
||||
ErrCount int
|
||||
}{
|
||||
{
|
||||
Value: "Random",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
Value: "Static",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "Dynamic",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "STATIC",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "static",
|
||||
ErrCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
_, errors := validateLoadBalancerPrivateIpAddressAllocation(tc.Value, "azurerm_lb")
|
||||
|
||||
if len(errors) != tc.ErrCount {
|
||||
t.Fatalf("Expected the Azure RM LoadBalancer private_ip_address_allocation to trigger a validation error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancer_basic(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancer_basic(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancer_frontEndConfig(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancer_frontEndConfig(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "frontend_ip_configuration.#", "2"),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancer_frontEndConfigRemoval(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "frontend_ip_configuration.#", "1"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAzureRMLoadBalancer_tags(t *testing.T) {
|
||||
var lb network.LoadBalancer
|
||||
ri := acctest.RandInt()
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testCheckAzureRMLoadBalancerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancer_basic(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "tags.%", "2"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "tags.Environment", "production"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "tags.Purpose", "AcceptanceTests"),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAzureRMLoadBalancer_updatedTags(ri),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "tags.%", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"azurerm_lb.test", "tags.Purpose", "AcceptanceTests"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerExists(name string, lb *network.LoadBalancer) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", name)
|
||||
}
|
||||
|
||||
loadbalancerName := rs.Primary.Attributes["name"]
|
||||
resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
|
||||
if !hasResourceGroup {
|
||||
return fmt.Errorf("Bad: no resource group found in state for loadbalancer: %s", loadbalancerName)
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*ArmClient).loadBalancerClient
|
||||
|
||||
resp, err := conn.Get(resourceGroup, loadbalancerName, "")
|
||||
if err != nil {
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
return fmt.Errorf("Bad: LoadBalancer %q (resource group: %q) does not exist", loadbalancerName, resourceGroup)
|
||||
}
|
||||
|
||||
return fmt.Errorf("Bad: Get on loadBalancerClient: %s", err)
|
||||
}
|
||||
|
||||
*lb = resp
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckAzureRMLoadBalancerDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*ArmClient).loadBalancerClient
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "azurerm_lb" {
|
||||
continue
|
||||
}
|
||||
|
||||
name := rs.Primary.Attributes["name"]
|
||||
resourceGroup := rs.Primary.Attributes["resource_group_name"]
|
||||
|
||||
resp, err := conn.Get(resourceGroup, name, "")
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusNotFound {
|
||||
return fmt.Errorf("LoadBalancer still exists:\n%#v", resp.Properties)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancer_basic(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
tags {
|
||||
Environment = "production"
|
||||
Purpose = "AcceptanceTests"
|
||||
}
|
||||
|
||||
}`, rInt, rInt)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancer_updatedTags(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
tags {
|
||||
Purpose = "AcceptanceTests"
|
||||
}
|
||||
|
||||
}`, rInt, rInt)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancer_frontEndConfig(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test1" {
|
||||
name = "another-test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "two-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test1.id}"
|
||||
}
|
||||
}`, rInt, rInt, rInt, rInt, rInt, rInt)
|
||||
}
|
||||
|
||||
func testAccAzureRMLoadBalancer_frontEndConfigRemoval(rInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "acctestrg-%d"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "test-ip-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "arm-test-loadbalancer-%d"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "one-%d"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}`, rInt, rInt, rInt, rInt)
|
||||
}
|
|
@ -11,6 +11,7 @@ func tagsSchema() *schema.Schema {
|
|||
return &schema.Schema{
|
||||
Type: schema.TypeMap,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateFunc: validateAzureRMTags,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
layout: "azurerm"
|
||||
page_title: "Azure Resource Manager: azurerm_lb"
|
||||
sidebar_current: "docs-azurerm-resource-loadbalancer"
|
||||
description: |-
|
||||
Create a LoadBalancer Resource.
|
||||
---
|
||||
|
||||
# azurerm\_lb
|
||||
|
||||
Create a LoadBalancer Resource.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "LoadBalancerRG"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "PublicIPForLB"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "TestLoadBalancer"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "PublicIPAddress"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) Specifies the name of the LoadBalancer.
|
||||
* `resource_group_name` - (Required) The name of the resource group in which to create the LoadBalancer.
|
||||
* `location` - (Required) Specifies the supported Azure location where the resource exists.
|
||||
* `frontend_ip_configuration` - (Optional) A frontend ip configuration block as documented below.
|
||||
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
||||
|
||||
`frontend_ip_configuration` supports the following:
|
||||
|
||||
* `name` - (Required) Specifies the name of the frontend ip configuration.
|
||||
* `subnet_id` - (Optional) Reference to subnet associated with the IP Configuration.
|
||||
* `private_ip_address` - (Optional) Private IP Address to assign to the Load Balancer. The last one and first four IPs in any range are reserved and cannot be manually assigned.
|
||||
* `public_ip_address_id` - (Optional) Reference to Public IP address to be associated with the Load Balancer.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The LoadBalancer ID.
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
layout: "azurerm"
|
||||
page_title: "Azure Resource Manager: azurerm_lb_backend_address_pool"
|
||||
sidebar_current: "docs-azurerm-resource-loadbalancer-backend-address-pool"
|
||||
description: |-
|
||||
Create a LoadBalancer Backend Address Pool.
|
||||
---
|
||||
|
||||
# azurerm\_lb\_backend\_address\_pool
|
||||
|
||||
Create a LoadBalancer Backend Address Pool.
|
||||
|
||||
~> **NOTE When using this resource, the LoadBalancer needs to have a FrontEnd IP Configuration Attached
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "LoadBalancerRG"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "PublicIPForLB"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "TestLoadBalancer"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "PublicIPAddress"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_backend_address_pool" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "BackEndAddressPool"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) Specifies the name of the Backend Address Pool.
|
||||
* `resource_group_name` - (Required) The name of the resource group in which to create the resource.
|
||||
* `location` - (Required) Specifies the supported Azure location where the resource exists.
|
||||
* `loadbalancer_id` - (Required) The ID of the LoadBalancer in which to create the Backend Address Pool.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the LoadBalancer to which the resource is attached.
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
layout: "azurerm"
|
||||
page_title: "Azure Resource Manager: azurerm_lb_nat_pool"
|
||||
sidebar_current: "docs-azurerm-resource-loadbalancer-nat-pool"
|
||||
description: |-
|
||||
Create a LoadBalancer NAT Pool.
|
||||
---
|
||||
|
||||
# azurerm\_lb\_nat\_pool
|
||||
|
||||
Create a LoadBalancer NAT pool.
|
||||
|
||||
~> **NOTE When using this resource, the LoadBalancer needs to have a FrontEnd IP Configuration Attached
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "LoadBalancerRG"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "PublicIPForLB"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "TestLoadBalancer"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "PublicIPAddress"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_nat_pool" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "SampleApplication Pool"
|
||||
protocol = "Tcp"
|
||||
frontend_port_start = 80
|
||||
frontend_port_end = 81
|
||||
backend_port = 8080
|
||||
frontend_ip_configuration_name = "PublicIPAddress"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) Specifies the name of the NAT pool.
|
||||
* `resource_group_name` - (Required) The name of the resource group in which to create the resource.
|
||||
* `location` - (Required) Specifies the supported Azure location where the resource exists.
|
||||
* `loadbalancer_id` - (Required) The ID of the LoadBalancer in which to create the NAT pool.
|
||||
* `frontend_ip_configuration_name` - (Required) The name of the frontend IP configuration exposing this rule.
|
||||
* `protocol` - (Required) The transport protocol for the external endpoint. Possible values are `Udp` or `Tcp`.
|
||||
* `frontend_port_start` - (Required) The first port number in the range of external ports that will be used to provide Inbound Nat to NICs associated with this Load Balancer. Possible values range between 1 and 65534, inclusive.
|
||||
* `frontend_port_end` - (Required) The last port number in the range of external ports that will be used to provide Inbound Nat to NICs associated with this Load Balancer. Possible values range between 1 and 65534, inclusive.
|
||||
* `backend_port` - (Required) The port used for the internal endpoint. Possible values range between 1 and 65535, inclusive.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the LoadBalancer to which the resource is attached.
|
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
layout: "azurerm"
|
||||
page_title: "Azure Resource Manager: azurerm_lb_nat_rule"
|
||||
sidebar_current: "docs-azurerm-resource-loadbalancer-nat-rule"
|
||||
description: |-
|
||||
Create a LoadBalancer NAT Rule.
|
||||
---
|
||||
|
||||
# azurerm\_lb\_nat\_rule
|
||||
|
||||
Create a LoadBalancer NAT Rule.
|
||||
|
||||
~> **NOTE When using this resource, the LoadBalancer needs to have a FrontEnd IP Configuration Attached
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "LoadBalancerRG"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "PublicIPForLB"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "TestLoadBalancer"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "PublicIPAddress"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_nat_rule" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "RDP Access"
|
||||
protocol = "Tcp"
|
||||
frontend_port = 3389
|
||||
backend_port = 3389
|
||||
frontend_ip_configuration_name = "PublicIPAddress"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) Specifies the name of the NAT Rule.
|
||||
* `resource_group_name` - (Required) The name of the resource group in which to create the resource.
|
||||
* `location` - (Required) Specifies the supported Azure location where the resource exists.
|
||||
* `loadbalancer_id` - (Required) The ID of the LoadBalancer in which to create the NAT Rule.
|
||||
* `frontend_ip_configuration_name` - (Required) The name of the frontend IP configuration exposing this rule.
|
||||
* `protocol` - (Required) The transport protocol for the external endpoint. Possible values are `Udp` or `Tcp`.
|
||||
* `frontend_port` - (Required) The port for the external endpoint. Port numbers for each Rule must be unique within the Load Balancer. Possible values range between 1 and 65534, inclusive.
|
||||
* `backend_port` - (Required) The port used for internal connections on the endpoint. Possible values range between 1 and 65535, inclusive.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the LoadBalancer to which the resource is attached.
|
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
layout: "azurerm"
|
||||
page_title: "Azure Resource Manager: azurerm_lb_probe"
|
||||
sidebar_current: "docs-azurerm-resource-loadbalancer-probe"
|
||||
description: |-
|
||||
Create a LoadBalancer Probe Resource.
|
||||
---
|
||||
|
||||
# azurerm\_lb\_probe
|
||||
|
||||
Create a LoadBalancer Probe Resource.
|
||||
|
||||
~> **NOTE When using this resource, the LoadBalancer needs to have a FrontEnd IP Configuration Attached
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "LoadBalancerRG"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "PublicIPForLB"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "TestLoadBalancer"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "PublicIPAddress"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_probe" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "SSH Running Probe"
|
||||
port = 22
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) Specifies the name of the Probe.
|
||||
* `resource_group_name` - (Required) The name of the resource group in which to create the resource.
|
||||
* `location` - (Required) Specifies the supported Azure location where the resource exists.
|
||||
* `loadbalancer_id` - (Required) The ID of the LoadBalancer in which to create the NAT Rule.
|
||||
* `protocol` - (Optional) Specifies the protocol of the end point. Possible values are `Http` or `Tcp`. If Tcp is specified, a received ACK is required for the probe to be successful. If Http is specified, a 200 OK response from the specified URI is required for the probe to be successful.
|
||||
* `port` - (Required) Port on which the Probe queries the backend endpoint. Possible values range from 1 to 65535, inclusive.
|
||||
* `request_path` - (Optional) The URI used for requesting health status from the backend endpoint. Required if protocol is set to Http. Otherwise, it is not allowed.
|
||||
* `interval_in_seconds` - (Optional) The interval, in seconds between probes to the backend endpoint for health status. The default value is 15, the minimum value is 5.
|
||||
* `number_of_probes` - (Optional) The number of failed probe attempts after which the backend endpoint is removed from rotation. The default value is 2. NumberOfProbes multiplied by intervalInSeconds value must be greater or equal to 10.Endpoints are returned to rotation when at least one probe is successful.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the LoadBalancer to which the resource is attached.
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
layout: "azurerm"
|
||||
page_title: "Azure Resource Manager: azurerm_lb_rule"
|
||||
sidebar_current: "docs-azurerm-resource-loadbalancer-rule"
|
||||
description: |-
|
||||
Create a LoadBalancer Rule.
|
||||
---
|
||||
|
||||
# azurerm\_lb\_rule
|
||||
|
||||
Create a LoadBalancer Rule.
|
||||
|
||||
~> **NOTE When using this resource, the LoadBalancer needs to have a FrontEnd IP Configuration Attached
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "azurerm_resource_group" "test" {
|
||||
name = "LoadBalancerRG"
|
||||
location = "West US"
|
||||
}
|
||||
|
||||
resource "azurerm_public_ip" "test" {
|
||||
name = "PublicIPForLB"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
public_ip_address_allocation = "static"
|
||||
}
|
||||
|
||||
resource "azurerm_lb" "test" {
|
||||
name = "TestLoadBalancer"
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "PublicIPAddress"
|
||||
public_ip_address_id = "${azurerm_public_ip.test.id}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_lb_rule" "test" {
|
||||
location = "West US"
|
||||
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||
loadbalancer_id = "${azurerm_lb.test.id}"
|
||||
name = "LBRule"
|
||||
protocol = "Tcp"
|
||||
frontend_port = 3389
|
||||
backend_port = 3389
|
||||
frontend_ip_configuration_name = "PublicIPAddress"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) Specifies the name of the LB Rule.
|
||||
* `resource_group_name` - (Required) The name of the resource group in which to create the resource.
|
||||
* `location` - (Required) Specifies the supported Azure location where the resource exists.
|
||||
* `loadbalancer_id` - (Required) The ID of the LoadBalancer in which to create the Rule.
|
||||
* `frontend_ip_configuration_name` - (Required) The name of the frontend IP configuration to which the rule is associated.
|
||||
* `protocol` - (Required) The transport protocol for the external endpoint. Possible values are `Udp` or `Tcp`.
|
||||
* `frontend_port` - (Required) The port for the external endpoint. Port numbers for each Rule must be unique within the Load Balancer. Possible values range between 1 and 65534, inclusive.
|
||||
* `backend_port` - (Required) The port used for internal connections on the endpoint. Possible values range between 1 and 65535, inclusive.
|
||||
* `backend_address_pool_id` - (Optional) A reference to a Backend Address Pool over which this Load Balancing Rule operates.
|
||||
* `probe_id` - (Optional) A reference to a Probe used by this Load Balancing Rule.
|
||||
* `enable_floating_ip` - (Optional) Floating IP is pertinent to failover scenarios: a “floating” IP is reassigned to a secondary server in case the primary server fails. Floating IP is required for SQL AlwaysOn.
|
||||
* `idle_timeout_in_minutes` - (Optional) Specifies the timeout for the Tcp idle connection. The value can be set between 4 and 30 minutes. The default value is 4 minutes. This element is only used when the protocol is set to Tcp.
|
||||
* `load_distribution` - (Optional) Specifies the load balancing distribution type to be used by the Load Balancer. Possible values are: Default – The load balancer is configured to use a 5 tuple hash to map traffic to available servers. SourceIP – The load balancer is configured to use a 2 tuple hash to map traffic to available servers. SourceIPProtocol – The load balancer is configured to use a 3 tuple hash to map traffic to available servers.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the LoadBalancer to which the resource is attached.
|
|
@ -74,6 +74,37 @@
|
|||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current(/^docs-azurerm-resource-loadbalancer/) %>>
|
||||
<a href="#">Load Balancer Resources</a>
|
||||
<ul class="nav nav-visible">
|
||||
|
||||
<li<%= sidebar_current("docs-azurerm-resource-loadbalancer") %>>
|
||||
<a href="/docs/providers/azurerm/r/loadbalancer.html">azurerm_lb</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-azurerm-resource-loadbalancer-backend-address-pool") %>>
|
||||
<a href="/docs/providers/azurerm/r/loadbalancer_backend_address_pool.html">azurerm_lb_backend_address_pool</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-azurerm-resource-loadbalancer-rule") %>>
|
||||
<a href="/docs/providers/azurerm/r/loadbalancer_rule.html">azurerm_lb_rule</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-azurerm-resource-loadbalancer-nat-rule") %>>
|
||||
<a href="/docs/providers/azurerm/r/loadbalancer_nat_rule.html">azurerm_lb_nat_rule</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-azurerm-resource-loadbalancer-nat-pool") %>>
|
||||
<a href="/docs/providers/azurerm/r/loadbalancer_nat_pool.html">azurerm_lb_nat_pool</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-azurerm-resource-loadbalancer-probe") %>>
|
||||
<a href="/docs/providers/azurerm/r/loadbalancer_probe.html">azurerm_lb_probe</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current(/^docs-azurerm-resource-network/) %>>
|
||||
<a href="#">Network Resources</a>
|
||||
<ul class="nav nav-visible">
|
||||
|
|
Loading…
Reference in New Issue