diff --git a/azurerm/config.go b/azurerm/config.go index f263bae528cc..08c4706dfd6d 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -78,10 +78,11 @@ type ArmClient struct { cosmosDBClient documentdb.DatabaseAccountsClient - automationAccountClient automation.AccountClient - automationRunbookClient automation.RunbookClient - automationCredentialClient automation.CredentialClient - automationScheduleClient automation.ScheduleClient + automationAccountClient automation.AccountClient + automationRunbookClient automation.RunbookClient + automationCredentialClient automation.CredentialClient + automationScheduleClient automation.ScheduleClient + automationRunbookDraftClient automation.RunbookDraftClient dnsClient dns.RecordSetsClient zonesClient dns.ZonesClient @@ -472,6 +473,10 @@ func (c *ArmClient) registerAutomationClients(endpoint, subscriptionId string, a scheduleClient := automation.NewScheduleClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&scheduleClient.Client, auth) c.automationScheduleClient = scheduleClient + + runbookDraftClient := automation.NewRunbookDraftClientWithBaseURI(endpoint, subscriptionId) + c.configureClient(&runbookDraftClient.Client, auth) + c.automationRunbookDraftClient = runbookDraftClient } func (c *ArmClient) registerAuthentication(endpoint, graphEndpoint, subscriptionId, tenantId string, auth, graphAuth autorest.Authorizer, sender autorest.Sender) { diff --git a/azurerm/resource_arm_automation_runbook.go b/azurerm/resource_arm_automation_runbook.go index 914cddf5a7d7..a6ccbf8ac6ad 100644 --- a/azurerm/resource_arm_automation_runbook.go +++ b/azurerm/resource_arm_automation_runbook.go @@ -1,7 +1,9 @@ package azurerm import ( + "bytes" "fmt" + "io/ioutil" "log" "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" @@ -68,6 +70,12 @@ func resourceArmAutomationRunbook() *schema.Resource { Optional: true, }, + "content": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "publish_content_link": { Type: schema.TypeList, Required: true, @@ -144,16 +152,31 @@ func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta inter _, err := client.CreateOrUpdate(ctx, resGroup, accName, name, parameters) if err != nil { - return err + return fmt.Errorf("Error creating/updating Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) + } + + if v, ok := d.GetOk("content"); ok { + content := v.(string) + reader := ioutil.NopCloser(bytes.NewBufferString(content)) + draftClient := meta.(*ArmClient).automationRunbookDraftClient + _, err := draftClient.ReplaceContent(ctx, resGroup, accName, name, reader) + if err != nil { + return fmt.Errorf("Error setting the draft Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) + } + + _, err = draftClient.Publish(ctx, resGroup, accName, name) + if err != nil { + return fmt.Errorf("Error publishing the updated Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) + } } read, err := client.Get(ctx, resGroup, accName, name) if err != nil { - return err + return fmt.Errorf("Error retrieving Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) } if read.ID == nil { - return fmt.Errorf("Cannot read Automation Runbook '%s' (resource group %s) ID", name, resGroup) + return fmt.Errorf("Cannot read Automation Runbook %q (Account %q / Resource Group %q) ID", name, accName, resGroup) } d.SetId(*read.ID) @@ -180,7 +203,7 @@ func resourceArmAutomationRunbookRead(d *schema.ResourceData, meta interface{}) return nil } - return fmt.Errorf("Error making Read request on AzureRM Automation Runbook '%s': %+v", name, err) + return fmt.Errorf("Error making Read request on AzureRM Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) } d.Set("name", resp.Name) @@ -201,6 +224,20 @@ func resourceArmAutomationRunbookRead(d *schema.ResourceData, meta interface{}) flattenAndSetTags(d, tags) } + response, err := client.GetContent(ctx, resGroup, accName, name) + if err != nil { + return fmt.Errorf("Error retrieving content for Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) + } + + if v := response.Value; v != nil { + if contentBytes := *response.Value; contentBytes != nil { + buf := new(bytes.Buffer) + buf.ReadFrom(contentBytes) + content := buf.String() + d.Set("content", content) + } + } + return nil } diff --git a/azurerm/resource_arm_automation_runbook_test.go b/azurerm/resource_arm_automation_runbook_test.go index 27686417f540..14fd140789a0 100644 --- a/azurerm/resource_arm_automation_runbook_test.go +++ b/azurerm/resource_arm_automation_runbook_test.go @@ -62,6 +62,33 @@ func TestAccAzureRMAutomationRunbook_PSWorkflowWithHash(t *testing.T) { }) } +func TestAccAzureRMAutomationRunbook_PSWithContent(t *testing.T) { + resourceName := "azurerm_automation_runbook.test" + ri := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationRunbookDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationRunbook_PSWithContent(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationRunbookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "runbook_type", "PowerShell"), + resource.TestCheckResourceAttr(resourceName, "content", "# Some test content\n# for Terraform acceptance test\n"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"publish_content_link"}, + }, + }, + }) +} + func testCheckAzureRMAutomationRunbookDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*ArmClient).automationRunbookClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -199,3 +226,43 @@ resource "azurerm_automation_runbook" "test" { } `, rInt, location, rInt) } + +func testAccAzureRMAutomationRunbook_PSWithContent(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_runbook" "test" { + name = "Get-AzureVMTutorial" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + account_name = "${azurerm_automation_account.test.name}" + log_verbose = "true" + log_progress = "true" + description = "This is a test runbook for terraform acceptance test" + runbook_type = "PowerShell" + + publish_content_link { + uri = "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-automation-runbook-getvms/Runbooks/Get-AzureVMTutorial.ps1" + } + + content = < **NOTE** The Azure API requires a `publish_content_link` to be supplied even when specifying your own `content`. + +~> **NOTE** Setting `content` to an empty string will revert the runbook to the `publish_content_link`. `publish_content_link` supports the following: