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