diff --git a/internal/services/automation/automation_schedule_resource.go b/internal/services/automation/automation_schedule_resource.go index e5666f0a7417..ee91d677ed02 100644 --- a/internal/services/automation/automation_schedule_resource.go +++ b/internal/services/automation/automation_schedule_resource.go @@ -31,9 +31,9 @@ import ( func resourceAutomationSchedule() *pluginsdk.Resource { return &pluginsdk.Resource{ - Create: resourceAutomationScheduleCreateUpdate, + Create: resourceAutomationScheduleCreate, Read: resourceAutomationScheduleRead, - Update: resourceAutomationScheduleCreateUpdate, + Update: resourceAutomationScheduleUpdate, Delete: resourceAutomationScheduleDelete, Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { @@ -211,7 +211,7 @@ func resourceAutomationSchedule() *pluginsdk.Resource { } } -func resourceAutomationScheduleCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { +func resourceAutomationScheduleCreate(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Automation.Schedule subscriptionId := meta.(*clients.Client).Account.SubscriptionId ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) @@ -221,19 +221,17 @@ func resourceAutomationScheduleCreateUpdate(d *pluginsdk.ResourceData, meta inte id := schedule.NewScheduleID(subscriptionId, d.Get("resource_group_name").(string), d.Get("automation_account_name").(string), d.Get("name").(string)) - if d.IsNewResource() { - existing, err := client.Get(ctx, id) - if err != nil { - if !response.WasNotFound(existing.HttpResponse) { - return fmt.Errorf("checking for presence of existing %s: %s", id, err) - } - } - + existing, err := client.Get(ctx, id) + if err != nil { if !response.WasNotFound(existing.HttpResponse) { - return tf.ImportAsExistsError("azurerm_automation_schedule", id.ID()) + return fmt.Errorf("checking for presence of existing %s: %v", id, err) } } + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_automation_schedule", id.ID()) + } + frequency := d.Get("frequency").(string) timeZone := d.Get("timezone").(string) description := d.Get("description").(string) @@ -285,7 +283,7 @@ func resourceAutomationScheduleCreateUpdate(d *pluginsdk.ResourceData, meta inte } if _, err := client.CreateOrUpdate(ctx, id, parameters); err != nil { - return err + return fmt.Errorf("creating %s: %+v", id, err) } d.SetId(id.ID()) @@ -293,6 +291,92 @@ func resourceAutomationScheduleCreateUpdate(d *pluginsdk.ResourceData, meta inte return resourceAutomationScheduleRead(d, meta) } +func resourceAutomationScheduleUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Automation.Schedule + subscriptionId := meta.(*clients.Client).Account.SubscriptionId + ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + log.Printf("[INFO] preparing arguments for AzureRM Automation Schedule update.") + + id := schedule.NewScheduleID(subscriptionId, d.Get("resource_group_name").(string), d.Get("automation_account_name").(string), d.Get("name").(string)) + + existing, err := client.Get(ctx, id) + if err != nil { + return fmt.Errorf("checking for presence of existing %s: %v", id, err) + + } + + if existing.Model == nil || existing.Model.Properties == nil { + return fmt.Errorf("reading existing properties of %s", id) + } + + parameters := schedule.ScheduleCreateOrUpdateParameters{ + Name: id.ScheduleName, + Properties: schedule.ScheduleCreateOrUpdateProperties{ + Frequency: pointer.From(existing.Model.Properties.Frequency), + Description: existing.Model.Properties.Description, + TimeZone: existing.Model.Properties.TimeZone, + }, + } + if d.HasChange("frequency") { + parameters.Properties.Frequency = schedule.ScheduleFrequency(d.Get("frequency").(string)) + } + + if d.HasChange("timezone") { + parameters.Properties.TimeZone = pointer.To(d.Get("timezone").(string)) + } + + if d.HasChange("description") { + parameters.Properties.Description = pointer.To(d.Get("description").(string)) + } + + parameters.Properties.StartTime = pointer.From(existing.Model.Properties.StartTime) + if d.HasChange("start_time") { + // start time can default to now + 7 (5 could be invalid by the time the API is called) + loc, err := time.LoadLocation(pointer.From(parameters.Properties.TimeZone)) + if err != nil { + return err + } + if v, ok := d.GetOk("start_time"); ok { + t, _ := time.Parse(time.RFC3339, v.(string)) // should be validated by the schema + duration := time.Duration(5) * time.Minute + if time.Until(t) < duration { + return fmt.Errorf("`start_time` is %q and should be at least %q in the future", t, duration) + } + + parameters.Properties.SetStartTimeAsTime(t.In(loc)) + } else { + parameters.Properties.SetStartTimeAsTime(time.Now().In(loc).Add(time.Duration(7) * time.Minute)) + } + } + + parameters.Properties.ExpiryTime = existing.Model.Properties.ExpiryTime + if d.HasChange("expiry_time") { + parameters.Properties.ExpiryTime = pointer.To(d.Get("expiry_time").(string)) + } + + // only pay attention to interval if frequency is not OneTime, and default it to 1 if not set + if parameters.Properties.Frequency != schedule.ScheduleFrequencyOneTime { + parameters.Properties.Interval = existing.Model.Properties.Interval + if d.HasChange("interval") { + parameters.Properties.Interval = pointer.To(d.Get("interval")) + } + } + + if d.HasChange("week_days") || d.HasChange("month_days") || d.HasChange("monthly_occurrence") { + // only pay attention to the advanced schedule fields if frequency is either Week or Month + if parameters.Properties.Frequency == schedule.ScheduleFrequencyWeek || parameters.Properties.Frequency == schedule.ScheduleFrequencyMonth { + parameters.Properties.AdvancedSchedule = expandArmAutomationScheduleAdvanced(d, d.Id() != "") + } + } + + if _, err := client.CreateOrUpdate(ctx, id, parameters); err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + return resourceAutomationScheduleRead(d, meta) +} + func resourceAutomationScheduleRead(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Automation.Schedule ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)