github.com/emc-cmd/terraform@v0.7.8-0.20161101145618-f16309630e7c/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 119 "tags": tagsSchema(), 120 }, 121 } 122 } 123 124 func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{}) error { 125 conn := meta.(*AWSClient).r53conn 126 127 updateHealthCheck := &route53.UpdateHealthCheckInput{ 128 HealthCheckId: aws.String(d.Id()), 129 } 130 131 if d.HasChange("failure_threshold") { 132 updateHealthCheck.FailureThreshold = aws.Int64(int64(d.Get("failure_threshold").(int))) 133 } 134 135 if d.HasChange("fqdn") { 136 updateHealthCheck.FullyQualifiedDomainName = aws.String(d.Get("fqdn").(string)) 137 } 138 139 if d.HasChange("port") { 140 updateHealthCheck.Port = aws.Int64(int64(d.Get("port").(int))) 141 } 142 143 if d.HasChange("resource_path") { 144 updateHealthCheck.ResourcePath = aws.String(d.Get("resource_path").(string)) 145 } 146 147 if d.HasChange("invert_healthcheck") { 148 updateHealthCheck.Inverted = aws.Bool(d.Get("invert_healthcheck").(bool)) 149 } 150 151 if d.HasChange("child_healthchecks") { 152 updateHealthCheck.ChildHealthChecks = expandStringList(d.Get("child_healthchecks").(*schema.Set).List()) 153 154 } 155 if d.HasChange("child_health_threshold") { 156 updateHealthCheck.HealthThreshold = aws.Int64(int64(d.Get("child_health_threshold").(int))) 157 } 158 159 if d.HasChange("search_string") { 160 updateHealthCheck.SearchString = aws.String(d.Get("search_string").(string)) 161 } 162 163 if d.HasChange("cloudwatch_alarm_name") || d.HasChange("cloudwatch_alarm_region") { 164 cloudwatchAlarm := &route53.AlarmIdentifier{ 165 Name: aws.String(d.Get("cloudwatch_alarm_name").(string)), 166 Region: aws.String(d.Get("cloudwatch_alarm_region").(string)), 167 } 168 169 updateHealthCheck.AlarmIdentifier = cloudwatchAlarm 170 } 171 172 if d.HasChange("insufficient_data_health_status") { 173 updateHealthCheck.InsufficientDataHealthStatus = aws.String(d.Get("insufficient_data_health_status").(string)) 174 } 175 176 _, err := conn.UpdateHealthCheck(updateHealthCheck) 177 if err != nil { 178 return err 179 } 180 181 if err := setTagsR53(conn, d, "healthcheck"); err != nil { 182 return err 183 } 184 185 return resourceAwsRoute53HealthCheckRead(d, meta) 186 } 187 188 func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{}) error { 189 conn := meta.(*AWSClient).r53conn 190 191 healthConfig := &route53.HealthCheckConfig{ 192 Type: aws.String(d.Get("type").(string)), 193 } 194 195 if v, ok := d.GetOk("request_interval"); ok { 196 healthConfig.RequestInterval = aws.Int64(int64(v.(int))) 197 } 198 199 if v, ok := d.GetOk("failure_threshold"); ok { 200 healthConfig.FailureThreshold = aws.Int64(int64(v.(int))) 201 } 202 203 if v, ok := d.GetOk("fqdn"); ok { 204 healthConfig.FullyQualifiedDomainName = aws.String(v.(string)) 205 } 206 207 if v, ok := d.GetOk("search_string"); ok { 208 healthConfig.SearchString = aws.String(v.(string)) 209 } 210 211 if v, ok := d.GetOk("ip_address"); ok { 212 healthConfig.IPAddress = aws.String(v.(string)) 213 } 214 215 if v, ok := d.GetOk("port"); ok { 216 healthConfig.Port = aws.Int64(int64(v.(int))) 217 } 218 219 if v, ok := d.GetOk("resource_path"); ok { 220 healthConfig.ResourcePath = aws.String(v.(string)) 221 } 222 223 if *healthConfig.Type != route53.HealthCheckTypeCalculated && *healthConfig.Type != route53.HealthCheckTypeCloudwatchMetric { 224 if v, ok := d.GetOk("measure_latency"); ok { 225 healthConfig.MeasureLatency = aws.Bool(v.(bool)) 226 } 227 } 228 229 if v, ok := d.GetOk("invert_healthcheck"); ok { 230 healthConfig.Inverted = aws.Bool(v.(bool)) 231 } 232 233 if *healthConfig.Type == route53.HealthCheckTypeCalculated { 234 if v, ok := d.GetOk("child_healthchecks"); ok { 235 healthConfig.ChildHealthChecks = expandStringList(v.(*schema.Set).List()) 236 } 237 238 if v, ok := d.GetOk("child_health_threshold"); ok { 239 healthConfig.HealthThreshold = aws.Int64(int64(v.(int))) 240 } 241 } 242 243 if *healthConfig.Type == route53.HealthCheckTypeCloudwatchMetric { 244 cloudwatchAlarmIdentifier := &route53.AlarmIdentifier{} 245 246 if v, ok := d.GetOk("cloudwatch_alarm_name"); ok { 247 cloudwatchAlarmIdentifier.Name = aws.String(v.(string)) 248 } 249 250 if v, ok := d.GetOk("cloudwatch_alarm_region"); ok { 251 cloudwatchAlarmIdentifier.Region = aws.String(v.(string)) 252 } 253 254 healthConfig.AlarmIdentifier = cloudwatchAlarmIdentifier 255 256 if v, ok := d.GetOk("insufficient_data_health_status"); ok { 257 healthConfig.InsufficientDataHealthStatus = aws.String(v.(string)) 258 } 259 } 260 261 callerRef := resource.UniqueId() 262 if v, ok := d.GetOk("reference_name"); ok { 263 callerRef = fmt.Sprintf("%s-%s", v.(string), callerRef) 264 } 265 266 input := &route53.CreateHealthCheckInput{ 267 CallerReference: aws.String(callerRef), 268 HealthCheckConfig: healthConfig, 269 } 270 271 resp, err := conn.CreateHealthCheck(input) 272 273 if err != nil { 274 return err 275 } 276 277 d.SetId(*resp.HealthCheck.Id) 278 279 if err := setTagsR53(conn, d, "healthcheck"); err != nil { 280 return err 281 } 282 283 return resourceAwsRoute53HealthCheckRead(d, meta) 284 } 285 286 func resourceAwsRoute53HealthCheckRead(d *schema.ResourceData, meta interface{}) error { 287 conn := meta.(*AWSClient).r53conn 288 289 read, err := conn.GetHealthCheck(&route53.GetHealthCheckInput{HealthCheckId: aws.String(d.Id())}) 290 if err != nil { 291 if r53err, ok := err.(awserr.Error); ok && r53err.Code() == "NoSuchHealthCheck" { 292 d.SetId("") 293 return nil 294 295 } 296 return err 297 } 298 299 if read == nil { 300 return nil 301 } 302 303 updated := read.HealthCheck.HealthCheckConfig 304 d.Set("type", updated.Type) 305 d.Set("failure_threshold", updated.FailureThreshold) 306 d.Set("request_interval", updated.RequestInterval) 307 d.Set("fqdn", updated.FullyQualifiedDomainName) 308 d.Set("search_string", updated.SearchString) 309 d.Set("ip_address", updated.IPAddress) 310 d.Set("port", updated.Port) 311 d.Set("resource_path", updated.ResourcePath) 312 d.Set("measure_latency", updated.MeasureLatency) 313 d.Set("invert_healthcheck", updated.Inverted) 314 d.Set("child_healthchecks", updated.ChildHealthChecks) 315 d.Set("child_health_threshold", updated.HealthThreshold) 316 d.Set("insufficient_data_health_status", updated.InsufficientDataHealthStatus) 317 318 if updated.AlarmIdentifier != nil { 319 d.Set("cloudwatch_alarm_name", updated.AlarmIdentifier.Name) 320 d.Set("cloudwatch_alarm_region", updated.AlarmIdentifier.Region) 321 } 322 323 // read the tags 324 req := &route53.ListTagsForResourceInput{ 325 ResourceId: aws.String(d.Id()), 326 ResourceType: aws.String("healthcheck"), 327 } 328 329 resp, err := conn.ListTagsForResource(req) 330 if err != nil { 331 return err 332 } 333 334 var tags []*route53.Tag 335 if resp.ResourceTagSet != nil { 336 tags = resp.ResourceTagSet.Tags 337 } 338 339 if err := d.Set("tags", tagsToMapR53(tags)); err != nil { 340 return err 341 } 342 343 return nil 344 } 345 346 func resourceAwsRoute53HealthCheckDelete(d *schema.ResourceData, meta interface{}) error { 347 conn := meta.(*AWSClient).r53conn 348 349 log.Printf("[DEBUG] Deleteing Route53 health check: %s", d.Id()) 350 _, err := conn.DeleteHealthCheck(&route53.DeleteHealthCheckInput{HealthCheckId: aws.String(d.Id())}) 351 if err != nil { 352 return err 353 } 354 355 return nil 356 } 357 358 func createChildHealthCheckList(s *schema.Set) (nl []*string) { 359 l := s.List() 360 for _, n := range l { 361 nl = append(nl, aws.String(n.(string))) 362 } 363 364 return nl 365 }