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