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