github.com/meteor/terraform@v0.6.15-0.20210412225145-79ec4bc057c6/builtin/providers/aws/resource_aws_autoscaling_schedule.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/service/autoscaling"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  const awsAutoscalingScheduleTimeLayout = "2006-01-02T15:04:05Z"
    15  
    16  func resourceAwsAutoscalingSchedule() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsAutoscalingScheduleCreate,
    19  		Read:   resourceAwsAutoscalingScheduleRead,
    20  		Update: resourceAwsAutoscalingScheduleCreate,
    21  		Delete: resourceAwsAutoscalingScheduleDelete,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"arn": {
    25  				Type:     schema.TypeString,
    26  				Computed: true,
    27  			},
    28  			"scheduled_action_name": {
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  			"autoscaling_group_name": {
    34  				Type:     schema.TypeString,
    35  				Required: true,
    36  				ForceNew: true,
    37  			},
    38  			"start_time": {
    39  				Type:         schema.TypeString,
    40  				Optional:     true,
    41  				Computed:     true,
    42  				ValidateFunc: validateASGScheduleTimestamp,
    43  			},
    44  			"end_time": {
    45  				Type:         schema.TypeString,
    46  				Optional:     true,
    47  				Computed:     true,
    48  				ValidateFunc: validateASGScheduleTimestamp,
    49  			},
    50  			"recurrence": {
    51  				Type:     schema.TypeString,
    52  				Optional: true,
    53  				Computed: true,
    54  			},
    55  			"min_size": {
    56  				Type:     schema.TypeInt,
    57  				Optional: true,
    58  				Computed: true,
    59  			},
    60  			"max_size": {
    61  				Type:     schema.TypeInt,
    62  				Optional: true,
    63  				Computed: true,
    64  			},
    65  			"desired_capacity": {
    66  				Type:     schema.TypeInt,
    67  				Optional: true,
    68  				Computed: true,
    69  			},
    70  		},
    71  	}
    72  }
    73  
    74  func resourceAwsAutoscalingScheduleCreate(d *schema.ResourceData, meta interface{}) error {
    75  	autoscalingconn := meta.(*AWSClient).autoscalingconn
    76  	params := &autoscaling.PutScheduledUpdateGroupActionInput{
    77  		AutoScalingGroupName: aws.String(d.Get("autoscaling_group_name").(string)),
    78  		ScheduledActionName:  aws.String(d.Get("scheduled_action_name").(string)),
    79  	}
    80  
    81  	if attr, ok := d.GetOk("start_time"); ok {
    82  		t, err := time.Parse(awsAutoscalingScheduleTimeLayout, attr.(string))
    83  		if err != nil {
    84  			return fmt.Errorf("Error Parsing AWS Autoscaling Group Schedule Start Time: %s", err.Error())
    85  		}
    86  		params.StartTime = aws.Time(t)
    87  	}
    88  
    89  	if attr, ok := d.GetOk("end_time"); ok {
    90  		t, err := time.Parse(awsAutoscalingScheduleTimeLayout, attr.(string))
    91  		if err != nil {
    92  			return fmt.Errorf("Error Parsing AWS Autoscaling Group Schedule End Time: %s", err.Error())
    93  		}
    94  		params.EndTime = aws.Time(t)
    95  	}
    96  
    97  	if attr, ok := d.GetOk("recurrence"); ok {
    98  		params.Recurrence = aws.String(attr.(string))
    99  	}
   100  
   101  	// Scheduled actions don't need to set all three size parameters. For example,
   102  	// you may want to change the min or max without also forcing an immediate
   103  	// resize by changing a desired_capacity that may have changed due to other
   104  	// autoscaling rules. Since Terraform doesn't have a great pattern for
   105  	// differentiating between 0 and unset fields, we accept "-1" to mean "don't
   106  	// include this parameter in the action".
   107  	minSize := int64(d.Get("min_size").(int))
   108  	maxSize := int64(d.Get("max_size").(int))
   109  	desiredCapacity := int64(d.Get("desired_capacity").(int))
   110  	if minSize != -1 {
   111  		params.MinSize = aws.Int64(minSize)
   112  	}
   113  	if maxSize != -1 {
   114  		params.MaxSize = aws.Int64(maxSize)
   115  	}
   116  	if desiredCapacity != -1 {
   117  		params.DesiredCapacity = aws.Int64(desiredCapacity)
   118  	}
   119  
   120  	log.Printf("[INFO] Creating Autoscaling Scheduled Action: %s", d.Get("scheduled_action_name").(string))
   121  	_, err := autoscalingconn.PutScheduledUpdateGroupAction(params)
   122  	if err != nil {
   123  		return fmt.Errorf("Error Creating Autoscaling Scheduled Action: %s", err.Error())
   124  	}
   125  
   126  	d.SetId(d.Get("scheduled_action_name").(string))
   127  
   128  	return resourceAwsAutoscalingScheduleRead(d, meta)
   129  }
   130  
   131  func resourceAwsAutoscalingScheduleRead(d *schema.ResourceData, meta interface{}) error {
   132  	sa, err, exists := resourceAwsASGScheduledActionRetrieve(d, meta)
   133  	if err != nil {
   134  		return err
   135  	}
   136  
   137  	if !exists {
   138  		log.Printf("Error retrieving Autoscaling Scheduled Actions. Removing from state")
   139  		d.SetId("")
   140  		return nil
   141  	}
   142  
   143  	d.Set("autoscaling_group_name", sa.AutoScalingGroupName)
   144  	d.Set("arn", sa.ScheduledActionARN)
   145  
   146  	if sa.MinSize == nil {
   147  		d.Set("min_size", -1)
   148  	} else {
   149  		d.Set("min_size", sa.MinSize)
   150  	}
   151  	if sa.MaxSize == nil {
   152  		d.Set("max_size", -1)
   153  	} else {
   154  		d.Set("max_size", sa.MaxSize)
   155  	}
   156  	if sa.DesiredCapacity == nil {
   157  		d.Set("desired_capacity", -1)
   158  	} else {
   159  		d.Set("desired_capacity", sa.DesiredCapacity)
   160  	}
   161  
   162  	d.Set("recurrence", sa.Recurrence)
   163  
   164  	if sa.StartTime != nil {
   165  		d.Set("start_time", sa.StartTime.Format(awsAutoscalingScheduleTimeLayout))
   166  	}
   167  
   168  	if sa.EndTime != nil {
   169  		d.Set("end_time", sa.EndTime.Format(awsAutoscalingScheduleTimeLayout))
   170  	}
   171  
   172  	return nil
   173  }
   174  
   175  func resourceAwsAutoscalingScheduleDelete(d *schema.ResourceData, meta interface{}) error {
   176  	autoscalingconn := meta.(*AWSClient).autoscalingconn
   177  
   178  	params := &autoscaling.DeleteScheduledActionInput{
   179  		AutoScalingGroupName: aws.String(d.Get("autoscaling_group_name").(string)),
   180  		ScheduledActionName:  aws.String(d.Id()),
   181  	}
   182  
   183  	log.Printf("[INFO] Deleting Autoscaling Scheduled Action: %s", d.Id())
   184  	_, err := autoscalingconn.DeleteScheduledAction(params)
   185  	if err != nil {
   186  		return fmt.Errorf("Error deleting Autoscaling Scheduled Action: %s", err.Error())
   187  	}
   188  
   189  	return nil
   190  }
   191  
   192  func resourceAwsASGScheduledActionRetrieve(d *schema.ResourceData, meta interface{}) (*autoscaling.ScheduledUpdateGroupAction, error, bool) {
   193  	autoscalingconn := meta.(*AWSClient).autoscalingconn
   194  
   195  	params := &autoscaling.DescribeScheduledActionsInput{
   196  		AutoScalingGroupName: aws.String(d.Get("autoscaling_group_name").(string)),
   197  		ScheduledActionNames: []*string{aws.String(d.Id())},
   198  	}
   199  
   200  	log.Printf("[INFO] Describing Autoscaling Scheduled Action: %+v", params)
   201  	actions, err := autoscalingconn.DescribeScheduledActions(params)
   202  	if err != nil {
   203  		//A ValidationError here can mean that either the Schedule is missing OR the Autoscaling Group is missing
   204  		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "ValidationError" {
   205  			log.Printf("[WARNING] %s not found, removing from state", d.Id())
   206  			d.SetId("")
   207  
   208  			return nil, nil, false
   209  		}
   210  		return nil, fmt.Errorf("Error retrieving Autoscaling Scheduled Actions: %s", err), false
   211  	}
   212  
   213  	if len(actions.ScheduledUpdateGroupActions) != 1 ||
   214  		*actions.ScheduledUpdateGroupActions[0].ScheduledActionName != d.Id() {
   215  		return nil, nil, false
   216  	}
   217  
   218  	return actions.ScheduledUpdateGroupActions[0], nil, true
   219  }