github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/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  			"name": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Optional: true,
    26  				Computed: true,
    27  				ForceNew: true,
    28  				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
    29  					// https://github.com/boto/botocore/blob/9f322b1/botocore/data/autoscaling/2011-01-01/service-2.json#L1862-L1873
    30  					value := v.(string)
    31  					if len(value) > 255 {
    32  						errors = append(errors, fmt.Errorf(
    33  							"%q cannot be longer than 255 characters", k))
    34  					}
    35  					return
    36  				},
    37  			},
    38  			"arn": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Computed: true,
    41  			},
    42  			"max_capacity": &schema.Schema{
    43  				Type:     schema.TypeInt,
    44  				Required: true,
    45  				ForceNew: true,
    46  			},
    47  			"min_capacity": &schema.Schema{
    48  				Type:     schema.TypeInt,
    49  				Required: true,
    50  				ForceNew: true,
    51  			},
    52  			"resource_id": &schema.Schema{
    53  				Type:     schema.TypeString,
    54  				Required: true,
    55  				ForceNew: true,
    56  			},
    57  			"role_arn": &schema.Schema{
    58  				Type:     schema.TypeString,
    59  				Required: true,
    60  				ForceNew: true,
    61  			},
    62  			"scalable_dimension": &schema.Schema{
    63  				Type:     schema.TypeString,
    64  				Optional: true,
    65  				Default:  "ecs:service:DesiredCount",
    66  				ForceNew: true,
    67  			},
    68  			"service_namespace": &schema.Schema{
    69  				Type:     schema.TypeString,
    70  				Optional: true,
    71  				Default:  "ecs",
    72  				ForceNew: true,
    73  			},
    74  		},
    75  	}
    76  }
    77  
    78  func resourceAwsAppautoscalingTargetCreate(d *schema.ResourceData, meta interface{}) error {
    79  	conn := meta.(*AWSClient).appautoscalingconn
    80  
    81  	var targetOpts applicationautoscaling.RegisterScalableTargetInput
    82  
    83  	targetOpts.MaxCapacity = aws.Int64(int64(d.Get("max_capacity").(int)))
    84  	targetOpts.MinCapacity = aws.Int64(int64(d.Get("min_capacity").(int)))
    85  	targetOpts.ResourceId = aws.String(d.Get("resource_id").(string))
    86  	targetOpts.RoleARN = aws.String(d.Get("role_arn").(string))
    87  	targetOpts.ScalableDimension = aws.String(d.Get("scalable_dimension").(string))
    88  	targetOpts.ServiceNamespace = aws.String(d.Get("service_namespace").(string))
    89  
    90  	log.Printf("[DEBUG] Application autoscaling target create configuration %#v", targetOpts)
    91  	var err error
    92  	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
    93  		_, err = conn.RegisterScalableTarget(&targetOpts)
    94  
    95  		if err != nil {
    96  			if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "ValidationException" {
    97  				log.Printf("[DEBUG] Retrying creation of Application Autoscaling Scalable Target due to possible issues with IAM: %s", awsErr)
    98  				return resource.RetryableError(err)
    99  			}
   100  			return resource.NonRetryableError(err)
   101  		}
   102  
   103  		return nil
   104  	})
   105  	if err != nil {
   106  		return fmt.Errorf("Error creating application autoscaling target: %s", err)
   107  	}
   108  
   109  	d.SetId(d.Get("resource_id").(string))
   110  	log.Printf("[INFO] Application AutoScaling Target ID: %s", d.Id())
   111  
   112  	return resourceAwsAppautoscalingTargetRead(d, meta)
   113  }
   114  
   115  func resourceAwsAppautoscalingTargetRead(d *schema.ResourceData, meta interface{}) error {
   116  	conn := meta.(*AWSClient).appautoscalingconn
   117  
   118  	t, err := getAwsAppautoscalingTarget(d, conn)
   119  	if err != nil {
   120  		return err
   121  	}
   122  	if t == nil {
   123  		log.Printf("[INFO] Application AutoScaling Target %q not found", d.Id())
   124  		d.SetId("")
   125  		return nil
   126  	}
   127  
   128  	d.Set("max_capacity", t.MaxCapacity)
   129  	d.Set("min_capacity", t.MinCapacity)
   130  	d.Set("resource_id", t.ResourceId)
   131  	d.Set("role_arn", t.RoleARN)
   132  	d.Set("scalable_dimension", t.ScalableDimension)
   133  	d.Set("service_namespace", t.ServiceNamespace)
   134  
   135  	return nil
   136  }
   137  
   138  // Updating Target is not supported
   139  // func getAwsAppautoscalingTargetUpdate(d *schema.ResourceData, meta interface{}) error {
   140  //   conn := meta.(*AWSClient).appautoscalingconn
   141  
   142  // }
   143  
   144  func resourceAwsAppautoscalingTargetDelete(d *schema.ResourceData, meta interface{}) error {
   145  	conn := meta.(*AWSClient).appautoscalingconn
   146  
   147  	t, err := getAwsAppautoscalingTarget(d, conn)
   148  	if err != nil {
   149  		return err
   150  	}
   151  	if t == nil {
   152  		log.Printf("[INFO] Application AutoScaling Target %q not found", d.Id())
   153  		d.SetId("")
   154  		return nil
   155  	}
   156  
   157  	log.Printf("[DEBUG] Application AutoScaling Target destroy: %#v", d.Id())
   158  	deleteOpts := applicationautoscaling.DeregisterScalableTargetInput{
   159  		ResourceId:        aws.String(d.Get("resource_id").(string)),
   160  		ServiceNamespace:  aws.String(d.Get("service_namespace").(string)),
   161  		ScalableDimension: aws.String(d.Get("scalable_dimension").(string)),
   162  	}
   163  
   164  	err = resource.Retry(5*time.Minute, func() *resource.RetryError {
   165  		if _, err := conn.DeregisterScalableTarget(&deleteOpts); err != nil {
   166  			if awserr, ok := err.(awserr.Error); ok {
   167  				// @TODO: We should do stuff here depending on the actual error returned
   168  				return resource.RetryableError(awserr)
   169  			}
   170  			// Non recognized error, no retry.
   171  			return resource.NonRetryableError(err)
   172  		}
   173  		// Successful delete
   174  		return nil
   175  	})
   176  	if err != nil {
   177  		return err
   178  	}
   179  
   180  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
   181  		if t, _ = getAwsAppautoscalingTarget(d, conn); t != nil {
   182  			return resource.RetryableError(
   183  				fmt.Errorf("Application AutoScaling Target still exists"))
   184  		}
   185  		return nil
   186  	})
   187  }
   188  
   189  func getAwsAppautoscalingTarget(
   190  	d *schema.ResourceData,
   191  	conn *applicationautoscaling.ApplicationAutoScaling) (*applicationautoscaling.ScalableTarget, error) {
   192  
   193  	tgtName := d.Id()
   194  	describeOpts := applicationautoscaling.DescribeScalableTargetsInput{
   195  		ResourceIds:      []*string{aws.String(tgtName)},
   196  		ServiceNamespace: aws.String(d.Get("service_namespace").(string)),
   197  	}
   198  
   199  	log.Printf("[DEBUG] Application AutoScaling Target describe configuration: %#v", describeOpts)
   200  	describeTargets, err := conn.DescribeScalableTargets(&describeOpts)
   201  	if err != nil {
   202  		// @TODO: We should probably send something else back if we're trying to access an unknown Resource ID
   203  		// targetserr, ok := err.(awserr.Error)
   204  		// if ok && targetserr.Code() == ""
   205  		return nil, fmt.Errorf("Error retrieving Application AutoScaling Target: %s", err)
   206  	}
   207  
   208  	for idx, tgt := range describeTargets.ScalableTargets {
   209  		if *tgt.ResourceId == tgtName {
   210  			return describeTargets.ScalableTargets[idx], nil
   211  		}
   212  	}
   213  
   214  	return nil, nil
   215  }