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