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

Automation resources #1512

Merged
merged 25 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0a0b0bc
added resource automation_module
bgelens Jul 4, 2018
6fa2fd6
added resource for automation dsc configuration and nodeconfiguration
bgelens Jul 5, 2018
f5f8abd
added tests
bgelens Jul 6, 2018
345d558
sorted automation resources alphabetically
bgelens Jul 29, 2018
94c976c
changed account_name to automation_account_name
bgelens Jul 29, 2018
ac18fd4
fix indentation issues
bgelens Jul 30, 2018
f1c1e3e
added initial docs
bgelens Jul 30, 2018
155d38b
fixed rebase mistake
bgelens Jul 30, 2018
71a5232
fix comp error
bgelens Aug 8, 2018
c918778
update azurerm.erb
bgelens Aug 8, 2018
68ecd1e
automationClients now make use of configureClient function
bgelens Aug 9, 2018
0aa0a7a
added validation.NoZeroValues where applicable
bgelens Aug 14, 2018
cfceafd
fetching location for dsc configuration
bgelens Aug 18, 2018
0a7f63e
dsc configuration: added regex name validation, changed to content_em…
bgelens Aug 18, 2018
5d11527
replace %s with %q where applicable
bgelens Aug 19, 2018
4c9b888
updaed dsc nodeconfig test to reflect change to dsc config resource
bgelens Aug 19, 2018
0704603
updated dsc node config with content_embedded and adjusted test and e…
bgelens Aug 19, 2018
a3ab5b5
added comment to test
bgelens Aug 20, 2018
34f6a94
fixed minor issues in dsc configuration
bgelens Aug 24, 2018
b2cbb32
vendoring azure go sdk v20.0.0 for automation
bgelens Aug 31, 2018
f192327
added fetch of content for dsc_configuration and updated test
bgelens Aug 31, 2018
872517e
make use of utils.String where applicable and removed name from dsc c…
bgelens Sep 9, 2018
11926b1
Merge branch 'master' into automationresources
bgelens Sep 9, 2018
10bd951
renamed dsc configuration name to acctest for tests
bgelens Sep 12, 2018
71503c8
Merge remote-tracking branch 'origin/master' into automationresources
katbyte Oct 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,14 @@ type ArmClient struct {

cosmosDBClient documentdb.DatabaseAccountsClient

automationAccountClient automation.AccountClient
automationRunbookClient automation.RunbookClient
automationCredentialClient automation.CredentialClient
automationScheduleClient automation.ScheduleClient
automationRunbookDraftClient automation.RunbookDraftClient
automationAccountClient automation.AccountClient
automationCredentialClient automation.CredentialClient
automationDscConfigurationClient automation.DscConfigurationClient
automationDscNodeConfigurationClient automation.DscNodeConfigurationClient
automationModuleClient automation.ModuleClient
automationRunbookClient automation.RunbookClient
automationRunbookDraftClient automation.RunbookDraftClient
automationScheduleClient automation.ScheduleClient

dnsClient dns.RecordSetsClient
zonesClient dns.ZonesClient
Expand Down Expand Up @@ -534,6 +537,18 @@ func (c *ArmClient) registerAutomationClients(endpoint, subscriptionId string, a
c.configureClient(&credentialClient.Client, auth)
c.automationCredentialClient = credentialClient

dscConfigurationClient := automation.NewDscConfigurationClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&dscConfigurationClient.Client, auth)
c.automationDscConfigurationClient = dscConfigurationClient

dscNodeConfigurationClient := automation.NewDscNodeConfigurationClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&dscNodeConfigurationClient.Client, auth)
c.automationDscNodeConfigurationClient = dscNodeConfigurationClient

moduleClient := automation.NewModuleClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&moduleClient.Client, auth)
c.automationModuleClient = moduleClient

