github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/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: ignoreCaseStateFunc, 44 DiffSuppressFunc: ignoreCaseDiffSuppressFunc, 45 }, 46 47 "idle_timeout_in_minutes": { 48 Type: schema.TypeInt, 49 Optional: true, 50 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 51 value := v.(int) 52 if value < 4 || value > 30 { 53 errors = append(errors, fmt.Errorf( 54 "The idle timeout must be between 4 and 30 minutes")) 55 } 56 return 57 }, 58 }, 59 60 "domain_name_label": { 61 Type: schema.TypeString, 62 Optional: true, 63 ValidateFunc: validatePublicIpDomainNameLabel, 64 }, 65 66 "reverse_fqdn": { 67 Type: schema.TypeString, 68 Optional: true, 69 }, 70 71 "fqdn": { 72 Type: schema.TypeString, 73 Computed: true, 74 }, 75 76 "ip_address": { 77 Type: schema.TypeString, 78 Computed: true, 79 }, 80 81 "tags": tagsSchema(), 82 }, 83 } 84 } 85 86 func resourceArmPublicIpCreate(d *schema.ResourceData, meta interface{}) error { 87 client := meta.(*ArmClient) 88 publicIPClient := client.publicIPClient 89 90 log.Printf("[INFO] preparing arguments for Azure ARM Public IP creation.") 91 92 name := d.Get("name").(string) 93 location := d.Get("location").(string) 94 resGroup := d.Get("resource_group_name").(string) 95 tags := d.Get("tags").(map[string]interface{}) 96 97 properties := network.PublicIPAddressPropertiesFormat{ 98 PublicIPAllocationMethod: network.IPAllocationMethod(d.Get("public_ip_address_allocation").(string)), 99 } 100 101 dnl, hasDnl := d.GetOk("domain_name_label") 102 rfqdn, hasRfqdn := d.GetOk("reverse_fqdn") 103 104 if hasDnl || hasRfqdn { 105 dnsSettings := network.PublicIPAddressDNSSettings{} 106 107 if hasRfqdn { 108 reverse_fqdn := rfqdn.(string) 109 dnsSettings.ReverseFqdn = &reverse_fqdn 110 } 111 112 if hasDnl { 113 domain_name_label := dnl.(string) 114 dnsSettings.DomainNameLabel = &domain_name_label 115 116 } 117 118 properties.DNSSettings = &dnsSettings 119 } 120 121 if v, ok := d.GetOk("idle_timeout_in_minutes"); ok { 122 idle_timeout := int32(v.(int)) 123 properties.IdleTimeoutInMinutes = &idle_timeout 124 } 125 126 publicIp := network.PublicIPAddress{ 127 Name: &name, 128 Location: &location, 129 PublicIPAddressPropertiesFormat: &properties, 130 Tags: expandTags(tags), 131 } 132 133 _, error := publicIPClient.CreateOrUpdate(resGroup, name, publicIp, make(chan struct{})) 134 err := <-error 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 _, error := publicIPClient.Delete(resGroup, name, make(chan struct{})) 200 err = <-error 201 202 return err 203 } 204 205 func validatePublicIpAllocation(v interface{}, k string) (ws []string, errors []error) { 206 value := strings.ToLower(v.(string)) 207 allocations := map[string]bool{ 208 "static": true, 209 "dynamic": true, 210 } 211 212 if !allocations[value] { 213 errors = append(errors, fmt.Errorf("Public IP Allocation can only be Static of Dynamic")) 214 } 215 return 216 } 217 218 func validatePublicIpDomainNameLabel(v interface{}, k string) (ws []string, errors []error) { 219 value := v.(string) 220 if !regexp.MustCompile(`^[a-z0-9-]+$`).MatchString(value) { 221 errors = append(errors, fmt.Errorf( 222 "only alphanumeric characters and hyphens allowed in %q: %q", 223 k, value)) 224 } 225 226 if len(value) > 61 { 227 errors = append(errors, fmt.Errorf( 228 "%q cannot be longer than 61 characters: %q", k, value)) 229 } 230 231 if len(value) == 0 { 232 errors = append(errors, fmt.Errorf( 233 "%q cannot be an empty string: %q", k, value)) 234 } 235 if regexp.MustCompile(`-$`).MatchString(value) { 236 errors = append(errors, fmt.Errorf( 237 "%q cannot end with a hyphen: %q", k, value)) 238 } 239 240 return 241 }