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