github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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": &schema.Schema{
    24  				Type:     schema.TypeInt,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  			"min_capacity": &schema.Schema{
    29  				Type:     schema.TypeInt,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  			"resource_id": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Required: true,
    36  				ForceNew: true,
    37  			},
    38  			"role_arn": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Required: true,
    41  				ForceNew: true,
    42  			},
    43  			"scalable_dimension": &schema.Schema{
    44  				Type:         schema.TypeString,
    45  				Required:     true,
    46  				ForceNew:     true,
    47  				ValidateFunc: validateAppautoscalingScalableDimension,
    48  			},
    49  			"service_namespace": &schema.Schema{
    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  // Updating Target is not supported
   120  // func getAwsAppautoscalingTargetUpdate(d *schema.ResourceData, meta interface{}) error {
   121  //   conn := meta.(*AWSClient).appautoscalingconn
   122  
   123  // }
   124  
   125  func resourceAwsAppautoscalingTargetDelete(d *schema.ResourceData, meta interface{}) error {
   126  	conn := meta.(*AWSClient).appautoscalingconn
   127  
   128  	t, err := getAwsAppautoscalingTarget(d, conn)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	if t == nil {
   133  		log.Printf("[INFO] Application AutoScaling Target %q not found", d.Id())
   134  		d.SetId("")
   135  		return nil
   136  	}
   137  
   138  	log.Printf("[DEBUG] Application AutoScaling Target destroy: %#v", d.Id())
   139  	deleteOpts := applicationautoscaling.DeregisterScalableTargetInput{
   140  		ResourceId:        aws.String(d.Get("resource_id").(string)),
   141  		ServiceNamespace:  aws.String(d.Get("service_namespace").(string)),
   142  		ScalableDimension: aws.String(d.Get("scalable_dimension").(string)),
   143  	}
   144  
   145  	err = resource.Retry(5*time.Minute, func() *resource.RetryError {
   146  		if _, err := conn.DeregisterScalableTarget(&deleteOpts); err != nil {
   147  			if awserr, ok := err.(awserr.Error); ok {
   148  				// @TODO: We should do stuff here depending on the actual error returned
   149  				return resource.RetryableError(awserr)
   150  			}
   151  			// Non recognized error, no retry.
   152  			return resource.NonRetryableError(err)
   153  		}
   154  		// Successful delete
   155  		return nil
   156  	})
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
   162  		if t, _ = getAwsAppautoscalingTarget(d, conn); t != nil {
   163  			return resource.RetryableError(
   164  				fmt.Errorf("Application AutoScaling Target still exists"))
   165  		}
   166  		return nil
   167  	})
   168  }
   169  
   170  func getAwsAppautoscalingTarget(
   171  	d *schema.ResourceData,
   172  	conn *applicationautoscaling.ApplicationAutoScaling) (*applicationautoscaling.ScalableTarget, error) {
   173  
   174  	tgtName := d.Id()
   175  	describeOpts := applicationautoscaling.DescribeScalableTargetsInput{
   176  		ResourceIds:      []*string{aws.String(tgtName)},
   177  		ServiceNamespace: aws.String(d.Get("service_namespace").(string)),
   178  	}
   179  
   180  	log.Printf("[DEBUG] Application AutoScaling Target describe configuration: %#v", describeOpts)
   181  	describeTargets, err := conn.DescribeScalableTargets(&describeOpts)
   182  	if err != nil {
   183  		// @TODO: We should probably send something else back if we're trying to access an unknown Resource ID
   184  		// targetserr, ok := err.(awserr.Error)
   185  		// if ok && targetserr.Code() == ""
   186  		return nil, fmt.Errorf("Error retrieving Application AutoScaling Target: %s", err)
   187  	}
   188  
   189  	for idx, tgt := range describeTargets.ScalableTargets {
   190  		if *tgt.ResourceId == tgtName {
   191  			return describeTargets.ScalableTargets[idx], nil
   192  		}
   193  	}
   194  
   195  	return nil, nil
   196  }