diff --git a/azurerm/config.go b/azurerm/config.go index 6ab38ebcf185..a2b3565a15ac 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -167,6 +167,7 @@ type ArmClient struct { // Batch batchAccountClient batch.AccountClient + batchApplicationClient batch.ApplicationClient batchCertificateClient batch.CertificateClient batchPoolClient batch.PoolClient @@ -453,6 +454,10 @@ func (c *ArmClient) registerBatchClients(endpoint, subscriptionId string, auth a c.configureClient(&batchAccount.Client, auth) c.batchAccountClient = batchAccount + batchApplicationClient := batch.NewApplicationClientWithBaseURI(endpoint, subscriptionId) + c.configureClient(&batchApplicationClient.Client, auth) + c.batchApplicationClient = batchApplicationClient + batchCertificateClient := batch.NewCertificateClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&batchCertificateClient.Client, auth) c.batchCertificateClient = batchCertificateClient diff --git a/azurerm/provider.go b/azurerm/provider.go index 9675f35f12e5..313476f9152f 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -231,6 +231,7 @@ func Provider() terraform.ResourceProvider { "azurerm_azuread_service_principal_password": resourceArmActiveDirectoryServicePrincipalPassword(), "azurerm_azuread_service_principal": resourceArmActiveDirectoryServicePrincipal(), "azurerm_batch_account": resourceArmBatchAccount(), + "azurerm_batch_application": resourceArmBatchApplication(), "azurerm_batch_certificate": resourceArmBatchCertificate(), "azurerm_batch_pool": resourceArmBatchPool(), "azurerm_cdn_endpoint": resourceArmCdnEndpoint(), diff --git a/azurerm/resource_arm_batch_application.go b/azurerm/resource_arm_batch_application.go new file mode 100644 index 000000000000..b416b9bb7803 --- /dev/null +++ b/azurerm/resource_arm_batch_application.go @@ -0,0 +1,239 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmBatchApplication() *schema.Resource { + return &schema.Resource{ + Create: resourceArmBatchApplicationCreate, + Read: resourceArmBatchApplicationRead, + Update: resourceArmBatchApplicationUpdate, + Delete: resourceArmBatchApplicationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMBatchApplicationName, + }, + + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMBatchAccountName, + }, + + "allow_updates": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "default_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAzureRMBatchApplicationVersion, + }, + + "display_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAzureRMBatchApplicationDisplayName, + }, + }, + } +} + +func resourceArmBatchApplicationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batchApplicationClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + + if requireResourcesToBeImported { + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error checking for present of existing Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + } + if !utils.ResponseWasNotFound(resp.Response) { + return tf.ImportAsExistsError("azurerm_batch_application", *resp.ID) + } + } + + allowUpdates := d.Get("allow_updates").(bool) + defaultVersion := d.Get("default_version").(string) + displayName := d.Get("display_name").(string) + + parameters := batch.Application{ + ApplicationProperties: &batch.ApplicationProperties{ + AllowUpdates: utils.Bool(allowUpdates), + DefaultVersion: utils.String(defaultVersion), + DisplayName: utils.String(displayName), + }, + } + + if _, err := client.Create(ctx, resourceGroup, accountName, name, ¶meters); err != nil { + return fmt.Errorf("Error creating Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + return fmt.Errorf("Error retrieving Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read Batch Application %q (Account Name %q / Resource Group %q) ID", name, accountName, resourceGroup) + } + d.SetId(*resp.ID) + + return resourceArmBatchApplicationRead(d, meta) +} + +func resourceArmBatchApplicationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batchApplicationClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + accountName := id.Path["batchAccounts"] + name := id.Path["applications"] + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Batch Application %q does not exist - removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + d.Set("account_name", accountName) + if applicationProperties := resp.ApplicationProperties; applicationProperties != nil { + d.Set("allow_updates", applicationProperties.AllowUpdates) + d.Set("default_version", applicationProperties.DefaultVersion) + d.Set("display_name", applicationProperties.DisplayName) + } + + return nil +} + +func resourceArmBatchApplicationUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batchApplicationClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + allowUpdates := d.Get("allow_updates").(bool) + defaultVersion := d.Get("default_version").(string) + displayName := d.Get("display_name").(string) + + parameters := batch.Application{ + ApplicationProperties: &batch.ApplicationProperties{ + AllowUpdates: utils.Bool(allowUpdates), + DefaultVersion: utils.String(defaultVersion), + DisplayName: utils.String(displayName), + }, + } + + if _, err := client.Update(ctx, resourceGroup, accountName, name, parameters); err != nil { + return fmt.Errorf("Error updating Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + return resourceArmBatchApplicationRead(d, meta) +} + +func resourceArmBatchApplicationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batchApplicationClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + accountName := id.Path["batchAccounts"] + name := id.Path["applications"] + + if _, err := client.Delete(ctx, resourceGroup, accountName, name); err != nil { + return fmt.Errorf("Error deleting Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + return nil +} + +func validateAzureRMBatchApplicationName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if !regexp.MustCompile(`^[-_\da-zA-Z]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf("%q can contain any combination of alphanumeric characters, hyphens, and underscores: %q", k, value)) + } + + if 1 > len(value) { + errors = append(errors, fmt.Errorf("%q cannot be less than 1 character: %q", k, value)) + } + + if len(value) > 64 { + errors = append(errors, fmt.Errorf("%q cannot be longer than 64 characters: %q %d", k, value, len(value))) + } + + return warnings, errors +} + +func validateAzureRMBatchApplicationVersion(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if !regexp.MustCompile(`^[-._\da-zA-Z]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf("%q can contain any combination of alphanumeric characters, hyphens, underscores, and periods: %q", k, value)) + } + + if 1 > len(value) { + errors = append(errors, fmt.Errorf("%q cannot be less than 1 character: %q", k, value)) + } + + if len(value) > 64 { + errors = append(errors, fmt.Errorf("%q cannot be longer than 64 characters: %q %d", k, value, len(value))) + } + + return warnings, errors +} + +func validateAzureRMBatchApplicationDisplayName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if 1 > len(value) { + errors = append(errors, fmt.Errorf("%q cannot be less than 1 character: %q", k, value)) + } + + if len(value) > 1024 { + errors = append(errors, fmt.Errorf("%q cannot be longer than 1024 characters: %q %d", k, value, len(value))) + } + + return warnings, errors +} diff --git a/azurerm/resource_arm_batch_application_test.go b/azurerm/resource_arm_batch_application_test.go new file mode 100644 index 000000000000..63dfe4f68333 --- /dev/null +++ b/azurerm/resource_arm_batch_application_test.go @@ -0,0 +1,150 @@ +package azurerm + +import ( + "fmt" + "strings" + "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/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMBatchApplication_basic(t *testing.T) { + resourceName := "azurerm_batch_application.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchApplicationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMBatchApplication_template(ri, rs, location, ""), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchApplicationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMBatchApplication_update(t *testing.T) { + resourceName := "azurerm_batch_application.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + displayName := fmt.Sprintf("TestAccDisplayName-%d", ri) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchApplicationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMBatchApplication_template(ri, rs, location, ""), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchApplicationExists(resourceName), + ), + }, + { + Config: testAccAzureRMBatchApplication_template(ri, rs, location, fmt.Sprintf(`display_name = "%s"`, displayName)), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchApplicationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "display_name", displayName), + ), + }, + }, + }) +} + +func testCheckAzureRMBatchApplicationExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Batch Application not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + accountName := rs.Primary.Attributes["account_name"] + + client := testAccProvider.Meta().(*ArmClient).batchApplicationClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + if resp, err := client.Get(ctx, resourceGroup, accountName, name); err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Batch Application %q (Account Name %q / Resource Group %q) does not exist", name, accountName, resourceGroup) + } + return fmt.Errorf("Bad: Get on batchApplicationClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMBatchApplicationDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).batchApplicationClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_batch_application" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + accountName := rs.Primary.Attributes["account_name"] + + if resp, err := client.Get(ctx, resourceGroup, accountName, name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Get on batchApplicationClient: %+v", err) + } + } + + return nil + } + + return nil +} + +func testAccAzureRMBatchApplication_template(rInt int, rString string, location string, displayName string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_batch_account" "test" { + name = "acctestba%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" + storage_account_id = "${azurerm_storage_account.test.id}" +} + +resource "azurerm_batch_application" "test" { + name = "acctestbatchapp-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + %s +} +`, rInt, location, rString, rString, rInt, displayName) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 5307691f2e33..8d427020b176 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -607,6 +607,10 @@ azurerm_batch_account +
  • + azurerm_batch_application +
  • +
  • azurerm_batch_certificate
  • diff --git a/website/docs/r/batch_application.html.markdown b/website/docs/r/batch_application.html.markdown new file mode 100644 index 000000000000..9186b4dc6d24 --- /dev/null +++ b/website/docs/r/batch_application.html.markdown @@ -0,0 +1,73 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_batch_application" +sidebar_current: "docs-azurerm-resource-batch-application" +description: |- + Manage Azure Batch Application instance. +--- + +# azurerm_batch_application + +Manage Azure Batch Application instance. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-rg" + location = "West US" +} + +resource "azurerm_storage_account" "example" { + name = "examplesa" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_batch_account" "example" { + name = "exampleba" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + pool_allocation_mode = "BatchService" + storage_account_id = "${azurerm_storage_account.example.id}" +} + +resource "azurerm_batch_application" "example" { + name = "example-batch-application" + resource_group_name = "${azurerm_resource_group.example.name}" + account_name = "${azurerm_batch_account.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the application. This must be unique within the account. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group that contains the Batch account. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Batch account. Changing this forces a new resource to be created. + +* `allow_updates` - (Optional) A value indicating whether packages within the application may be overwritten using the same version string. Defaults to `true`. + +* `default_version` - (Optional) The package to use if a client requests the application but does not specify a version. This property can only be set to the name of an existing package. + +* `display_name` - (Optional) The display name for the application. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the resource. + + +## Import + +Batch Application can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_batch_application.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Batch/batchAccounts/exampleba/applications/example-batch-application +```