github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/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 }