github.com/aspring/terraform@v0.8.2-0.20161216122603-6a8619a5db2e/builtin/providers/azurerm/resource_arm_public_ip.go (about) 1 package azurerm 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 "regexp" 8 "strings" 9 10 "github.com/Azure/azure-sdk-for-go/arm/network" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceArmPublicIp() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceArmPublicIpCreate, 17 Read: resourceArmPublicIpRead, 18 Update: resourceArmPublicIpCreate, 19 Delete: resourceArmPublicIpDelete, 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 "location": locationSchema(), 32 33 "resource_group_name": { 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: true, 37 }, 38 39 "public_ip_address_allocation": { 40 Type: schema.TypeString, 41 Required: true, 42 ValidateFunc: validatePublicIpAllocation, 43 StateFunc: func(val interface{}) string { 44 return strings.ToLower(val.(string)) 45 }, 46 }, 47 48 "idle_timeout_in_minutes": { 49 Type: schema.TypeInt, 50 Optional: true, 51 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 52 value := v.(int) 53 if value < 4 || value > 30 { 54 errors = append(errors, fmt.Errorf( 55 "The idle timeout must be between 4 and 30 minutes")) 56 } 57 return 58 }, 59 }, 60 61 "domain_name_label": { 62 Type: schema.TypeString, 63 Optional: true, 64 ValidateFunc: validatePublicIpDomainNameLabel, 65 }, 66 67 "reverse_fqdn": { 68 Type: schema.TypeString, 69 Optional: true, 70 }, 71 72 "fqdn": { 73 Type: schema.TypeString, 74 Computed: true, 75 }, 76 77 "ip_address": { 78 Type: schema.TypeString, 79 Computed: true, 80 }, 81 82 "tags": tagsSchema(), 83 }, 84 } 85 } 86 87 func resourceArmPublicIpCreate(d *schema.ResourceData, meta interface{}) error { 88 client := meta.(*ArmClient) 89 publicIPClient := client.publicIPClient 90 91 log.Printf("[INFO] preparing arguments for Azure ARM Public IP creation.") 92 93 name := d.Get("name").(string) 94 location := d.Get("location").(string) 95 resGroup := d.Get("resource_group_name").(string) 96 tags := d.Get("tags").(map[string]interface{}) 97 98 properties := network.PublicIPAddressPropertiesFormat{ 99 PublicIPAllocationMethod: network.IPAllocationMethod(d.Get("public_ip_address_allocation").(string)), 100 } 101 102 dnl, hasDnl := d.GetOk("domain_name_label") 103 rfqdn, hasRfqdn := d.GetOk("reverse_fqdn") 104 105 if hasDnl || hasRfqdn { 106 dnsSettings := network.PublicIPAddressDNSSettings{} 107 108 if hasRfqdn { 109 reverse_fqdn := rfqdn.(string) 110 dnsSettings.ReverseFqdn = &reverse_fqdn 111 } 112 113 if hasDnl { 114 domain_name_label := dnl.(string) 115 dnsSettings.DomainNameLabel = &domain_name_label 116 117 } 118 119 properties.DNSSettings = &dnsSettings 120 } 121 122 if v, ok := d.GetOk("idle_timeout_in_minutes"); ok { 123 idle_timeout := int32(v.(int)) 124 properties.IdleTimeoutInMinutes = &idle_timeout 125 } 126 127 publicIp := network.PublicIPAddress{ 128 Name: &name, 129 Location: &location, 130 PublicIPAddressPropertiesFormat: &properties, 131 Tags: expandTags(tags), 132 } 133 134 _, err := publicIPClient.CreateOrUpdate(resGroup, name, publicIp, make(chan struct{})) 135 if err != nil { 136 return err 137 } 138 139 read, err := publicIPClient.Get(resGroup, name, "") 140 if err != nil { 141 return err 142 } 143 if read.ID == nil { 144 return fmt.Errorf("Cannot read Public IP %s (resource group %s) ID", name, resGroup) 145 } 146 147 d.SetId(*read.ID) 148 149 return resourceArmPublicIpRead(d, meta) 150 } 151 152 func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error { 153 publicIPClient := meta.(*ArmClient).publicIPClient 154 155 id, err := parseAzureResourceID(d.Id()) 156 if err != nil { 157 return err 158 } 159 resGroup := id.ResourceGroup 160 name := id.Path["publicIPAddresses"] 161 162 resp, err := publicIPClient.Get(resGroup, name, "") 163 if err != nil { 164 if resp.StatusCode == http.StatusNotFound { 165 d.SetId("") 166 return nil 167 } 168 return fmt.Errorf("Error making Read request on Azure public ip %s: %s", name, err) 169 } 170 171 d.Set("resource_group_name", resGroup) 172 d.Set("location", resp.Location) 173 d.Set("name", resp.Name) 174 d.Set("public_ip_address_allocation", strings.ToLower(string(resp.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod))) 175 176 if resp.PublicIPAddressPropertiesFormat.DNSSettings != nil && resp.PublicIPAddressPropertiesFormat.DNSSettings.Fqdn != nil && *resp.PublicIPAddressPropertiesFormat.DNSSettings.Fqdn != "" { 177 d.Set("fqdn", resp.PublicIPAddressPropertiesFormat.DNSSettings.Fqdn) 178 } 179 180 if resp.PublicIPAddressPropertiesFormat.IPAddress != nil && *resp.PublicIPAddressPropertiesFormat.IPAddress != "" { 181 d.Set("ip_address", resp.PublicIPAddressPropertiesFormat.IPAddress) 182 } 183 184 flattenAndSetTags(d, resp.Tags) 185 186 return nil 187 } 188 189 func resourceArmPublicIpDelete(d *schema.ResourceData, meta interface{}) error { 190 publicIPClient := meta.(*ArmClient).publicIPClient 191 192 id, err := parseAzureResourceID(d.Id()) 193 if err != nil { 194 return err 195 } 196 resGroup := id.ResourceGroup 197 name := id.Path["publicIPAddresses"] 198 199 _, err = publicIPClient.Delete(resGroup, name, make(chan struct{})) 200 201 return err 202 } 203 204 func validatePublicIpAllocation(v interface{}, k string) (ws []string, errors []error) { 205 value := strings.ToLower(v.(string)) 206 allocations := map[string]bool{ 207 "static": true, 208 "dynamic": true, 209 } 210 211 if !allocations[value] { 212 errors = append(errors, fmt.Errorf("Public IP Allocation can only be Static of Dynamic")) 213 } 214 return 215 } 216 217 func validatePublicIpDomainNameLabel(v interface{}, k string) (ws []string, errors []error) { 218 value := v.(string) 219 if !regexp.MustCompile(`^[a-z0-9-]+$`).MatchString(value) { 220 errors = append(errors, fmt.Errorf( 221 "only alphanumeric characters and hyphens allowed in %q: %q", 222 k, value)) 223 } 224 225 if len(value) > 61 { 226 errors = append(errors, fmt.Errorf( 227 "%q cannot be longer than 61 characters: %q", k, value)) 228 } 229 230 if len(value) == 0 { 231 errors = append(errors, fmt.Errorf( 232 "%q cannot be an empty string: %q", k, value)) 233 } 234 if regexp.MustCompile(`-$`).MatchString(value) { 235 errors = append(errors, fmt.Errorf( 236 "%q cannot end with a hyphen: %q", k, value)) 237 } 238 239 return 240 }