Skip to content

Commit d30d714

Browse files
committed
automation: split automation_module CreateUpdate into separate Create and Update
Split resourceAutomationModuleCreateUpdate into independent resourceAutomationModuleCreate and resourceAutomationModuleUpdate functions. Create function: - Uses timeouts.ForCreate - Unwraps d.IsNewResource() guard, keeps isGlobal existence check - Uses CreateOrUpdate API - State waiter uses TimeoutCreate - Error message says 'creating' Update function: - Uses timeouts.ForUpdate - Parses ID from d.Id() - Uses PATCH API (ModuleUpdateParameters) instead of PUT - HasChange guard for module_link - State waiter uses TimeoutUpdate - Error message says 'updating' - No d.SetId() call
1 parent 5c0d5ed commit d30d714

File tree

1 file changed

+92
-21
lines changed

1 file changed

+92
-21
lines changed

internal/services/automation/automation_module_resource.go

Lines changed: 92 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import (
2222

2323
func resourceAutomationModule() *pluginsdk.Resource {
2424
return &pluginsdk.Resource{
25-
Create: resourceAutomationModuleCreateUpdate,
25+
Create: resourceAutomationModuleCreate,
2626
Read: resourceAutomationModuleRead,
27-
Update: resourceAutomationModuleCreateUpdate,
27+
Update: resourceAutomationModuleUpdate,
2828
Delete: resourceAutomationModuleDelete,
2929

3030
Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error {
@@ -91,29 +91,27 @@ func resourceAutomationModule() *pluginsdk.Resource {
9191
}
9292
}
9393

94-
func resourceAutomationModuleCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
94+
func resourceAutomationModuleCreate(d *pluginsdk.ResourceData, meta interface{}) error {
9595
client := meta.(*clients.Client).Automation.Module
9696
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
97-
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
97+
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
9898
defer cancel()
9999

100100
log.Printf("[INFO] preparing arguments for AzureRM Automation Module creation.")
101101

102102
id := module.NewModuleID(subscriptionId, d.Get("resource_group_name").(string), d.Get("automation_account_name").(string), d.Get("name").(string))
103103

104-
if d.IsNewResource() {
105-
existing, err := client.Get(ctx, id)
106-
if err != nil {
107-
if !response.WasNotFound(existing.HttpResponse) {
108-
return fmt.Errorf("checking for presence of existing %s: %s", id, err)
109-
}
104+
existing, err := client.Get(ctx, id)
105+
if err != nil {
106+
if !response.WasNotFound(existing.HttpResponse) {
107+
return fmt.Errorf("checking for presence of existing %s: %s", id, err)
110108
}
109+
}
111110

112-
// for existing global module do update instead of raising ImportAsExistsError
113-
isGlobal := existing.Model != nil && existing.Model.Properties != nil && existing.Model.Properties.IsGlobal != nil && *existing.Model.Properties.IsGlobal
114-
if !response.WasNotFound(existing.HttpResponse) && !isGlobal {
115-
return tf.ImportAsExistsError("azurerm_automation_module", id.ID())
116-
}
111+
// for existing global module do update instead of raising ImportAsExistsError
112+
isGlobal := existing.Model != nil && existing.Model.Properties != nil && existing.Model.Properties.IsGlobal != nil && *existing.Model.Properties.IsGlobal
113+
if !response.WasNotFound(existing.HttpResponse) && !isGlobal {
114+
return tf.ImportAsExistsError("azurerm_automation_module", id.ID())
117115
}
118116

119117
parameters := module.ModuleCreateOrUpdateParameters{
@@ -123,7 +121,7 @@ func resourceAutomationModuleCreateUpdate(d *pluginsdk.ResourceData, meta interf
123121
}
124122

125123
if _, err := client.CreateOrUpdate(ctx, id, parameters); err != nil {
126-
return err
124+
return fmt.Errorf("creating %s: %+v", id, err)
127125
}
128126

129127
// the API returns 'done' but it's not actually finished provisioning yet
@@ -148,6 +146,7 @@ func resourceAutomationModuleCreateUpdate(d *pluginsdk.ResourceData, meta interf
148146
string(module.ModuleProvisioningStateSucceeded),
149147
},
150148
MinTimeout: 30 * time.Second,
149+
Timeout: d.Timeout(pluginsdk.TimeoutCreate),
151150
Refresh: func() (interface{}, string, error) {
152151
resp, err2 := client.Get(ctx, id)
153152
if err2 != nil {
@@ -169,11 +168,6 @@ func resourceAutomationModuleCreateUpdate(d *pluginsdk.ResourceData, meta interf
169168
return resp, provisioningState, nil
170169
},
171170
}
172-
if d.IsNewResource() {
173-
stateConf.Timeout = d.Timeout(pluginsdk.TimeoutCreate)
174-
} else {
175-
stateConf.Timeout = d.Timeout(pluginsdk.TimeoutUpdate)
176-
}
177171

178172
if _, err := stateConf.WaitForStateContext(ctx); err != nil {
179173
return fmt.Errorf("waiting for %s to finish provisioning: %+v", id, err)
@@ -184,6 +178,83 @@ func resourceAutomationModuleCreateUpdate(d *pluginsdk.ResourceData, meta interf
184178
return resourceAutomationModuleRead(d, meta)
185179
}
186180

181+
func resourceAutomationModuleUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
182+
client := meta.(*clients.Client).Automation.Module
183+
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
184+
defer cancel()
185+
186+
id, err := module.ParseModuleID(d.Id())
187+
if err != nil {
188+
return err
189+
}
190+
191+
parameters := module.ModuleUpdateParameters{
192+
Name: &id.ModuleName,
193+
}
194+
195+
if d.HasChange("module_link") {
196+
contentLink := expandModuleLink(d)
197+
parameters.Properties = &module.ModuleUpdateProperties{
198+
ContentLink: &contentLink,
199+
}
200+
}
201+
202+
if _, err := client.Update(ctx, *id, parameters); err != nil {
203+
return fmt.Errorf("updating %s: %+v", *id, err)
204+
}
205+
206+
// the API returns 'done' but it's not actually finished provisioning yet
207+
// tracking issue: https://github.com/Azure/azure-rest-api-specs/pull/25435
208+
stateConf := &pluginsdk.StateChangeConf{
209+
Pending: []string{
210+
string(module.ModuleProvisioningStateActivitiesStored),
211+
string(module.ModuleProvisioningStateConnectionTypeImported),
212+
string(module.ModuleProvisioningStateContentDownloaded),
213+
string(module.ModuleProvisioningStateContentRetrieved),
214+
string(module.ModuleProvisioningStateContentStored),
215+
string(module.ModuleProvisioningStateContentValidated),
216+
string(module.ModuleProvisioningStateCreated),
217+
string(module.ModuleProvisioningStateCreating),
218+
string(module.ModuleProvisioningStateModuleDataStored),
219+
string(module.ModuleProvisioningStateModuleImportRunbookComplete),
220+
string(module.ModuleProvisioningStateRunningImportModuleRunbook),
221+
string(module.ModuleProvisioningStateStartingImportModuleRunbook),
222+
string(module.ModuleProvisioningStateUpdating),
223+
},
224+
Target: []string{
225+
string(module.ModuleProvisioningStateSucceeded),
226+
},
227+
MinTimeout: 30 * time.Second,
228+
Timeout: d.Timeout(pluginsdk.TimeoutUpdate),
229+
Refresh: func() (interface{}, string, error) {
230+
resp, err2 := client.Get(ctx, *id)
231+
if err2 != nil {
232+
return resp, "Error", fmt.Errorf("retrieving %s: %+v", *id, err2)
233+
}
234+
235+
provisioningState := "Unknown"
236+
if model := resp.Model; model != nil {
237+
if props := model.Properties; props != nil {
238+
if props.ProvisioningState != nil {
239+
provisioningState = string(*props.ProvisioningState)
240+
}
241+
if props.Error != nil && props.Error.Message != nil && *props.Error.Message != "" {
242+
return resp, provisioningState, errors.New(*props.Error.Message)
243+
}
244+
return resp, provisioningState, nil
245+
}
246+
}
247+
return resp, provisioningState, nil
248+
},
249+
}
250+
251+
if _, err := stateConf.WaitForStateContext(ctx); err != nil {
252+
return fmt.Errorf("waiting for %s to finish provisioning: %+v", *id, err)
253+
}
254+
255+
return resourceAutomationModuleRead(d, meta)
256+
}
257+
187258
func resourceAutomationModuleRead(d *pluginsdk.ResourceData, meta interface{}) error {
188259
client := meta.(*clients.Client).Automation.Module
189260
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)

0 commit comments

Comments
 (0)