Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_automation_job_schedule: update jobSchedule resource id format #22164

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

wuxu92
Copy link
Contributor

@wuxu92 wuxu92 commented Jun 14, 2023

Draft: Wait hashicorp/go-azure-helpers#208 to be released and update the verion in azurerm.

The job schdule is a link between a runbook and a schdule. there should be only one such link between the runbook and schedule pair. When we update a runbook, request a PUT of runbook resource, the job schedule id linked to this runbook will be automatically updated, and the old job schedule id should be NOT FOUND then.

The current implementation introduced in #7555 will try to delete all job schedules linked to the runbook and then it need a next terraform apply to recreate these job schedules. This is not neccessary at first, and it make the terraform plan can not report what terraform apply really does, it makes users confused when update a runbook.

This PR is to replace the azurerm_automation_job_schedule resource id with a customized one. The new one contains the runbook name and the schedule resource name, so we can query the job schdule id in runtime and made the id responded from API as computed attribute resource_manager_id. this PR also introduces a schema migration to make sure not break exsiting resources.

the old resource id format: terraform import azurerm_automation_job_schedule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/jobSchedules/10000000-1001-1001-1001-000000000001
the new resourec id format: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/runBook/book1/schedule/schedule1

resolves: #8634

--- PASS: TestAccAutomationJobSchedule_basic (136.84s)
--- PASS: TestAccAutomationJobSchedule_complete (198.69s)
--- PASS: TestAccAutomationJobSchedule_update (298.63s)
--- PASS: TestAccAutomationJobSchedule_requiresImport (209.73s)
--- PASS: TestAccAutomationRunbook_PSWorkflow (184.43s)
--- PASS: TestAccAutomationRunbook_WithDraft (184.13s)
--- PASS: TestAccAutomationRunbook_requiresImport (193.49s)
--- PASS: TestAccAutomationRunbook_PSWorkflowWithHash (141.74s)
--- PASS: TestAccAutomationRunbook_PSWithContent (186.88s)
--- PASS: TestAccAutomationRunbook_PSWorkflowWithoutUri (177.20s)
--- PASS: TestAccAutomationRunbook_withJobSchedule (543.13s)
--- PASS: TestAccAutomationRunbook_withJobScheduleResourceAndUpdate (211.70s)

Test Pass in TC

image

Copy link
Collaborator

@magodo magodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!
I've taken a look through and left some comments inline. The main ask is that this solution is built on an assumption that the schedules linked to a runbook must have different names, would you please help confirm whether this is the case?

@wuxu92
Copy link
Contributor Author

wuxu92 commented Jul 3, 2023

The Schedule name should be unique inside the same automation account, and there MUST be only 1 link between the runbook and the schedule. so the new id schema should work.

Copy link
Collaborator

@magodo magodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!
I have left some additional mostly minor comments that once addressed this should be good to merge 👍

@@ -0,0 +1,3 @@
package automation

//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=AutomationJobSchedule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/runBook/book1/schedule/schedule1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality provided by resourceids.go shouldn't be used for new resources and will be removed once we've finished migrating off them - instead, since this is already using hashicorp/go-azure-sdk - the relevant Resource ID from hashicorp/go-azure-sdk should be used instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Resource ID in go-azure-sdk cannot work as expect in the issue of this PR is tring to fix. because the job schedule id will be updated automatically when the runbook resource updated. so I create this new job schedule ID Format to represent the link between the runbook and schedule.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this PR to fix some logic and tested it locally. Although the ID format of the resource has changed, I verified that this update should not introduce any breaking changes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this now?

@@ -67,5 +71,5 @@ The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/l
Automation Job Schedules can be imported using the `resource id`, e.g.

