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