runbookClient := automation.NewRunbookClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&runbookClient.Client, auth)
c.automationRunbookClient = runbookClient
Expand Down
3 changes: 3 additions & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ func Provider() terraform.ResourceProvider {
"azurerm_app_service_slot": resourceArmAppServiceSlot(),
"azurerm_automation_account": resourceArmAutomationAccount(),
"azurerm_automation_credential": resourceArmAutomationCredential(),
"azurerm_automation_dsc_configuration": resourceArmAutomationDscConfiguration(),
"azurerm_automation_dsc_nodeconfiguration": resourceArmAutomationDscNodeConfiguration(),
"azurerm_automation_module": resourceArmAutomationModule(),
"azurerm_automation_runbook": resourceArmAutomationRunbook(),
"azurerm_automation_schedule": resourceArmAutomationSchedule(),
"azurerm_autoscale_setting": resourceArmAutoScaleSetting(),
Expand Down
190 changes: 190 additions & 0 deletions azurerm/resource_arm_automation_dsc_configuration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package azurerm

import (
"bytes"
"fmt"
"log"
"regexp"

"github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmAutomationDscConfiguration() *schema.Resource {
return &schema.Resource{
Create: resourceArmAutomationDscConfigurationCreateUpdate,
Read: resourceArmAutomationDscConfigurationRead,
Update: resourceArmAutomationDscConfigurationCreateUpdate,
Delete: resourceArmAutomationDscConfigurationDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
katbyte marked this conversation as resolved.
Show resolved Hide resolved
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`^[a-zA-Z0-9_]{1,64}$`),
`The name length must be from 1 to 64 characters. The name can only contain letters, numbers and underscores.`,
),
},

"automation_account_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.NoZeroValues,
},

"content_embedded": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.NoZeroValues,
},

"resource_group_name": resourceGroupNameSchema(),

"location": locationSchema(),

"log_verbose": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"description": {
Type: schema.TypeString,
Optional: true,
},

"state": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceArmAutomationDscConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).automationDscConfigurationClient
ctx := meta.(*ArmClient).StopContext

log.Printf("[INFO] preparing arguments for AzureRM Automation Dsc Configuration creation.")

name := d.Get("name").(string)
resGroup := d.Get("resource_group_name").(string)
accName := d.Get("automation_account_name").(string)
contentEmbedded := d.Get("content_embedded").(string)
location := azureRMNormalizeLocation(d.Get("location").(string))
logVerbose := d.Get("log_verbose").(bool)
description := d.Get("description").(string)

parameters := automation.DscConfigurationCreateOrUpdateParameters{
DscConfigurationCreateOrUpdateProperties: &automation.DscConfigurationCreateOrUpdateProperties{
LogVerbose: utils.Bool(logVerbose),
Description: utils.String(description),
Source: &automation.ContentSource{
Type: automation.EmbeddedContent,
Value: utils.String(contentEmbedded),
},
},
Location: utils.String(location),
}

_, err := client.CreateOrUpdate(ctx, resGroup, accName, name, parameters)
if err != nil {
return err
}

read, err := client.Get(ctx, resGroup, accName, name)
if err != nil {
return err
}

if read.ID == nil {
return fmt.Errorf("Cannot read Automation Dsc Configuration %q (resource group %q) ID", name, resGroup)
}

d.SetId(*read.ID)

return resourceArmAutomationDscConfigurationRead(d, meta)
}

func resourceArmAutomationDscConfigurationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).automationDscConfigurationClient
ctx := meta.(*ArmClient).StopContext

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
accName := id.Path["automationAccounts"]
name := id.Path["configurations"]

resp, err := client.Get(ctx, resGroup, accName, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}

return fmt.Errorf("Error making Read request on AzureRM Automation Dsc Configuration %q: %+v", name, err)
}

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 you are not fetching the content? It does appear to be part of the data structure. If there is a reason a comment explaining why here would be great.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also is there a reason location not being read back into state?

Copy link
Contributor Author

@bgelens bgelens Aug 18, 2018

Choose a reason for hiding this comment

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

Content is not part of the data structure, instead it needs to be fetched by GetContent function. I have an issue with the Azure Go SDK so I won't be able to fix this right now. Reported an issue

Location is now fetched among some other properties (log_verbose and description).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like that issue has been resolved

d.Set("name", resp.Name)
d.Set("resource_group_name", resGroup)
d.Set("automation_account_name", accName)

