diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 9d2fd1754..324e5a0a5 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -49,7 +49,7 @@ func Provider() terraform.ResourceProvider { //"azurerm_cdn_endpoint": resourceArmCdnEndpoint(), //"azurerm_cdn_profile": resourceArmCdnProfile(), //"azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), - //"azurerm_network_interface": resourceArmNetworkInterface(), + "azurerm_network_interface": resourceArmNetworkInterface(), //"azurerm_network_security_group": resourceArmNetworkSecurityGroup(), //"azurerm_network_security_rule": resourceArmNetworkSecurityRule(), "azurerm_public_ip": resourceArmPublicIp(), diff --git a/builtin/providers/azurerm/resource_arm_network_interface_card.go b/builtin/providers/azurerm/resource_arm_network_interface_card.go index 3207d3e87..8e6771541 100644 --- a/builtin/providers/azurerm/resource_arm_network_interface_card.go +++ b/builtin/providers/azurerm/resource_arm_network_interface_card.go @@ -1,431 +1,427 @@ package azurerm -//import ( -// "bytes" -// "fmt" -// "log" -// "net/http" -// "strings" -// "time" -// -// "github.com/Azure/azure-sdk-for-go/arm/network" -// "github.com/hashicorp/terraform/helper/hashcode" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/helper/schema" -//) -// -//func resourceArmNetworkInterface() *schema.Resource { -// return &schema.Resource{ -// Create: resourceArmNetworkInterfaceCreate, -// Read: resourceArmNetworkInterfaceRead, -// Update: resourceArmNetworkInterfaceCreate, -// Delete: resourceArmNetworkInterfaceDelete, -// -// Schema: map[string]*schema.Schema{ -// "name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "location": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// StateFunc: azureRMNormalizeLocation, -// }, -// -// "resource_group_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "network_security_group_id": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "mac_address": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "private_ip_address": &schema.Schema{ -// Type: schema.TypeString, -// Computed: true, -// }, -// -// "virtual_machine_id": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "ip_configuration": &schema.Schema{ -// Type: schema.TypeSet, -// Required: true, -// Elem: &schema.Resource{ -// Schema: map[string]*schema.Schema{ -// "name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// }, -// -// "subnet_id": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// }, -// -// "private_ip_address": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "private_ip_address_allocation": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ValidateFunc: validateNetworkInterfacePrivateIpAddressAllocation, -// }, -// -// "public_ip_address_id": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "load_balancer_backend_address_pools_ids": &schema.Schema{ -// Type: schema.TypeSet, -// Optional: true, -// Computed: true, -// Elem: &schema.Schema{Type: schema.TypeString}, -// Set: schema.HashString, -// }, -// -// "load_balancer_inbound_nat_rules_ids": &schema.Schema{ -// Type: schema.TypeSet, -// Optional: true, -// Computed: true, -// Elem: &schema.Schema{Type: schema.TypeString}, -// Set: schema.HashString, -// }, -// }, -// }, -// Set: resourceArmNetworkInterfaceIpConfigurationHash, -// }, -// -// "dns_servers": &schema.Schema{ -// Type: schema.TypeSet, -// Optional: true, -// Computed: true, -// Elem: &schema.Schema{Type: schema.TypeString}, -// Set: schema.HashString, -// }, -// -// "internal_dns_name_label": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "applied_dns_servers": &schema.Schema{ -// Type: schema.TypeSet, -// Optional: true, -// Computed: true, -// Elem: &schema.Schema{Type: schema.TypeString}, -// Set: schema.HashString, -// }, -// -// "internal_fqdn": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "enable_ip_forwarding": &schema.Schema{ -// Type: schema.TypeBool, -// Optional: true, -// Default: false, -// }, -// -// "tags": tagsSchema(), -// }, -// } -//} -// -//func resourceArmNetworkInterfaceCreate(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient) -// ifaceClient := client.ifaceClient -// -// log.Printf("[INFO] preparing arguments for Azure ARM Network Interface creation.") -// -// name := d.Get("name").(string) -// location := d.Get("location").(string) -// resGroup := d.Get("resource_group_name").(string) -// enableIpForwarding := d.Get("enable_ip_forwarding").(bool) -// tags := d.Get("tags").(map[string]interface{}) -// -// properties := network.InterfacePropertiesFormat{ -// EnableIPForwarding: &enableIpForwarding, -// } -// -// if v, ok := d.GetOk("network_security_group_id"); ok { -// nsgId := v.(string) -// properties.NetworkSecurityGroup = &network.SecurityGroup{ -// ID: &nsgId, -// } -// } -// -// dns, hasDns := d.GetOk("dns_servers") -// nameLabel, hasNameLabel := d.GetOk("internal_dns_name_label") -// if hasDns || hasNameLabel { -// ifaceDnsSettings := network.InterfaceDNSSettings{} -// -// if hasDns { -// var dnsServers []string -// dns := dns.(*schema.Set).List() -// for _, v := range dns { -// str := v.(string) -// dnsServers = append(dnsServers, str) -// } -// ifaceDnsSettings.DNSServers = &dnsServers -// } -// -// if hasNameLabel { -// name_label := nameLabel.(string) -// ifaceDnsSettings.InternalDNSNameLabel = &name_label -// -// } -// -// properties.DNSSettings = &ifaceDnsSettings -// } -// -// ipConfigs, sgErr := expandAzureRmNetworkInterfaceIpConfigurations(d) -// if sgErr != nil { -// return fmt.Errorf("Error Building list of Network Interface IP Configurations: %s", sgErr) -// } -// if len(ipConfigs) > 0 { -// properties.IPConfigurations = &ipConfigs -// } -// -// iface := network.Interface{ -// Name: &name, -// Location: &location, -// Properties: &properties, -// Tags: expandTags(tags), -// } -// -// resp, err := ifaceClient.CreateOrUpdate(resGroup, name, iface) -// if err != nil { -// return err -// } -// -// d.SetId(*resp.ID) -// -// log.Printf("[DEBUG] Waiting for Network Interface (%s) to become available", name) -// stateConf := &resource.StateChangeConf{ -// Pending: []string{"Accepted", "Updating"}, -// Target: []string{"Succeeded"}, -// Refresh: networkInterfaceStateRefreshFunc(client, resGroup, name), -// Timeout: 10 * time.Minute, -// } -// if _, err := stateConf.WaitForState(); err != nil { -// return fmt.Errorf("Error waiting for Network Interface (%s) to become available: %s", name, err) -// } -// -// return resourceArmNetworkInterfaceRead(d, meta) -//} -// -//func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error { -// ifaceClient := meta.(*ArmClient).ifaceClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// name := id.Path["networkInterfaces"] -// -// resp, err := ifaceClient.Get(resGroup, name, "") -// if resp.StatusCode == http.StatusNotFound { -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error making Read request on Azure Network Interface %s: %s", name, err) -// } -// -// iface := *resp.Properties -// -// if iface.MacAddress != nil { -// if *iface.MacAddress != "" { -// d.Set("mac_address", iface.MacAddress) -// } -// } -// -// if iface.IPConfigurations != nil && len(*iface.IPConfigurations) > 0 { -// var privateIPAddress *string -// ///TODO: Change this to a loop when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed -// if (*iface.IPConfigurations)[0].Properties != nil { -// privateIPAddress = (*iface.IPConfigurations)[0].Properties.PrivateIPAddress -// } -// -// if *privateIPAddress != "" { -// d.Set("private_ip_address", *privateIPAddress) -// } -// } -// -// if iface.VirtualMachine != nil { -// if *iface.VirtualMachine.ID != "" { -// d.Set("virtual_machine_id", *iface.VirtualMachine.ID) -// } -// } -// -// if iface.DNSSettings != nil { -// if iface.DNSSettings.AppliedDNSServers != nil && len(*iface.DNSSettings.AppliedDNSServers) > 0 { -// dnsServers := make([]string, 0, len(*iface.DNSSettings.AppliedDNSServers)) -// for _, dns := range *iface.DNSSettings.AppliedDNSServers { -// dnsServers = append(dnsServers, dns) -// } -// -// if err := d.Set("applied_dns_servers", dnsServers); err != nil { -// return err -// } -// } -// -// if iface.DNSSettings.InternalFqdn != nil && *iface.DNSSettings.InternalFqdn != "" { -// d.Set("internal_fqdn", iface.DNSSettings.InternalFqdn) -// } -// } -// -// flattenAndSetTags(d, resp.Tags) -// -// return nil -//} -// -//func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) error { -// ifaceClient := meta.(*ArmClient).ifaceClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// name := id.Path["networkInterfaces"] -// -// _, err = ifaceClient.Delete(resGroup, name) -// -// return err -//} -// -//func networkInterfaceStateRefreshFunc(client *ArmClient, resourceGroupName string, ifaceName string) resource.StateRefreshFunc { -// return func() (interface{}, string, error) { -// res, err := client.ifaceClient.Get(resourceGroupName, ifaceName, "") -// if err != nil { -// return nil, "", fmt.Errorf("Error issuing read request in networkInterfaceStateRefreshFunc to Azure ARM for network interace '%s' (RG: '%s'): %s", ifaceName, resourceGroupName, err) -// } -// -// return res, *res.Properties.ProvisioningState, nil -// } -//} -// -//func resourceArmNetworkInterfaceIpConfigurationHash(v interface{}) int { -// var buf bytes.Buffer -// m := v.(map[string]interface{}) -// buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) -// buf.WriteString(fmt.Sprintf("%s-", m["subnet_id"].(string))) -// if m["private_ip_address"] != nil { -// buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address"].(string))) -// } -// buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address_allocation"].(string))) -// if m["public_ip_address_id"] != nil { -// buf.WriteString(fmt.Sprintf("%s-", m["public_ip_address_id"].(string))) -// } -// -// return hashcode.String(buf.String()) -//} -// -//func validateNetworkInterfacePrivateIpAddressAllocation(v interface{}, k string) (ws []string, errors []error) { -// value := strings.ToLower(v.(string)) -// allocations := map[string]bool{ -// "static": true, -// "dynamic": true, -// } -// -// if !allocations[value] { -// errors = append(errors, fmt.Errorf("Network Interface Allocations can only be Static or Dynamic")) -// } -// return -//} -// -//func expandAzureRmNetworkInterfaceIpConfigurations(d *schema.ResourceData) ([]network.InterfaceIPConfiguration, error) { -// configs := d.Get("ip_configuration").(*schema.Set).List() -// ipConfigs := make([]network.InterfaceIPConfiguration, 0, len(configs)) -// -// for _, configRaw := range configs { -// data := configRaw.(map[string]interface{}) -// -// subnet_id := data["subnet_id"].(string) -// private_ip_allocation_method := data["private_ip_address_allocation"].(string) -// -// properties := network.InterfaceIPConfigurationPropertiesFormat{ -// Subnet: &network.Subnet{ -// ID: &subnet_id, -// }, -// PrivateIPAllocationMethod: &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, ok := data["load_balancer_backend_address_pools_ids"]; ok { -// var ids []network.BackendAddressPool -// pools := v.(*schema.Set).List() -// for _, p := range pools { -// pool_id := p.(string) -// id := network.BackendAddressPool{ -// ID: &pool_id, -// } -// -// ids = append(ids, id) -// } -// -// properties.LoadBalancerBackendAddressPools = &ids -// } -// -// if v, ok := data["load_balancer_inbound_nat_rules_ids"]; ok { -// var natRules []network.InboundNatRule -// rules := v.(*schema.Set).List() -// for _, r := range rules { -// rule_id := r.(string) -// rule := network.InboundNatRule{ -// ID: &rule_id, -// } -// -// natRules = append(natRules, rule) -// } -// -// properties.LoadBalancerInboundNatRules = &natRules -// } -// -// name := data["name"].(string) -// ipConfig := network.InterfaceIPConfiguration{ -// Name: &name, -// Properties: &properties, -// } -// -// ipConfigs = append(ipConfigs, ipConfig) -// } -// -// return ipConfigs, nil -//} +import ( + "bytes" + "fmt" + "log" + "net/http" + "strings" + + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmNetworkInterface() *schema.Resource { + return &schema.Resource{ + Create: resourceArmNetworkInterfaceCreate, + Read: resourceArmNetworkInterfaceRead, + Update: resourceArmNetworkInterfaceCreate, + Delete: resourceArmNetworkInterfaceDelete, + + 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, + }, + + "network_security_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "mac_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "private_ip_address": { + Type: schema.TypeString, + Computed: true, + }, + + "virtual_machine_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "ip_configuration": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "subnet_id": { + Type: schema.TypeString, + Required: true, + }, + + "private_ip_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "private_ip_address_allocation": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateNetworkInterfacePrivateIpAddressAllocation, + }, + + "public_ip_address_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "load_balancer_backend_address_pools_ids": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + + "load_balancer_inbound_nat_rules_ids": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + }, + Set: resourceArmNetworkInterfaceIpConfigurationHash, + }, + + "dns_servers": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + + "internal_dns_name_label": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "applied_dns_servers": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + + "internal_fqdn": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "enable_ip_forwarding": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceArmNetworkInterfaceCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + ifaceClient := client.ifaceClient + + log.Printf("[INFO] preparing arguments for Azure ARM Network Interface creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + enableIpForwarding := d.Get("enable_ip_forwarding").(bool) + tags := d.Get("tags").(map[string]interface{}) + + properties := network.InterfacePropertiesFormat{ + EnableIPForwarding: &enableIpForwarding, + } + + if v, ok := d.GetOk("network_security_group_id"); ok { + nsgId := v.(string) + properties.NetworkSecurityGroup = &network.SecurityGroup{ + ID: &nsgId, + } + } + + dns, hasDns := d.GetOk("dns_servers") + nameLabel, hasNameLabel := d.GetOk("internal_dns_name_label") + if hasDns || hasNameLabel { + ifaceDnsSettings := network.InterfaceDNSSettings{} + + if hasDns { + var dnsServers []string + dns := dns.(*schema.Set).List() + for _, v := range dns { + str := v.(string) + dnsServers = append(dnsServers, str) + } + ifaceDnsSettings.DNSServers = &dnsServers + } + + if hasNameLabel { + name_label := nameLabel.(string) + ifaceDnsSettings.InternalDNSNameLabel = &name_label + + } + + properties.DNSSettings = &ifaceDnsSettings + } + + ipConfigs, sgErr := expandAzureRmNetworkInterfaceIpConfigurations(d) + if sgErr != nil { + return fmt.Errorf("Error Building list of Network Interface IP Configurations: %s", sgErr) + } + if len(ipConfigs) > 0 { + properties.IPConfigurations = &ipConfigs + } + + iface := network.Interface{ + Name: &name, + Location: &location, + Properties: &properties, + Tags: expandTags(tags), + } + + _, err := ifaceClient.CreateOrUpdate(resGroup, name, iface, make(chan struct{})) + if err != nil { + return err + } + + read, err := ifaceClient.Get(resGroup, name, "") + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read NIC %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmNetworkInterfaceRead(d, meta) +} + +func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error { + ifaceClient := meta.(*ArmClient).ifaceClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["networkInterfaces"] + + resp, err := ifaceClient.Get(resGroup, name, "") + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error making Read request on Azure Network Interface %s: %s", name, err) + } + + iface := *resp.Properties + + if iface.MacAddress != nil { + if *iface.MacAddress != "" { + d.Set("mac_address", iface.MacAddress) + } + } + + if iface.IPConfigurations != nil && len(*iface.IPConfigurations) > 0 { + var privateIPAddress *string + ///TODO: Change this to a loop when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed + if (*iface.IPConfigurations)[0].Properties != nil { + privateIPAddress = (*iface.IPConfigurations)[0].Properties.PrivateIPAddress + } + + if *privateIPAddress != "" { + d.Set("private_ip_address", *privateIPAddress) + } + } + + if iface.VirtualMachine != nil { + if *iface.VirtualMachine.ID != "" { + d.Set("virtual_machine_id", *iface.VirtualMachine.ID) + } + } + + if iface.DNSSettings != nil { + if iface.DNSSettings.AppliedDNSServers != nil && len(*iface.DNSSettings.AppliedDNSServers) > 0 { + dnsServers := make([]string, 0, len(*iface.DNSSettings.AppliedDNSServers)) + for _, dns := range *iface.DNSSettings.AppliedDNSServers { + dnsServers = append(dnsServers, dns) + } + + if err := d.Set("applied_dns_servers", dnsServers); err != nil { + return err + } + } + + if iface.DNSSettings.InternalFqdn != nil && *iface.DNSSettings.InternalFqdn != "" { + d.Set("internal_fqdn", iface.DNSSettings.InternalFqdn) + } + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) error { + ifaceClient := meta.(*ArmClient).ifaceClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["networkInterfaces"] + + _, err = ifaceClient.Delete(resGroup, name, make(chan struct{})) + + return err +} + +func resourceArmNetworkInterfaceIpConfigurationHash(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) + buf.WriteString(fmt.Sprintf("%s-", m["subnet_id"].(string))) + if m["private_ip_address"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address"].(string))) + } + buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address_allocation"].(string))) + if m["public_ip_address_id"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["public_ip_address_id"].(string))) + } + + return hashcode.String(buf.String()) +} + +func validateNetworkInterfacePrivateIpAddressAllocation(v interface{}, k string) (ws []string, errors []error) { + value := strings.ToLower(v.(string)) + allocations := map[string]bool{ + "static": true, + "dynamic": true, + } + + if !allocations[value] { + errors = append(errors, fmt.Errorf("Network Interface Allocations can only be Static or Dynamic")) + } + return +} + +func expandAzureRmNetworkInterfaceIpConfigurations(d *schema.ResourceData) ([]network.InterfaceIPConfiguration, error) { + configs := d.Get("ip_configuration").(*schema.Set).List() + ipConfigs := make([]network.InterfaceIPConfiguration, 0, len(configs)) + + for _, configRaw := range configs { + data := configRaw.(map[string]interface{}) + + subnet_id := data["subnet_id"].(string) + private_ip_allocation_method := data["private_ip_address_allocation"].(string) + + var allocationMethod network.IPAllocationMethod + switch strings.ToLower(private_ip_allocation_method) { + case "dynamic": + allocationMethod = network.Dynamic + case "static": + allocationMethod = network.Static + default: + return []network.InterfaceIPConfiguration{}, fmt.Errorf( + "valid values for private_ip_allocation_method are 'dynamic' and 'static' - got '%s'", + private_ip_allocation_method) + } + + properties := network.InterfaceIPConfigurationPropertiesFormat{ + Subnet: &network.Subnet{ + ID: &subnet_id, + }, + PrivateIPAllocationMethod: allocationMethod, + } + + 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, ok := data["load_balancer_backend_address_pools_ids"]; ok { + var ids []network.BackendAddressPool + pools := v.(*schema.Set).List() + for _, p := range pools { + pool_id := p.(string) + id := network.BackendAddressPool{ + ID: &pool_id, + } + + ids = append(ids, id) + } + + properties.LoadBalancerBackendAddressPools = &ids + } + + if v, ok := data["load_balancer_inbound_nat_rules_ids"]; ok { + var natRules []network.InboundNatRule + rules := v.(*schema.Set).List() + for _, r := range rules { + rule_id := r.(string) + rule := network.InboundNatRule{ + ID: &rule_id, + } + + natRules = append(natRules, rule) + } + + properties.LoadBalancerInboundNatRules = &natRules + } + + name := data["name"].(string) + ipConfig := network.InterfaceIPConfiguration{ + Name: &name, + Properties: &properties, + } + + ipConfigs = append(ipConfigs, ipConfig) + } + + return ipConfigs, nil +} diff --git a/builtin/providers/azurerm/resource_arm_network_interface_card_test.go b/builtin/providers/azurerm/resource_arm_network_interface_card_test.go index 83149871e..43df3a73e 100644 --- a/builtin/providers/azurerm/resource_arm_network_interface_card_test.go +++ b/builtin/providers/azurerm/resource_arm_network_interface_card_test.go @@ -1,16 +1,82 @@ package azurerm -// -//import ( -// "fmt" -// "net/http" -// "testing" -// -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/terraform" -//) -// -//func TestAccAzureRMNetworkInterface_basic(t *testing.T) { +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMNetworkInterface_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkInterface_basic, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMNetworkInterface_enableIPForwarding(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkInterface_ipForwarding, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), + resource.TestCheckResourceAttr( + "azurerm_network_interface.test", "enable_ip_forwarding", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMNetworkInterface_withTags(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkInterface_withTags, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), + resource.TestCheckResourceAttr( + "azurerm_network_interface.test", "tags.#", "2"), + resource.TestCheckResourceAttr( + "azurerm_network_interface.test", "tags.environment", "Production"), + resource.TestCheckResourceAttr( + "azurerm_network_interface.test", "tags.cost_center", "MSFT"), + ), + }, + { + Config: testAccAzureRMNetworkInterface_withTagsUpdate, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), + resource.TestCheckResourceAttr( + "azurerm_network_interface.test", "tags.#", "1"), + resource.TestCheckResourceAttr( + "azurerm_network_interface.test", "tags.environment", "staging"), + ), + }, + }, + }) +} + +///TODO: Re-enable this test when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed +//func TestAccAzureRMNetworkInterface_addingIpConfigurations(t *testing.T) { // // resource.Test(t, resource.TestCase{ // PreCheck: func() { testAccPreCheck(t) }, @@ -21,149 +87,221 @@ package azurerm // Config: testAccAzureRMNetworkInterface_basic, // Check: resource.ComposeTestCheckFunc( // testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), +// resource.TestCheckResourceAttr( +// "azurerm_network_interface.test", "ip_configuration.#", "1"), +// ), +// }, +// +// resource.TestStep{ +// Config: testAccAzureRMNetworkInterface_extraIpConfiguration, +// Check: resource.ComposeTestCheckFunc( +// testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), +// resource.TestCheckResourceAttr( +// "azurerm_network_interface.test", "ip_configuration.#", "2"), // ), // }, // }, // }) //} -// -//func TestAccAzureRMNetworkInterfaceenableIPForwarding(t *testing.T) { -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: testAccAzureRMNetworkInterface_ipForwarding, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), -// resource.TestCheckResourceAttr( -// "azurerm_network_interface.test", "enable_ip_forwarding", "true"), -// ), -// }, -// }, -// }) -//} -// -//func TestAccAzureRMNetworkInterface_withTags(t *testing.T) { -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: testAccAzureRMNetworkInterface_withTags, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), -// resource.TestCheckResourceAttr( -// "azurerm_network_interface.test", "tags.#", "2"), -// resource.TestCheckResourceAttr( -// "azurerm_network_interface.test", "tags.environment", "Production"), -// resource.TestCheckResourceAttr( -// "azurerm_network_interface.test", "tags.cost_center", "MSFT"), -// ), -// }, -// -// resource.TestStep{ -// Config: testAccAzureRMNetworkInterface_withTagsUpdate, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), -// resource.TestCheckResourceAttr( -// "azurerm_network_interface.test", "tags.#", "1"), -// resource.TestCheckResourceAttr( -// "azurerm_network_interface.test", "tags.environment", "staging"), -// ), -// }, -// }, -// }) -//} -// -/////TODO: Re-enable this test when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed -////func TestAccAzureRMNetworkInterface_addingIpConfigurations(t *testing.T) { -//// -//// resource.Test(t, resource.TestCase{ -//// PreCheck: func() { testAccPreCheck(t) }, -//// Providers: testAccProviders, -//// CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy, -//// Steps: []resource.TestStep{ -//// resource.TestStep{ -//// Config: testAccAzureRMNetworkInterface_basic, -//// Check: resource.ComposeTestCheckFunc( -//// testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), -//// resource.TestCheckResourceAttr( -//// "azurerm_network_interface.test", "ip_configuration.#", "1"), -//// ), -//// }, -//// -//// resource.TestStep{ -//// Config: testAccAzureRMNetworkInterface_extraIpConfiguration, -//// Check: resource.ComposeTestCheckFunc( -//// testCheckAzureRMNetworkInterfaceExists("azurerm_network_interface.test"), -//// resource.TestCheckResourceAttr( -//// "azurerm_network_interface.test", "ip_configuration.#", "2"), -//// ), -//// }, -//// }, -//// }) -////} -// -//func testCheckAzureRMNetworkInterfaceExists(name string) resource.TestCheckFunc { -// return func(s *terraform.State) error { -// // Ensure we have enough information in state to look up in API -// rs, ok := s.RootModule().Resources[name] -// if !ok { -// return fmt.Errorf("Not found: %s", name) -// } -// -// name := 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 availability set: %s", name) -// } -// -// conn := testAccProvider.Meta().(*ArmClient).ifaceClient -// -// resp, err := conn.Get(resourceGroup, name, "") -// if err != nil { -// return fmt.Errorf("Bad: Get on ifaceClient: %s", err) -// } -// -// if resp.StatusCode == http.StatusNotFound { -// return fmt.Errorf("Bad: Network Interface %q (resource group: %q) does not exist", name, resourceGroup) -// } -// -// return nil -// } -//} -// -//func testCheckAzureRMNetworkInterfaceDestroy(s *terraform.State) error { -// conn := testAccProvider.Meta().(*ArmClient).ifaceClient -// -// for _, rs := range s.RootModule().Resources { -// if rs.Type != "azurerm_network_interface" { -// 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("Network Interface still exists:\n%#v", resp.Properties) -// } -// } -// -// return nil -//} -// -//var testAccAzureRMNetworkInterface_basic = ` + +func testCheckAzureRMNetworkInterfaceExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := 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 availability set: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).ifaceClient + + resp, err := conn.Get(resourceGroup, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on ifaceClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Network Interface %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMNetworkInterfaceDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).ifaceClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_network_interface" { + 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("Network Interface still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +var testAccAzureRMNetworkInterface_basic = ` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_virtual_network" "test" { + name = "acceptanceTestVirtualNetwork1" + address_space = ["10.0.0.0/16"] + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "testsubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acceptanceTestNetworkInterface1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} +` + +var testAccAzureRMNetworkInterface_ipForwarding = ` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_virtual_network" "test" { + name = "acceptanceTestVirtualNetwork1" + address_space = ["10.0.0.0/16"] + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "testsubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acceptanceTestNetworkInterface1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + enable_ip_forwarding = true + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} +` + +var testAccAzureRMNetworkInterface_withTags = ` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_virtual_network" "test" { + name = "acceptanceTestVirtualNetwork1" + address_space = ["10.0.0.0/16"] + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "testsubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acceptanceTestNetworkInterface1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } + + tags { + environment = "Production" + cost_center = "MSFT" + } +} +` + +var testAccAzureRMNetworkInterface_withTagsUpdate = ` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_virtual_network" "test" { + name = "acceptanceTestVirtualNetwork1" + address_space = ["10.0.0.0/16"] + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "testsubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acceptanceTestNetworkInterface1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } + + tags { + environment = "staging" + } +} +` + +//TODO: Re-enable this test when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed +//var testAccAzureRMNetworkInterface_extraIpConfiguration = ` //resource "azurerm_resource_group" "test" { // name = "acceptanceTestResourceGroup1" // location = "West US" @@ -183,71 +321,11 @@ package azurerm // address_prefix = "10.0.2.0/24" //} // -//resource "azurerm_network_interface" "test" { -// name = "acceptanceTestNetworkInterface1" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// -// ip_configuration { -// name = "testconfiguration1" -// subnet_id = "${azurerm_subnet.test.id}" -// private_ip_address_allocation = "dynamic" -// } -//} -//` -// -//var testAccAzureRMNetworkInterface_ipForwarding = ` -//resource "azurerm_resource_group" "test" { -// name = "acceptanceTestResourceGroup1" -// location = "West US" -//} -// -//resource "azurerm_virtual_network" "test" { -// name = "acceptanceTestVirtualNetwork1" -// address_space = ["10.0.0.0/16"] -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -//} -// -//resource "azurerm_subnet" "test" { -// name = "testsubnet" +//resource "azurerm_subnet" "test1" { +// name = "testsubnet1" // resource_group_name = "${azurerm_resource_group.test.name}" // virtual_network_name = "${azurerm_virtual_network.test.name}" -// address_prefix = "10.0.2.0/24" -//} -// -//resource "azurerm_network_interface" "test" { -// name = "acceptanceTestNetworkInterface1" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// enable_ip_forwarding = true -// -// ip_configuration { -// name = "testconfiguration1" -// subnet_id = "${azurerm_subnet.test.id}" -// private_ip_address_allocation = "dynamic" -// } -//} -//` -// -//var testAccAzureRMNetworkInterface_withTags = ` -//resource "azurerm_resource_group" "test" { -// name = "acceptanceTestResourceGroup1" -// location = "West US" -//} -// -//resource "azurerm_virtual_network" "test" { -// name = "acceptanceTestVirtualNetwork1" -// address_space = ["10.0.0.0/16"] -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -//} -// -//resource "azurerm_subnet" "test" { -// name = "testsubnet" -// resource_group_name = "${azurerm_resource_group.test.name}" -// virtual_network_name = "${azurerm_virtual_network.test.name}" -// address_prefix = "10.0.2.0/24" +// address_prefix = "10.0.1.0/24" //} // //resource "azurerm_network_interface" "test" { @@ -261,94 +339,11 @@ package azurerm // private_ip_address_allocation = "dynamic" // } // -// tags { -// environment = "Production" -// cost_center = "MSFT" -// } -//} -//` -// -//var testAccAzureRMNetworkInterface_withTagsUpdate = ` -//resource "azurerm_resource_group" "test" { -// name = "acceptanceTestResourceGroup1" -// location = "West US" -//} -// -//resource "azurerm_virtual_network" "test" { -// name = "acceptanceTestVirtualNetwork1" -// address_space = ["10.0.0.0/16"] -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -//} -// -//resource "azurerm_subnet" "test" { -// name = "testsubnet" -// resource_group_name = "${azurerm_resource_group.test.name}" -// virtual_network_name = "${azurerm_virtual_network.test.name}" -// address_prefix = "10.0.2.0/24" -//} -// -//resource "azurerm_network_interface" "test" { -// name = "acceptanceTestNetworkInterface1" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// // ip_configuration { -// name = "testconfiguration1" -// subnet_id = "${azurerm_subnet.test.id}" +// name = "testconfiguration2" +// subnet_id = "${azurerm_subnet.test1.id}" // private_ip_address_allocation = "dynamic" -// } -// -// tags { -// environment = "staging" +// primary = true // } //} //` -// -////TODO: Re-enable this test when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed -////var testAccAzureRMNetworkInterface_extraIpConfiguration = ` -////resource "azurerm_resource_group" "test" { -//// name = "acceptanceTestResourceGroup1" -//// location = "West US" -////} -//// -////resource "azurerm_virtual_network" "test" { -//// name = "acceptanceTestVirtualNetwork1" -//// address_space = ["10.0.0.0/16"] -//// location = "West US" -//// resource_group_name = "${azurerm_resource_group.test.name}" -////} -//// -////resource "azurerm_subnet" "test" { -//// name = "testsubnet" -//// resource_group_name = "${azurerm_resource_group.test.name}" -//// virtual_network_name = "${azurerm_virtual_network.test.name}" -//// address_prefix = "10.0.2.0/24" -////} -//// -////resource "azurerm_subnet" "test1" { -//// name = "testsubnet1" -//// resource_group_name = "${azurerm_resource_group.test.name}" -//// virtual_network_name = "${azurerm_virtual_network.test.name}" -//// address_prefix = "10.0.1.0/24" -////} -//// -////resource "azurerm_network_interface" "test" { -//// name = "acceptanceTestNetworkInterface1" -//// location = "West US" -//// resource_group_name = "${azurerm_resource_group.test.name}" -//// -//// ip_configuration { -//// name = "testconfiguration1" -//// subnet_id = "${azurerm_subnet.test.id}" -//// private_ip_address_allocation = "dynamic" -//// } -//// -//// ip_configuration { -//// name = "testconfiguration2" -//// subnet_id = "${azurerm_subnet.test1.id}" -//// private_ip_address_allocation = "dynamic" -//// primary = true -//// } -////} -////`