github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/azurerm/resource_arm_virtual_network.go (about)

     1  package azurerm
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"net/http"
     7  
     8  	"github.com/Azure/azure-sdk-for-go/arm/network"
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  func resourceArmVirtualNetwork() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceArmVirtualNetworkCreate,
    17  		Read:   resourceArmVirtualNetworkRead,
    18  		Update: resourceArmVirtualNetworkCreate,
    19  		Delete: resourceArmVirtualNetworkDelete,
    20  		Importer: &schema.ResourceImporter{
    21  			State: schema.ImportStatePassthrough,
    22  		},
    23  
    24  		Schema: map[string]*schema.Schema{
    25  			"name": {
    26  				Type:     schema.TypeString,
    27  				Required: true,
    28  				ForceNew: true,
    29  			},
    30  
    31  			"address_space": {
    32  				Type:     schema.TypeList,
    33  				Required: true,
    34  				Elem: &schema.Schema{
    35  					Type: schema.TypeString,
    36  				},
    37  			},
    38  
    39  			"dns_servers": {
    40  				Type:     schema.TypeList,
    41  				Optional: true,
    42  				Elem: &schema.Schema{
    43  					Type: schema.TypeString,
    44  				},
    45  			},
    46  
    47  			"subnet": {
    48  				Type:     schema.TypeSet,
    49  				Optional: true,
    50  				Computed: true,
    51  				Elem: &schema.Resource{
    52  					Schema: map[string]*schema.Schema{
    53  						"name": {
    54  							Type:     schema.TypeString,
    55  							Required: true,
    56  						},
    57  						"address_prefix": {
    58  							Type:     schema.TypeString,
    59  							Required: true,
    60  						},
    61  						"security_group": {
    62  							Type:     schema.TypeString,
    63  							Optional: true,
    64  						},
    65  					},
    66  				},
    67  				Set: resourceAzureSubnetHash,
    68  			},
    69  
    70  			"location": {
    71  				Type:      schema.TypeString,
    72  				Required:  true,
    73  				ForceNew:  true,
    74  				StateFunc: azureRMNormalizeLocation,
    75  			},
    76  
    77  			"resource_group_name": {
    78  				Type:     schema.TypeString,
    79  				Required: true,
    80  				ForceNew: true,
    81  			},
    82  
    83  			"tags": tagsSchema(),
    84  		},
    85  	}
    86  }
    87  
    88  func resourceArmVirtualNetworkCreate(d *schema.ResourceData, meta interface{}) error {
    89  	client := meta.(*ArmClient)
    90  	vnetClient := client.vnetClient
    91  
    92  	log.Printf("[INFO] preparing arguments for Azure ARM virtual network creation.")
    93  
    94  	name := d.Get("name").(string)
    95  	location := d.Get("location").(string)
    96  	resGroup := d.Get("resource_group_name").(string)
    97  	tags := d.Get("tags").(map[string]interface{})
    98  
    99  	vnet := network.VirtualNetwork{
   100  		Name:       &name,
   101  		Location:   &location,
   102  		Properties: getVirtualNetworkProperties(d),
   103  		Tags:       expandTags(tags),
   104  	}
   105  
   106  	_, err := vnetClient.CreateOrUpdate(resGroup, name, vnet, make(chan struct{}))
   107  	if err != nil {
   108  		return err
   109  	}
   110  
   111  	read, err := vnetClient.Get(resGroup, name, "")
   112  	if err != nil {
   113  		return err
   114  	}
   115  	if read.ID == nil {
   116  		return fmt.Errorf("Cannot read Virtual Network %s (resource group %s) ID", name, resGroup)
   117  	}
   118  
   119  	d.SetId(*read.ID)
   120  
   121  	return resourceArmVirtualNetworkRead(d, meta)
   122  }
   123  
   124  func resourceArmVirtualNetworkRead(d *schema.ResourceData, meta interface{}) error {
   125  	vnetClient := meta.(*ArmClient).vnetClient
   126  
   127  	id, err := parseAzureResourceID(d.Id())
   128  	if err != nil {
   129  		return err
   130  	}
   131  	resGroup := id.ResourceGroup
   132  	name := id.Path["virtualNetworks"]
   133  
   134  	resp, err := vnetClient.Get(resGroup, name, "")
   135  	if err != nil {
   136  		if resp.StatusCode == http.StatusNotFound {
   137  			d.SetId("")
   138  			return nil
   139  		}
   140  		return fmt.Errorf("Error making Read request on Azure virtual network %s: %s", name, err)
   141  	}
   142  
   143  	vnet := *resp.Properties
   144  
   145  	// update appropriate values
   146  	d.Set("resource_group_name", resGroup)
   147  	d.Set("name", resp.Name)
   148  	d.Set("location", resp.Location)
   149  	d.Set("address_space", vnet.AddressSpace.AddressPrefixes)
   150  
   151  	subnets := &schema.Set{
   152  		F: resourceAzureSubnetHash,
   153  	}
   154  
   155  	for _, subnet := range *vnet.Subnets {
   156  		s := map[string]interface{}{}
   157  
   158  		s["name"] = *subnet.Name
   159  		s["address_prefix"] = *subnet.Properties.AddressPrefix
   160  		if subnet.Properties.NetworkSecurityGroup != nil {
   161  			s["security_group"] = *subnet.Properties.NetworkSecurityGroup.ID
   162  		}
   163  
   164  		subnets.Add(s)
   165  	}
   166  	d.Set("subnet", subnets)
   167  
   168  	dnses := []string{}
   169  	for _, dns := range *vnet.DhcpOptions.DNSServers {
   170  		dnses = append(dnses, dns)
   171  	}
   172  	d.Set("dns_servers", dnses)
   173  
   174  	flattenAndSetTags(d, resp.Tags)
   175  
   176  	return nil
   177  }
   178  
   179  func resourceArmVirtualNetworkDelete(d *schema.ResourceData, meta interface{}) error {
   180  	vnetClient := meta.(*ArmClient).vnetClient
   181  
   182  	id, err := parseAzureResourceID(d.Id())
   183  	if err != nil {
   184  		return err
   185  	}
   186  	resGroup := id.ResourceGroup
   187  	name := id.Path["virtualNetworks"]
   188  
   189  	_, err = vnetClient.Delete(resGroup, name, make(chan struct{}))
   190  
   191  	return err
   192  }
   193  
   194  func getVirtualNetworkProperties(d *schema.ResourceData) *network.VirtualNetworkPropertiesFormat {
   195  	// first; get address space prefixes:
   196  	prefixes := []string{}
   197  	for _, prefix := range d.Get("address_space").([]interface{}) {
   198  		prefixes = append(prefixes, prefix.(string))
   199  	}
   200  
   201  	// then; the dns servers:
   202  	dnses := []string{}
   203  	for _, dns := range d.Get("dns_servers").([]interface{}) {
   204  		dnses = append(dnses, dns.(string))
   205  	}
   206  
   207  	// then; the subnets:
   208  	subnets := []network.Subnet{}
   209  	if subs := d.Get("subnet").(*schema.Set); subs.Len() > 0 {
   210  		for _, subnet := range subs.List() {
   211  			subnet := subnet.(map[string]interface{})
   212  
   213  			name := subnet["name"].(string)
   214  			prefix := subnet["address_prefix"].(string)
   215  			secGroup := subnet["security_group"].(string)
   216  
   217  			var subnetObj network.Subnet
   218  			subnetObj.Name = &name
   219  			subnetObj.Properties = &network.SubnetPropertiesFormat{}
   220  			subnetObj.Properties.AddressPrefix = &prefix
   221  
   222  			if secGroup != "" {
   223  				subnetObj.Properties.NetworkSecurityGroup = &network.SecurityGroup{
   224  					ID: &secGroup,
   225  				}
   226  			}
   227  
   228  			subnets = append(subnets, subnetObj)
   229  		}
   230  	}
   231  
   232  	// finally; return the struct:
   233  	return &network.VirtualNetworkPropertiesFormat{
   234  		AddressSpace: &network.AddressSpace{
   235  			AddressPrefixes: &prefixes,
   236  		},
   237  		DhcpOptions: &network.DhcpOptions{
   238  			DNSServers: &dnses,
   239  		},
   240  		Subnets: &subnets,
   241  	}
   242  }
   243  
   244  func resourceAzureSubnetHash(v interface{}) int {
   245  	m := v.(map[string]interface{})
   246  	subnet := m["name"].(string) + m["address_prefix"].(string)
   247  	if securityGroup, present := m["security_group"]; present {
   248  		subnet = subnet + securityGroup.(string)
   249  	}
   250  	return hashcode.String(subnet)
   251  }
   252  
   253  func virtualNetworkStateRefreshFunc(client *ArmClient, resourceGroupName string, networkName string) resource.StateRefreshFunc {
   254  	return func() (interface{}, string, error) {
   255  		res, err := client.vnetClient.Get(resourceGroupName, networkName, "")
   256  		if err != nil {
   257  			return nil, "", fmt.Errorf("Error issuing read request in virtualNetworkStateRefreshFunc to Azure ARM for virtual network '%s' (RG: '%s'): %s", networkName, resourceGroupName, err)
   258  		}
   259  
   260  		return res, *res.Properties.ProvisioningState, nil
   261  	}
   262  }