github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_route53_health_check.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/aws/awserr" 13 "github.com/aws/aws-sdk-go/service/route53" 14 ) 15 16 func resourceAwsRoute53HealthCheck() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsRoute53HealthCheckCreate, 19 Read: resourceAwsRoute53HealthCheckRead, 20 Update: resourceAwsRoute53HealthCheckUpdate, 21 Delete: resourceAwsRoute53HealthCheckDelete, 22 Importer: &schema.ResourceImporter{ 23 State: schema.ImportStatePassthrough, 24 }, 25 26 Schema: map[string]*schema.Schema{ 27 "type": &schema.Schema{ 28 Type: schema.TypeString, 29 Required: true, 30 ForceNew: true, 31 StateFunc: func(val interface{}) string { 32 return strings.ToUpper(val.(string)) 33 }, 34 }, 35 "failure_threshold": &schema.Schema{ 36 Type: schema.TypeInt, 37 Optional: true, 38 }, 39 "request_interval": &schema.Schema{ 40 Type: schema.TypeInt, 41 Optional: true, 42 ForceNew: true, // todo this should be updateable but the awslabs route53 service doesnt have the ability 43 }, 44 "ip_address": &schema.Schema{ 45 Type: schema.TypeString, 46 Optional: true, 47 ForceNew: true, 48 }, 49 "fqdn": &schema.Schema{ 50 Type: schema.TypeString, 51 Optional: true, 52 }, 53 "port": &schema.Schema{ 54 Type: schema.TypeInt, 55 Optional: true, 56 }, 57 58 "invert_healthcheck": &schema.Schema{ 59 Type: schema.TypeBool, 60 Optional: true, 61 }, 62 63 "resource_path": &schema.Schema{ 64 Type: schema.TypeString, 65 Optional: true, 66 }, 67 68 "search_string": &schema.Schema{ 69 Type: schema.TypeString, 70 Optional: true, 71 }, 72 73 "measure_latency": &schema.Schema{ 74 Type: schema.TypeBool, 75 Optional: true, 76 Default: false, 77 ForceNew: true, 78 }, 79 80 "child_healthchecks": &schema.Schema{ 81 Type: schema.TypeSet, 82 Elem: &schema.Schema{Type: schema.TypeString}, 83 Optional: true, 84 Set: schema.HashString, 85 }, 86 "child_health_threshold": &schema.Schema{ 87 Type: schema.TypeInt, 88 Optional: true, 89 ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { 90 value := v.(int) 91 if value > 256 { 92 es = append(es, fmt.Errorf( 93 "Child HealthThreshold cannot be more than 256")) 94 } 95 return 96 }, 97 }, 98 99 "cloudwatch_alarm_name": &schema.Schema{ 100 Type: schema.TypeString, 101 Optional: true, 102 }, 103 104 "cloudwatch_alarm_region": &schema.Schema{ 105 Type: schema.TypeString, 106 Optional: true, 107 }, 108 109 "insufficient_data_health_status": &schema.Schema{ 110 Type: schema.TypeString, 111 Optional: true, 112 }, 113 "reference_name": &schema.Schema{ 114 Type: schema.TypeString, 115 Optional: true, 116 ForceNew: true, 117 }, 118 "enable_sni": &schema.Schema{ 119 Type: schema.TypeBool, 120 Optional: true, 121 Computed: true, 122 }, 123 124 "tags": tagsSchema(), 125 }, 126 } 127 } 128 129 func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{}) error { 130 conn := meta.(*AWSClient).r53conn 131 132 updateHealthCheck := &route53.UpdateHealthCheckInput{ 133 HealthCheckId: aws.String(d.Id()), 134 } 135 136 if d.HasChange("failure_threshold") { 137 updateHealthCheck.FailureThreshold = aws.Int64(int64(d.Get("failure_threshold").(int))) 138 } 139 140 if d.HasChange("fqdn") { 141 updateHealthCheck.FullyQualifiedDomainName = aws.String(d.Get("fqdn").(string)) 142 } 143 144 if d.HasChange("port") { 145 updateHealthCheck.Port = aws.Int64(int64(d.Get("port").(int))) 146 } 147 148 if d.HasChange("resource_path") { 149 updateHealthCheck.ResourcePath = aws.String(d.Get("resource_path").(string)) 150 } 151 152 if d.HasChange("invert_healthcheck") { 153 updateHealthCheck.Inverted = aws.Bool(d.Get("invert_healthcheck").(bool)) 154 } 155 156 if d.HasChange("child_healthchecks") { 157 updateHealthCheck.ChildHealthChecks = expandStringList(d.Get("child_healthchecks").(*schema.Set).List()) 158 159 } 160 if d.HasChange("child_health_threshold") { 161 updateHealthCheck.HealthThreshold = aws.Int64(int64(d.Get("child_health_threshold").(int))) 162 } 163 164 if d.HasChange("search_string") { 165 updateHealthCheck.SearchString = aws.String(d.Get("search_string").(string)) 166 } 167 168 if d.HasChange("cloudwatch_alarm_name") || d.HasChange("cloudwatch_alarm_region") { 169 cloudwatchAlarm := &route53.AlarmIdentifier{ 170 Name: aws.String(d.Get("cloudwatch_alarm_name").(string)), 171 Region: aws.String(d.Get("cloudwatch_alarm_region").(string)), 172 } 173 174 updateHealthCheck.AlarmIdentifier = cloudwatchAlarm 175 } 176 177 if d.HasChange("insufficient_data_health_status") { 178 updateHealthCheck.InsufficientDataHealthStatus = aws.String(d.Get("insufficient_data_health_status").(string)) 179 } 180 181 if d.HasChange("enable_sni") { 182 updateHealthCheck.EnableSNI = aws.Bool(d.Get("enable_sni").(bool)) 183 } 184 185 _, err := conn.UpdateHealthCheck(updateHealthCheck) 186 if err != nil { 187 return err 188 } 189 190 if err := setTagsR53(conn, d, "healthcheck"); err != nil { 191 return err 192 } 193 194 return resourceAwsRoute53HealthCheckRead(d, meta) 195 } 196 197 func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{}) error { 198 conn := meta.(*AWSClient).r53conn 199 200 healthConfig := &route53.HealthCheckConfig{ 201 Type: aws.String(d.Get("type").(string)), 202 } 203 204 if v, ok := d.GetOk("request_interval"); ok { 205 healthConfig.RequestInterval = aws.Int64(int64(v.(int))) 206 } 207 208 if v, ok := d.GetOk("failure_threshold"); ok { 209 healthConfig.FailureThreshold = aws.Int64(int64(v.(int))) 210 } 211 212 if v, ok := d.GetOk("fqdn"); ok { 213 healthConfig.FullyQualifiedDomainName = aws.String(v.(string)) 214 } 215 216 if v, ok := d.GetOk("search_string"); ok { 217 healthConfig.SearchString = aws.String(v.(string)) 218 } 219 220 if v, ok := d.GetOk("ip_address"); ok { 221 healthConfig.IPAddress = aws.String(v.(string)) 222 } 223 224 if v, ok := d.GetOk("port"); ok { 225 healthConfig.Port = aws.Int64(int64(v.(int))) 226 } 227 228 if v, ok := d.GetOk("resource_path"); ok { 229 healthConfig.ResourcePath = aws.String(v.(string)) 230 } 231 232 if *healthConfig.Type != route53.HealthCheckTypeCalculated && *healthConfig.Type != route53.HealthCheckTypeCloudwatchMetric { 233 if v, ok := d.GetOk("measure_latency"); ok { 234 healthConfig.MeasureLatency = aws.Bool(v.(bool)) 235 } 236 } 237 238 if v, ok := d.GetOk("invert_healthcheck"); ok { 239 healthConfig.Inverted = aws.Bool(v.(bool)) 240 } 241 242 if v, ok := d.GetOk("enable_sni"); ok { 243 healthConfig.EnableSNI = aws.Bool(v.(bool)) 244 } 245 246 if *healthConfig.Type == route53.HealthCheckTypeCalculated { 247 if v, ok := d.GetOk("child_healthchecks"); ok { 248 healthConfig.ChildHealthChecks = expandStringList(v.(*schema.Set).List()) 249 } 250 251 if v, ok := d.GetOk("child_health_threshold"); ok { 252 healthConfig.HealthThreshold = aws.Int64(int64(v.(int))) 253 } 254 } 255 256 if *healthConfig.Type == route53.HealthCheckTypeCloudwatchMetric { 257 cloudwatchAlarmIdentifier := &route53.AlarmIdentifier{} 258 259 if v, ok := d.GetOk("cloudwatch_alarm_name"); ok { 260 cloudwatchAlarmIdentifier.Name = aws.String(v.(string)) 261 } 262 263 if v, ok := d.GetOk("cloudwatch_alarm_region"); ok { 264 cloudwatchAlarmIdentifier.Region = aws.String(v.(string)) 265 } 266 267 healthConfig.AlarmIdentifier = cloudwatchAlarmIdentifier 268 269 if v, ok := d.GetOk("insufficient_data_health_status"); ok { 270 healthConfig.InsufficientDataHealthStatus = aws.String(v.(string)) 271 } 272 } 273 274 callerRef := resource.UniqueId() 275 if v, ok := d.GetOk("reference_name"); ok { 276 callerRef = fmt.Sprintf("%s-%s", v.(string), callerRef) 277 } 278 279 input := &route53.CreateHealthCheckInput{ 280 CallerReference: aws.String(callerRef), 281 HealthCheckConfig: healthConfig, 282 } 283 284 resp, err := conn.CreateHealthCheck(input) 285 286 if err != nil { 287 return err 288 } 289 290 d.SetId(*resp.HealthCheck.Id) 291 292 if err := setTagsR53(conn, d, "healthcheck"); err != nil { 293 return err 294 } 295 296 return resourceAwsRoute53HealthCheckRead(d, meta) 297 } 298 299 func resourceAwsRoute53HealthCheckRead(d *schema.ResourceData, meta interface{}) error { 300 conn := meta.(*AWSClient).r53conn 301 302 read, err := conn.GetHealthCheck(&route53.GetHealthCheckInput{HealthCheckId: aws.String(d.Id())}) 303 if err != nil { 304 if r53err, ok := err.(awserr.Error); ok && r53err.Code() == "NoSuchHealthCheck" { 305 d.SetId("") 306 return nil 307 308 } 309 return err 310 } 311 312 if read == nil { 313 return nil 314 } 315 316 updated := read.HealthCheck.HealthCheckConfig 317 d.Set("type", updated.Type) 318 d.Set("failure_threshold", updated.FailureThreshold) 319 d.Set("request_interval", updated.RequestInterval) 320 d.Set("fqdn", updated.FullyQualifiedDomainName) 321 d.Set("search_string", updated.SearchString) 322 d.Set("ip_address", updated.IPAddress) 323 d.Set("port", updated.Port) 324 d.Set("resource_path", updated.ResourcePath) 325 d.Set("measure_latency", updated.MeasureLatency) 326 d.Set("invert_healthcheck", updated.Inverted) 327 d.Set("child_healthchecks", updated.ChildHealthChecks) 328 d.Set("child_health_threshold", updated.HealthThreshold) 329 d.Set("insufficient_data_health_status", updated.InsufficientDataHealthStatus) 330 d.Set("enable_sni", updated.EnableSNI) 331 332 if updated.AlarmIdentifier != nil { 333 d.Set("cloudwatch_alarm_name", updated.AlarmIdentifier.Name) 334 d.Set("cloudwatch_alarm_region", updated.AlarmIdentifier.Region) 335 } 336 337 // read the tags 338 req := &route53.ListTagsForResourceInput{ 339 ResourceId: aws.String(d.Id()), 340 ResourceType: aws.String("healthcheck"), 341 } 342 343 resp, err := conn.ListTagsForResource(req) 344 if err != nil { 345 return err 346 } 347 348 var tags []*route53.Tag 349 if resp.ResourceTagSet != nil { 350 tags = resp.ResourceTagSet.Tags 351 } 352 353 if err := d.Set("tags", tagsToMapR53(tags)); err != nil { 354 return err 355 } 356 357 return nil 358 } 359 360 func resourceAwsRoute53HealthCheckDelete(d *schema.ResourceData, meta interface{}) error { 361 conn := meta.(*AWSClient).r53conn 362 363 log.Printf("[DEBUG] Deleteing Route53 health check: %s", d.Id()) 364 _, err := conn.DeleteHealthCheck(&route53.DeleteHealthCheckInput{HealthCheckId: aws.String(d.Id())}) 365 if err != nil { 366 return err 367 } 368 369 return nil 370 } 371 372 func createChildHealthCheckList(s *schema.Set) (nl []*string) { 373 l := s.List() 374 for _, n := range l { 375 nl = append(nl, aws.String(n.(string))) 376 } 377 378 return nl 379 }