github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_appautoscaling_target.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     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/applicationautoscaling"
    14  )
    15  
    16  func resourceAwsAppautoscalingTarget() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsAppautoscalingTargetCreate,
    19  		Read:   resourceAwsAppautoscalingTargetRead,
    20  		Delete: resourceAwsAppautoscalingTargetDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"max_capacity": {
    24  				Type:     schema.TypeInt,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  			"min_capacity": {
    29  				Type:     schema.TypeInt,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  			"resource_id": {
    34  				Type:     schema.TypeString,
    35  				Required: true,
    36  				ForceNew: true,
    37  			},
    38  			"role_arn": {
    39  				Type:     schema.TypeString,
    40  				Required: true,
    41  				ForceNew: true,
    42  			},
    43  			"scalable_dimension": {
    44  				Type:         schema.TypeString,
    45  				Required:     true,
    46  				ForceNew:     true,
    47  				ValidateFunc: validateAppautoscalingScalableDimension,
    48  			},
    49  			"service_namespace": {
    50  				Type:         schema.TypeString,
    51  				Required:     true,
    52  				ForceNew:     true,
    53  				ValidateFunc: validateAppautoscalingServiceNamespace,
    54  			},
    55  		},
    56  	}
    57  }
    58  
    59  func resourceAwsAppautoscalingTargetCreate(d *schema.ResourceData, meta interface{}) error {
    60  	conn := meta.(*AWSClient).appautoscalingconn
    61  
    62  	var targetOpts applicationautoscaling.RegisterScalableTargetInput
    63  
    64  	targetOpts.MaxCapacity = aws.Int64(int64(d.Get("max_capacity").(int)))
    65  	targetOpts.MinCapacity = aws.Int64(int64(d.Get("min_capacity").(int)))
    66  	targetOpts.ResourceId = aws.String(d.Get("resource_id").(string))
    67  	targetOpts.RoleARN = aws.String(d.Get("role_arn").(string))
    68  	targetOpts.ScalableDimension = aws.String(d.Get("scalable_dimension").(string))
    69  	targetOpts.ServiceNamespace = aws.String(d.Get("service_namespace").(string))
    70  
    71  	log.Printf("[DEBUG] Application autoscaling target create configuration %#v", targetOpts)
    72  	var err error
    73  	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
    74  		_, err = conn.RegisterScalableTarget(&targetOpts)
    75  
    76  		if err != nil {
    77  			if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "ValidationException" {
    78  				log.Printf("[DEBUG] Retrying creation of Application Autoscaling Scalable Target due to possible issues with IAM: %s", awsErr)
    79  				return resource.RetryableError(err)
    80  			}
    81  			return resource.NonRetryableError(err)
    82  		}
    83  
    84  		return nil
    85  	})
    86  	if err != nil {
    87  		return fmt.Errorf("Error creating application autoscaling target: %s", err)
    88  	}
    89  
    90  	d.SetId(d.Get("resource_id").(string))
    91  	log.Printf("[INFO] Application AutoScaling Target ID: %s", d.Id())
    92  
    93  	return resourceAwsAppautoscalingTargetRead(d, meta)
    94  }
    95  
    96  func resourceAwsAppautoscalingTargetRead(d *schema.ResourceData, meta interface{}) error {
    97  	conn := meta.(*AWSClient).appautoscalingconn
    98  
    99  	t, err := getAwsAppautoscalingTarget(d, conn)
   100  	if err != nil {
   101  		return err
   102  	}
   103  	if t == nil {
   104  		log.Printf("[INFO] Application AutoScaling Target %q not found", d.Id())
   105  		d.SetId("")
   106  		return nil
   107  	}
   108  
   109  	d.Set("max_capacity", t.MaxCapacity)
   110  	d.Set("min_capacity", t.MinCapacity)
   111  	d.Set("resource_id", t.ResourceId)
   112  	d.Set("role_arn", t.RoleARN)
   113  	d.Set("scalable_dimension", t.ScalableDimension)
   114  	d.Set("service_namespace", t.ServiceNamespace)
   115  
   116  	return nil
   117  }
   118  
   119  func resourceAwsAppautoscalingTargetDelete(d *schema.ResourceData, meta interface{}) error {
   120  	conn := meta.(*AWSClient).appautoscalingconn
   121  
   122  	t, err := getAwsAppautoscalingTarget(d, conn)
   123  	if err != nil {
   124  		return err
   125  	}
   126  	if t == nil {
   127  		log.Printf("[INFO] Application AutoScaling Target %q not found", d.Id())
   128  		d.SetId("")
   129  		return nil
   130  	}
   131  
   132  	log.Printf("[DEBUG] Application AutoScaling Target destroy: %#v", d.Id())
   133  	deleteOpts := applicationautoscaling.DeregisterScalableTargetInput{
   134  		ResourceId:        aws.String(d.Get("resource_id").(string)),
   135  		ServiceNamespace:  aws.String(d.Get("service_namespace").(string)),
   136  		ScalableDimension: aws.String(d.Get("scalable_dimension").(string)),
   137  	}
   138  
   139  	err = resource.Retry(5*time.Minute, func() *resource.RetryError {
   140  		if _, err := conn.DeregisterScalableTarget(&deleteOpts); err != nil {
   141  			if awserr, ok := err.(awserr.Error); ok {
   142  				// @TODO: We should do stuff here depending on the actual error returned
   143  				return resource.RetryableError(awserr)
   144  			}
   145  			// Non recognized error, no retry.
   146  			return resource.NonRetryableError(err)
   147  		}
   148  		// Successful delete
   149  		return nil
   150  	})
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
   156  		if t, _ = getAwsAppautoscalingTarget(d, conn); t != nil {
   157  			return resource.RetryableError(
   158  				fmt.Errorf("Application AutoScaling Target still exists"))
   159  		}
   160  		return nil
   161  	})
   162  }
   163  
   164  func getAwsAppautoscalingTarget(
   165  	d *schema.ResourceData,
   166  	conn *applicationautoscaling.ApplicationAutoScaling) (*applicationautoscaling.ScalableTarget, error) {
   167  
   168  	tgtName := d.Id()
   169  	describeOpts := applicationautoscaling.DescribeScalableTargetsInput{
   170  		ResourceIds:      []*string{aws.String(tgtName)},
   171  		ServiceNamespace: aws.String(d.Get("service_namespace").(string)),
   172  	}
   173  
   174  	log.Printf("[DEBUG] Application AutoScaling Target describe configuration: %#v", describeOpts)
   175  	describeTargets, err := conn.DescribeScalableTargets(&describeOpts)
   176  	if err != nil {
   177  		// @TODO: We should probably send something else back if we're trying to access an unknown Resource ID
   178  		// targetserr, ok := err.(awserr.Error)
   179  		// if ok && targetserr.Code() == ""
   180  		return nil, fmt.Errorf("Error retrieving Application AutoScaling Target: %s", err)
   181  	}
   182  
   183  	for idx, tgt := range describeTargets.ScalableTargets {
   184  		if *tgt.ResourceId == tgtName {
   185  			return describeTargets.ScalableTargets[idx], nil
   186  		}
   187  	}
   188  
   189  	return nil, nil
   190  }