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  }