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