if location := resp.Location; location != nil {
d.Set("location", azureRMNormalizeLocation(*location))
}

if props := resp.DscConfigurationProperties; props != nil {
d.Set("log_verbose", props.LogVerbose)
d.Set("description", props.Description)
d.Set("state", resp.State)
}

contentresp, err := client.GetContent(ctx, resGroup, accName, name)
if err != nil {
return fmt.Errorf("Error making Read request on AzureRM Automation Dsc Configuration content %q: %+v", name, err)
}

buf := new(bytes.Buffer)
buf.ReadFrom(contentresp.Body)
content := buf.String()

d.Set("content_embedded", content)

return nil
}

func resourceArmAutomationDscConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).automationDscConfigurationClient
ctx := meta.(*ArmClient).StopContext

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
accName := id.Path["automationAccounts"]
name := id.Path["configurations"]

resp, err := client.Delete(ctx, resGroup, accName, name)
if err != nil {
if utils.ResponseWasNotFound(resp) {
return nil
}

return fmt.Errorf("Error issuing AzureRM delete request for Automation Dsc Configuration %q: %+v", name, err)
}

return nil
}
135 changes: 135 additions & 0 deletions azurerm/resource_arm_automation_dsc_configuration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMAutomationDscConfiguration_basic(t *testing.T) {
resourceName := "azurerm_automation_dsc_configuration.test"
ri := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMAutomationDscConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMAutomationDscConfiguration_basic(ri, testLocation()),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMAutomationDscConfigurationExists(resourceName),
JunyiYi marked this conversation as resolved.
Show resolved Hide resolved
resource.TestCheckResourceAttrSet(resourceName, "location"),
resource.TestCheckResourceAttr(resourceName, "description", "test"),
resource.TestCheckResourceAttrSet(resourceName, "log_verbose"),
resource.TestCheckResourceAttrSet(resourceName, "state"),
resource.TestCheckResourceAttr(resourceName, "content_embedded", "configuration acctest {}"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testCheckAzureRMAutomationDscConfigurationDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*ArmClient).automationDscConfigurationClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

for _, rs := range s.RootModule().Resources {
if rs.Type != "azurerm_automation_dsc_configuration" {
continue
}

name := rs.Primary.Attributes["name"]
accName := rs.Primary.Attributes["automation_account_name"]

resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
if !hasResourceGroup {
return fmt.Errorf("Bad: no resource group found in state for Automation Dsc Configuration: '%s'", name)
}

resp, err := conn.Get(ctx, resourceGroup, accName, name)

if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return nil
}

return err
}

return fmt.Errorf("Automation Dsc Configuration still exists:\n%#v", resp)

}

return nil
}

func testCheckAzureRMAutomationDscConfigurationExists(name string) resource.TestCheckFunc {

return func(s *terraform.State) error {
// Ensure we have enough information in state to look up in API
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}

name := rs.Primary.Attributes["name"]
accName := rs.Primary.Attributes["automation_account_name"]

resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
if !hasResourceGroup {
return fmt.Errorf("Bad: no resource group found in state for Automation Dsc Configuration: '%s'", name)
}

conn := testAccProvider.Meta().(*ArmClient).automationDscConfigurationClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

resp, err := conn.Get(ctx, resourceGroup, accName, name)

if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Automation Dsc Configuration '%s' (resource group: '%s') does not exist", name, resourceGroup)
}

return fmt.Errorf("Bad: Get on automationDscConfigurationClient: %s\nName: %s, Account name: %s, Resource group: %s OBJECT: %+v", err, name, accName, resourceGroup, rs.Primary)
}

return nil
}
}

func testAccAzureRMAutomationDscConfiguration_basic(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_dsc_configuration" "test" {
name = "acctest"
resource_group_name = "${azurerm_resource_group.test.name}"
automation_account_name = "${azurerm_automation_account.test.name}"
location = "${azurerm_resource_group.test.location}"
content_embedded = "configuration acctest {}"
description = "test"
}
`, rInt, location, rInt)
}
Loading