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 }