```shell
terraform import azurerm_automation_job_schedule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/jobSchedules/10000000-1001-1001-1001-000000000001
terraform import azurerm_automation_job_schedule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/runBook/book1/schedule/schedule1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we are creating a new "fake" resource id instead of creating a composite resource id? ie
/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1| /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/runbooks/Get-AzureVMTutorial

this is something we are looking to implement first class support for soon and will work with the up coming casing fixes - see https://github.com/hashicorp/go-azure-helpers/pull/208/files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

‌‌‌‌‌‌A composite resource ID would definitely be effective. Is there a plan to merge PR 208? I will update this PR accordingly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, hopefully it'll be merged in the next couple weeks

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wuxu92 - the above PR has been merged

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated this PR with CompositeResourceID but need new version/tag of go-azure-helpers to be released. so I'm going to make this PR draft before new version of go-azure-helpers available.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wuxu92 wuxu92 marked this pull request as ready for review March 28, 2024 01:36
@stephybun stephybun added this to the v4.0.0 milestone Apr 3, 2024
Comment on lines 279 to 284
accountID := jobschedule.NewAutomationAccountID(id.First.SubscriptionId, id.First.ResourceGroupName, id.First.AutomationAccountName)
filter := fmt.Sprintf("properties/schedule/name eq '%s' and properties/runbook/name eq '%s'", id.First.ScheduleName, id.Second.RunbookName)
jsList, err := client.ListByAutomationAccountComplete(ctx, accountID, jobschedule.ListByAutomationAccountOperationOptions{Filter: &filter})
if err != nil {
return nil, fmt.Errorf("loading Automation Account %q Job Schedule List: %+v", accountID.AutomationAccountName, err)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed? The Go SDK has a Get method?

func (c RunbookClient) Get(ctx context.Context, id RunbookId) (result GetOperationResponse, err error) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to get the job schedule here, but we don't know the job schedule id from the composite id, because the job schedule id can be updated when the related account or runbook is updated. So we need the List operation to get the correct job schedule id here.

@@ -0,0 +1,3 @@
package automation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove this file?

runbookID := runbook.NewRunbookID(subscriptionId, resourceGroup, accountName, runbookName)
id := jobschedule.NewJobScheduleID(subscriptionId, resourceGroup, accountName, jobScheduleUUID.String())

// tfID := parse.NewAutomationJobScheduleID(id.SubscriptionId, id.ResourceGroupName, id.AutomationAccountName, runbookName, scheduleName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can remove this line now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.

@@ -0,0 +1,3 @@
package automation

//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=AutomationJobSchedule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/runBook/book1/schedule/schedule1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this now?

@@ -10,6 +10,8 @@ description: |-

Links an Automation Runbook and Schedule.

~> **NOTE** AzureRM provides this stand-alone [azurerm_automation_job_schedule](automation_job_schedule.html.markdown) and an inlined `job_schdule` property in [azurerm_runbook](automation_runbook.html.markdown) to manage the job schedules. At this time you should choose one of them to manage the job schedule resources.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
~> **NOTE** AzureRM provides this stand-alone [azurerm_automation_job_schedule](automation_job_schedule.html.markdown) and an inlined `job_schdule` property in [azurerm_runbook](automation_runbook.html.markdown) to manage the job schedules. At this time you should choose one of them to manage the job schedule resources.
~> **NOTE** AzureRM provides this stand-alone [azurerm_automation_job_schedule](automation_job_schedule.html.markdown) and an inlined `job_schdule` property in [azurerm_runbook](automation_runbook.html.markdown) to manage the job schedules. You can only make use of one of these methods to manage a job schedule.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

Copy link
Member

@catriona-m catriona-m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @wuxu92 I had a look though this and left a couple of comments inline, but once those are addressed we can take another look. Thanks!

@@ -107,43 +125,24 @@ func resourceAutomationJobScheduleCreate(d *pluginsdk.ResourceData, meta interfa
jobScheduleUUID = uuid.FromStringOrNil(jobScheduleID.(string))
}

id := jobschedule.NewJobScheduleID(subscriptionId, d.Get("resource_group_name").(string), d.Get("automation_account_name").(string), jobScheduleUUID.String())
// accountID := automationaccount.NewAutomationAccountID(subscriptionId, resourceGroup, accountName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.

Comment on lines 196 to 203
js, err := GetJobScheduleFromTFID(ctx, client, tfID)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
d.SetId("")
return nil
}
return fmt.Errorf("making Read request on %s: %+v", *id, err)
return err
}
if js == nil {
d.SetId("")
return nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case where the resource group has been deleted outside of terraform, this will continually give us an error when trying to list the job schedules and it is never marked as gone. We should update this to cover this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated GetJobScheduleFromTFID to return nil error if API response is 404.

* `draft` - (Optional) A `draft` block as defined below .
* `draft` - (Optional) A `draft` block as defined below.

* `job_schedule` - (Optional) Onr or more `job_schedule` block as defined below.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `job_schedule` - (Optional) Onr or more `job_schedule` block as defined below.
* `job_schedule` - (Optional) One or more `job_schedule` block as defined below.

Copy link
Member

@catriona-m catriona-m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the changes @wuxu92 - I tested this and still got an error in some cases, could you take another look? Thanks!

Copy link
Member

@catriona-m catriona-m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this up @wuxu92 - I spotted a couple of minor things on looking through this again but otherwise this is looking good. Thanks!

@@ -67,5 +71,5 @@ The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/l
Automation Job Schedules can be imported using the `resource id`, e.g.

```shell
terraform import azurerm_automation_job_schedule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/jobSchedules/10000000-1001-1001-1001-000000000001
terraform import azurerm_automation_job_schedule.example "/subscriptions/85b3dbca-5974-4067-9669-67a141095a76/resourceGroups/acctestRG-auto-240326135902419761/providers/Microsoft.Automation/automationAccounts/acctestAA-240328091346495956/schedules/acctestAS-240328091346495956|/subscriptions/85b3dbca-5974-4067-9669-67a141095a76/resourceGroups/acctestRG-auto-240326135902419761/providers/Microsoft.Automation/automationAccounts/acctestAA-240328091346495956/runbooks/Output-HelloWorld"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
terraform import azurerm_automation_job_schedule.example "/subscriptions/85b3dbca-5974-4067-9669-67a141095a76/resourceGroups/acctestRG-auto-240326135902419761/providers/Microsoft.Automation/automationAccounts/acctestAA-240328091346495956/schedules/acctestAS-240328091346495956|/subscriptions/85b3dbca-5974-4067-9669-67a141095a76/resourceGroups/acctestRG-auto-240326135902419761/providers/Microsoft.Automation/automationAccounts/acctestAA-240328091346495956/runbooks/Output-HelloWorld"
terraform import azurerm_automation_job_schedule.example "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/schedules/schedule1|/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1/runbooks/runbook1"


id, err := jobschedule.ParseJobScheduleID(pointer.From(js.Id))
if err != nil {
return fmt.Errorf("parse jobSchedule id %s: %v", pointer.From(js.Id), err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("parse jobSchedule id %s: %v", pointer.From(js.Id), err)
return err

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants