diff --git a/azurerm/internal/services/appplatform/client/client.go b/azurerm/internal/services/appplatform/client/client.go index a0a6953b8c0a..f346283a638d 100644 --- a/azurerm/internal/services/appplatform/client/client.go +++ b/azurerm/internal/services/appplatform/client/client.go @@ -6,19 +6,24 @@ import ( ) type Client struct { - ServicesClient *appplatform.ServicesClient - AppsClient *appplatform.AppsClient + AppsClient *appplatform.AppsClient + CertificatesClient *appplatform.CertificatesClient + ServicesClient *appplatform.ServicesClient } func NewClient(o *common.ClientOptions) *Client { appsClient := appplatform.NewAppsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&appsClient.Client, o.ResourceManagerAuthorizer) + certificatesClient := appplatform.NewCertificatesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&certificatesClient.Client, o.ResourceManagerAuthorizer) + servicesClient := appplatform.NewServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&servicesClient.Client, o.ResourceManagerAuthorizer) return &Client{ - AppsClient: &appsClient, - ServicesClient: &servicesClient, + AppsClient: &appsClient, + CertificatesClient: &certificatesClient, + ServicesClient: &servicesClient, } } diff --git a/azurerm/internal/services/appplatform/parse/spring_cloud_certificate.go b/azurerm/internal/services/appplatform/parse/spring_cloud_certificate.go new file mode 100644 index 000000000000..8a4d7cabd02c --- /dev/null +++ b/azurerm/internal/services/appplatform/parse/spring_cloud_certificate.go @@ -0,0 +1,38 @@ +package parse + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type SpringCloudCertificateId struct { + ResourceGroup string + ServiceName string + Name string +} + +func SpringCloudCertificateID(input string) (*SpringCloudCertificateId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("parsing Spring Cloud Certificate ID %q: %+v", input, err) + } + + cert := SpringCloudCertificateId{ + ResourceGroup: id.ResourceGroup, + } + + if cert.ServiceName, err = id.PopSegment("Spring"); err != nil { + return nil, err + } + + if cert.Name, err = id.PopSegment("certificates"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &cert, nil +} diff --git a/azurerm/internal/services/appplatform/parse/spring_cloud_certificate_test.go b/azurerm/internal/services/appplatform/parse/spring_cloud_certificate_test.go new file mode 100644 index 000000000000..8ee82159a983 --- /dev/null +++ b/azurerm/internal/services/appplatform/parse/spring_cloud_certificate_test.go @@ -0,0 +1,88 @@ +package parse + +import ( + "testing" +) + +func TestSpringCloudCertificateID(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *SpringCloudCertificateId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "No Resource Groups Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Expected: nil, + }, + { + Name: "No Resource Groups Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/", + Expected: nil, + }, + { + Name: "Resource Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/", + Expected: nil, + }, + { + Name: "No Spring Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.AppPlatform/Spring/", + Expected: nil, + }, + { + Name: "Missing Certificates Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.AppPlatform/Spring/spring1/", + Expected: nil, + }, + { + Name: "Missing Certificates Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.AppPlatform/Spring/spring1/certificates/", + Expected: nil, + }, + { + Name: "Spring Cloud Certificate ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.AppPlatform/Spring/spring1/certificates/cert1", + Expected: &SpringCloudCertificateId{ + ResourceGroup: "resGroup1", + ServiceName: "spring1", + Name: "cert1", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.AppPlatform/Spring/spring1/Certificates/cert1", + Expected: nil, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := SpringCloudCertificateID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.ResourceGroup, actual.ResourceGroup) + } + + if actual.ServiceName != v.Expected.ServiceName { + t.Fatalf("Expected %q but got %q for ServiceName", v.Expected.ServiceName, actual.ServiceName) + } + + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + } +} diff --git a/azurerm/internal/services/appplatform/registration.go b/azurerm/internal/services/appplatform/registration.go index f048e38b406c..f935e85abc7c 100644 --- a/azurerm/internal/services/appplatform/registration.go +++ b/azurerm/internal/services/appplatform/registration.go @@ -28,7 +28,8 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azurerm_spring_cloud_app": resourceArmSpringCloudApp(), - "azurerm_spring_cloud_service": resourceArmSpringCloudService(), + "azurerm_spring_cloud_app": resourceArmSpringCloudApp(), + "azurerm_spring_cloud_certificate": resourceArmSpringCloudCertificate(), + "azurerm_spring_cloud_service": resourceArmSpringCloudService(), } } diff --git a/azurerm/internal/services/appplatform/spring_cloud_certificate_resource.go b/azurerm/internal/services/appplatform/spring_cloud_certificate_resource.go new file mode 100644 index 000000000000..42d29c0201cf --- /dev/null +++ b/azurerm/internal/services/appplatform/spring_cloud_certificate_resource.go @@ -0,0 +1,149 @@ +package appplatform + +import ( + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/preview/appplatform/mgmt/2019-05-01-preview/appplatform" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "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/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/appplatform/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/appplatform/validate" + azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmSpringCloudCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSpringCloudCertificateCreate, + Read: resourceArmSpringCloudCertificateRead, + Delete: resourceArmSpringCloudCertificateDelete, + + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { + _, err := parse.SpringCloudCertificateID(id) + return err + }), + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "service_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.SpringCloudServiceName, + }, + + "key_vault_certificate_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateKeyVaultChildId, + }, + }, + } +} + +func resourceArmSpringCloudCertificateCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).AppPlatform.CertificatesClient + ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) + defer cancel() + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("service_name").(string) + + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for presence of existing Spring Cloud Service Certificate %q (Spring Cloud Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + } + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_spring_cloud_certificate", *existing.ID) + } + + keyVaultCertificateId, _ := azure.ParseKeyVaultChildID(d.Get("key_vault_certificate_id").(string)) + cert := appplatform.CertificateResource{ + Properties: &appplatform.CertificateProperties{ + VaultURI: &keyVaultCertificateId.KeyVaultBaseUrl, + KeyVaultCertName: &keyVaultCertificateId.Name, + }, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, cert); err != nil { + return fmt.Errorf("creating Spring Cloud Certificate %q (Spring Cloud Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("retrieving Spring Cloud Certificate %q (Spring Cloud Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + if resp.ID == nil || *resp.ID == "" { + return fmt.Errorf("read Spring Cloud Certificate %q (Spring Cloud Service %q / Resource Group %q) ID", name, serviceName, resourceGroup) + } + d.SetId(*resp.ID) + + return resourceArmSpringCloudCertificateRead(d, meta) +} + +func resourceArmSpringCloudCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).AppPlatform.CertificatesClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.SpringCloudCertificateID(d.Id()) + if err != nil { + return err + } + resp, err := client.Get(ctx, id.ResourceGroup, id.ServiceName, id.Name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Spring Cloud Certificate %q does not exist - removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("reading Spring Cloud Certificate %q (Spring Cloud Service %q / Resource Group %q): %+v", id.Name, id.ServiceName, id.ResourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("service_name", id.ServiceName) + + return nil +} + +func resourceArmSpringCloudCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).AppPlatform.CertificatesClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.SpringCloudCertificateID(d.Id()) + if err != nil { + return err + } + + if _, err := client.Delete(ctx, id.ResourceGroup, id.ServiceName, id.Name); err != nil { + return fmt.Errorf("deleting Spring Cloud Certificate %q (Spring Cloud Service %q / Resource Group %q): %+v", id.Name, id.ServiceName, id.ResourceGroup, err) + } + + return nil +} diff --git a/azurerm/internal/services/appplatform/tests/spring_cloud_certificate_resource_test.go b/azurerm/internal/services/appplatform/tests/spring_cloud_certificate_resource_test.go new file mode 100644 index 000000000000..1292f8612eb1 --- /dev/null +++ b/azurerm/internal/services/appplatform/tests/spring_cloud_certificate_resource_test.go @@ -0,0 +1,222 @@ +package tests + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMSpringCloudCertificate_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_spring_cloud_certificate", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMSpringCloudCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSpringCloudCertificate_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSpringCloudCertificateExists(data.ResourceName), + ), + }, + data.ImportStep("key_vault_certificate_id"), + }, + }) +} + +func TestAccAzureRMSpringCloudCertificate_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_spring_cloud_certificate", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMSpringCloudCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSpringCloudCertificate_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSpringCloudCertificateExists(data.ResourceName), + ), + }, + data.RequiresImportErrorStep(testAccAzureRMSpringCloudCertificate_requiresImport), + }, + }) +} + +func testCheckAzureRMSpringCloudCertificateExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Spring Cloud Certificate not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["service_name"] + + client := acceptance.AzureProvider.Meta().(*clients.Client).AppPlatform.CertificatesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + if resp, err := client.Get(ctx, resourceGroup, serviceName, name); err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("bad: Spring Cloud Certificate %q (Spring Cloud Name %q / Resource Group %q) does not exist", name, serviceName, resourceGroup) + } + return fmt.Errorf("bad: Get on AppPlatform.CertificatesClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMSpringCloudCertificateDestroy(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).AppPlatform.CertificatesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_spring_cloud_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + resGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["service_name"] + resp, err := client.Get(ctx, resGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("bad: Get on AppPlatform.CertificatesClient: %+v", err) + } + return nil + } + return fmt.Errorf("expected no spring cloud certificate but found %+v", resp) + } + + return nil +} + +func testAccAzureRMSpringCloudCertificate_basic(data acceptance.TestData) string { + template := testAccAzureRMSpringCloudCertificate_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_spring_cloud_certificate" "test" { + name = "acctest-scc-%d" + resource_group_name = azurerm_spring_cloud_service.test.resource_group_name + service_name = azurerm_spring_cloud_service.test.name + key_vault_certificate_id = azurerm_key_vault_certificate.test.id +} +`, template, data.RandomInteger) +} + +func testAccAzureRMSpringCloudCertificate_requiresImport(data acceptance.TestData) string { + template := testAccAzureRMSpringCloudCertificate_basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_spring_cloud_certificate" "import" { + name = azurerm_spring_cloud_certificate.test.name + resource_group_name = azurerm_spring_cloud_certificate.test.resource_group_name + service_name = azurerm_spring_cloud_certificate.test.service_name + key_vault_certificate_id = azurerm_spring_cloud_certificate.test.key_vault_certificate_id +} +`, template) +} + +func testAccAzureRMSpringCloudCertificate_template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-spring-%d" + location = "%s" +} + +data "azurerm_client_config" "current" { +} + +data "azuread_service_principal" "test" { + display_name = "Azure Spring Cloud Domain-Management" +} + +resource "azurerm_key_vault" "test" { + name = "acctestkeyvault%s" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + secret_permissions = ["set"] + certificate_permissions = ["create", "delete", "get", "update"] + } + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azuread_service_principal.test.object_id + secret_permissions = ["get", "list"] + certificate_permissions = ["get", "list"] + } +} + +resource "azurerm_key_vault_certificate" "test" { + name = "acctestcert%s" + key_vault_id = azurerm_key_vault.test.id + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = true + } + + lifetime_action { + action { + action_type = "AutoRenew" + } + + trigger { + days_before_expiry = 30 + } + } + + secret_properties { + content_type = "application/x-pkcs12" + } + + x509_certificate_properties { + key_usage = [ + "cRLSign", + "dataEncipherment", + "digitalSignature", + "keyAgreement", + "keyCertSign", + "keyEncipherment", + ] + + subject = "CN=contoso.com" + validity_in_months = 12 + } + } +} + +resource "azurerm_spring_cloud_service" "test" { + name = "acctest-sc-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString, data.RandomInteger) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index c21c580df7cc..9c4e5ed65e56 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -896,6 +896,10 @@ azurerm_spring_cloud_app +
  • + azurerm_spring_cloud_certificate +
  • +
  • azurerm_spring_cloud_service
  • diff --git a/website/docs/r/spring_cloud_certificate.html.markdown b/website/docs/r/spring_cloud_certificate.html.markdown new file mode 100644 index 000000000000..8ecdcba8e38c --- /dev/null +++ b/website/docs/r/spring_cloud_certificate.html.markdown @@ -0,0 +1,146 @@ +--- +subcategory: "Spring Cloud" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_spring_cloud_certificate" +description: |- + Manages an Azure Spring Cloud Certificate. +--- + +# azurerm_spring_cloud_certificate + +Manages an Azure Spring Cloud Certificate. + +## Example Usage + +```hcl +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "Southeast Asia" +} + +data "azurerm_client_config" "current" { +} + +data "azuread_service_principal" "example" { + display_name = "Azure Spring Cloud Domain-Management" +} + +resource "azurerm_key_vault" "example" { + name = "keyvaultcertexample" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + secret_permissions = ["set"] + certificate_permissions = ["create", "delete", "get", "update"] + } + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azuread_service_principal.example.object_id + secret_permissions = ["get", "list"] + certificate_permissions = ["get", "list"] + } +} + +resource "azurerm_key_vault_certificate" "example" { + name = "cert-example" + key_vault_id = azurerm_key_vault.example.id + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = true + } + + lifetime_action { + action { + action_type = "AutoRenew" + } + + trigger { + days_before_expiry = 30 + } + } + + secret_properties { + content_type = "application/x-pkcs12" + } + + x509_certificate_properties { + key_usage = [ + "cRLSign", + "dataEncipherment", + "digitalSignature", + "keyAgreement", + "keyCertSign", + "keyEncipherment", + ] + + subject = "CN=contoso.com" + validity_in_months = 12 + } + } +} + +resource "azurerm_spring_cloud_service" "example" { + name = "example-springcloud" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location +} + +resource "azurerm_spring_cloud_certificate" "example" { + name = "example-scc" + resource_group_name = azurerm_spring_cloud_service.example.resource_group_name + service_name = azurerm_spring_cloud_service.example.name + key_vault_certificate_id = azurerm_key_vault_certificate.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Spring Cloud Certificate. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the resource group in which to create the Spring Cloud Certificate. Changing this forces a new resource to be created. + +* `service_name` - (Required) Specifies the name of the Spring Cloud Service resource. Changing this forces a new resource to be created. + +* `key_vault_certificate_id` - (Required) Specifies the ID of the Key Vault Certificate resource. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Spring Cloud Certificate. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Spring Cloud Certificate. +* `read` - (Defaults to 5 minutes) Used when retrieving the Spring Cloud Certificate. +* `delete` - (Defaults to 30 minutes) Used when deleting the Spring Cloud Certificate. + +## Import + +Spring Cloud Certificate can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_spring_cloud_certificate.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourcegroup1/providers/Microsoft.AppPlatform/Spring/spring1/certificates/cert1 +```