github.com/emc-cmd/terraform@v0.7.8-0.20161101145618-f16309630e7c/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 if vnet.DhcpOptions != nil && vnet.DhcpOptions.DNSServers != nil { 169 dnses := []string{} 170 for _, dns := range *vnet.DhcpOptions.DNSServers { 171 dnses = append(dnses, dns) 172 } 173 d.Set("dns_servers", dnses) 174 } 175 176 flattenAndSetTags(d, resp.Tags) 177 178 return nil 179 } 180 181 func resourceArmVirtualNetworkDelete(d *schema.ResourceData, meta interface{}) error { 182 vnetClient := meta.(*ArmClient).vnetClient 183 184 id, err := parseAzureResourceID(d.Id()) 185 if err != nil { 186 return err 187 } 188 resGroup := id.ResourceGroup 189 name := id.Path["virtualNetworks"] 190 191 _, err = vnetClient.Delete(resGroup, name, make(chan struct{})) 192 193 return err 194 } 195 196 func getVirtualNetworkProperties(d *schema.ResourceData) *network.VirtualNetworkPropertiesFormat { 197 // first; get address space prefixes: 198 prefixes := []string{} 199 for _, prefix := range d.Get("address_space").([]interface{}) { 200 prefixes = append(prefixes, prefix.(string)) 201 } 202 203 // then; the dns servers: 204 dnses := []string{} 205 for _, dns := range d.Get("dns_servers").([]interface{}) { 206 dnses = append(dnses, dns.(string)) 207 } 208 209 // then; the subnets: 210 subnets := []network.Subnet{} 211 if subs := d.Get("subnet").(*schema.Set); subs.Len() > 0 { 212 for _, subnet := range subs.List() { 213 subnet := subnet.(map[string]interface{}) 214 215 name := subnet["name"].(string) 216 prefix := subnet["address_prefix"].(string) 217 secGroup := subnet["security_group"].(string) 218 219 var subnetObj network.Subnet 220 subnetObj.Name = &name 221 subnetObj.Properties = &network.SubnetPropertiesFormat{} 222 subnetObj.Properties.AddressPrefix = &prefix 223 224 if secGroup != "" { 225 subnetObj.Properties.NetworkSecurityGroup = &network.SecurityGroup{ 226 ID: &secGroup, 227 } 228 } 229 230 subnets = append(subnets, subnetObj) 231 } 232 } 233 234 // finally; return the struct: 235 return &network.VirtualNetworkPropertiesFormat{ 236 AddressSpace: &network.AddressSpace{ 237 AddressPrefixes: &prefixes, 238 }, 239 DhcpOptions: &network.DhcpOptions{ 240 DNSServers: &dnses, 241 }, 242 Subnets: &subnets, 243 } 244 } 245 246 func resourceAzureSubnetHash(v interface{}) int { 247 m := v.(map[string]interface{}) 248 subnet := m["name"].(string) + m["address_prefix"].(string) 249 if securityGroup, present := m["security_group"]; present { 250 subnet = subnet + securityGroup.(string) 251 } 252 return hashcode.String(subnet) 253 } 254 255 func virtualNetworkStateRefreshFunc(client *ArmClient, resourceGroupName string, networkName string) resource.StateRefreshFunc { 256 return func() (interface{}, string, error) { 257 res, err := client.vnetClient.Get(resourceGroupName, networkName, "") 258 if err != nil { 259 return nil, "", fmt.Errorf("Error issuing read request in virtualNetworkStateRefreshFunc to Azure ARM for virtual network '%s' (RG: '%s'): %s", networkName, resourceGroupName, err) 260 } 261 262 return res, *res.Properties.ProvisioningState, nil 263 } 264 }