github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/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 _, err := publicIPClient.CreateOrUpdate(resGroup, name, publicIp, make(chan struct{})) 134 if err != nil { 135 return err 136 } 137 138 read, err := publicIPClient.Get(resGroup, name, "") 139 if err != nil { 140 return err 141 } 142 if read.ID == nil { 143 return fmt.Errorf("Cannot read Public IP %s (resource group %s) ID", name, resGroup) 144 } 145 146 d.SetId(*read.ID) 147 148 return resourceArmPublicIpRead(d, meta) 149 } 150 151 func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error { 152 publicIPClient := meta.(*ArmClient).publicIPClient 153 154 id, err := parseAzureResourceID(d.Id()) 155 if err != nil { 156 return err 157 } 158 resGroup := id.ResourceGroup 159 name := id.Path["publicIPAddresses"] 160 161 resp, err := publicIPClient.Get(resGroup, name, "") 162 if err != nil { 163 if resp.StatusCode == http.StatusNotFound { 164 d.SetId("") 165 return nil 166 } 167 return fmt.Errorf("Error making Read request on Azure public ip %s: %s", name, err) 168 } 169 170 d.Set("resource_group_name", resGroup) 171 d.Set("location", resp.Location) 172 d.Set("name", resp.Name) 173 d.Set("public_ip_address_allocation", strings.ToLower(string(resp.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod))) 174 175 if resp.PublicIPAddressPropertiesFormat.DNSSettings != nil && resp.PublicIPAddressPropertiesFormat.DNSSettings.Fqdn != nil && *resp.PublicIPAddressPropertiesFormat.DNSSettings.Fqdn != "" { 176 d.Set("fqdn", resp.PublicIPAddressPropertiesFormat.DNSSettings.Fqdn) 177 } 178 179 if resp.PublicIPAddressPropertiesFormat.IPAddress != nil && *resp.PublicIPAddressPropertiesFormat.IPAddress != "" { 180 d.Set("ip_address", resp.PublicIPAddressPropertiesFormat.IPAddress) 181 } 182 183 flattenAndSetTags(d, resp.Tags) 184 185 return nil 186 } 187 188 func resourceArmPublicIpDelete(d *schema.ResourceData, meta interface{}) error { 189 publicIPClient := meta.(*ArmClient).publicIPClient 190 191 id, err := parseAzureResourceID(d.Id()) 192 if err != nil { 193 return err 194 } 195 resGroup := id.ResourceGroup 196 name := id.Path["publicIPAddresses"] 197 198 _, err = publicIPClient.Delete(resGroup, name, make(chan struct{})) 199 200 return err 201 } 202 203 func validatePublicIpAllocation(v interface{}, k string) (ws []string, errors []error) { 204 value := strings.ToLower(v.(string)) 205 allocations := map[string]bool{ 206 "static": true, 207 "dynamic": true, 208 } 209 210 if !allocations[value] { 211 errors = append(errors, fmt.Errorf("Public IP Allocation can only be Static of Dynamic")) 212 } 213 return 214 } 215 216 func validatePublicIpDomainNameLabel(v interface{}, k string) (ws []string, errors []error) { 217 value := v.(string) 218 if !regexp.MustCompile(`^[a-z0-9-]+$`).MatchString(value) { 219 errors = append(errors, fmt.Errorf( 220 "only alphanumeric characters and hyphens allowed in %q: %q", 221 k, value)) 222 } 223 224 if len(value) > 61 { 225 errors = append(errors, fmt.Errorf( 226 "%q cannot be longer than 61 characters: %q", k, value)) 227 } 228 229 if len(value) == 0 { 230 errors = append(errors, fmt.Errorf( 231 "%q cannot be an empty string: %q", k, value)) 232 } 233 if regexp.MustCompile(`-$`).MatchString(value) { 234 errors = append(errors, fmt.Errorf( 235 "%q cannot end with a hyphen: %q", k, value)) 236 } 237 238 return 239 }