From 7d608fe99d55ad4a7022c42d3a36e4b54d836633 Mon Sep 17 00:00:00 2001 From: Joakim Bakke Hellum Date: Sun, 1 Sep 2019 20:09:12 +0200 Subject: [PATCH] New Resource: `azurerm_app_service_certificate` (#4192) Reference to #1136 --- azurerm/internal/services/web/client.go | 5 + azurerm/provider.go | 1 + .../resource_arm_app_service_certificate.go | 258 ++++++++++++++++++ ...source_arm_app_service_certificate_test.go | 227 +++++++++++++++ azurerm/testdata/app_service_certificate.pfx | Bin 0 -> 2629 bytes .../app_service_certificate_nopassword.pfx | Bin 0 -> 2629 bytes website/azurerm.erb | 4 + .../r/app_service_certificate.html.markdown | 75 +++++ 8 files changed, 570 insertions(+) create mode 100644 azurerm/resource_arm_app_service_certificate.go create mode 100644 azurerm/resource_arm_app_service_certificate_test.go create mode 100644 azurerm/testdata/app_service_certificate.pfx create mode 100644 azurerm/testdata/app_service_certificate_nopassword.pfx create mode 100644 website/docs/r/app_service_certificate.html.markdown diff --git a/azurerm/internal/services/web/client.go b/azurerm/internal/services/web/client.go index 064c3f563308..948885766f1f 100644 --- a/azurerm/internal/services/web/client.go +++ b/azurerm/internal/services/web/client.go @@ -8,6 +8,7 @@ import ( type Client struct { AppServicePlansClient *web.AppServicePlansClient AppServicesClient *web.AppsClient + CertificatesClient *web.CertificatesClient } func BuildClient(o *common.ClientOptions) *Client { @@ -18,8 +19,12 @@ func BuildClient(o *common.ClientOptions) *Client { AppServicesClient := web.NewAppsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&AppServicesClient.Client, o.ResourceManagerAuthorizer) + CertificatesClient := web.NewCertificatesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&CertificatesClient.Client, o.ResourceManagerAuthorizer) + return &Client{ AppServicePlansClient: &AppServicePlansClient, AppServicesClient: &AppServicesClient, + CertificatesClient: &CertificatesClient, } } diff --git a/azurerm/provider.go b/azurerm/provider.go index d88ec0a50b23..783beea2a52a 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -144,6 +144,7 @@ func Provider() terraform.ResourceProvider { "azurerm_api_management_subscription": resourceArmApiManagementSubscription(), "azurerm_api_management_user": resourceArmApiManagementUser(), "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), + "azurerm_app_service_certificate": resourceArmAppServiceCertificate(), "azurerm_app_service_custom_hostname_binding": resourceArmAppServiceCustomHostnameBinding(), "azurerm_app_service_plan": resourceArmAppServicePlan(), "azurerm_app_service_slot": resourceArmAppServiceSlot(), diff --git a/azurerm/resource_arm_app_service_certificate.go b/azurerm/resource_arm_app_service_certificate.go new file mode 100644 index 000000000000..320f7e625fa0 --- /dev/null +++ b/azurerm/resource_arm_app_service_certificate.go @@ -0,0 +1,258 @@ +package azurerm + +import ( + "encoding/base64" + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/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/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmAppServiceCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAppServiceCertificateCreateUpdate, + Read: resourceArmAppServiceCertificateRead, + Update: resourceArmAppServiceCertificateCreateUpdate, + Delete: resourceArmAppServiceCertificateDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "pfx_blob": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ForceNew: true, + ValidateFunc: validate.Base64String(), + }, + + "password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ForceNew: true, + ValidateFunc: validation.NoZeroValues, + }, + + "key_vault_secret_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: azure.ValidateKeyVaultChildId, + ConflictsWith: []string{"pfx_blob", "password"}, + }, + + "friendly_name": { + Type: schema.TypeString, + Computed: true, + }, + + "subject_name": { + Type: schema.TypeString, + Computed: true, + }, + + "host_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "issuer": { + Type: schema.TypeString, + Computed: true, + }, + + "issue_date": { + Type: schema.TypeString, + Computed: true, + }, + + "expiration_date": { + Type: schema.TypeString, + Computed: true, + }, + + "thumbprint": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmAppServiceCertificateCreateUpdate(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).web.CertificatesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for App Service Certificate creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + pfxBlob := d.Get("pfx_blob").(string) + password := d.Get("password").(string) + keyVaultSecretId := d.Get("key_vault_secret_id").(string) + t := d.Get("tags").(map[string]interface{}) + + if pfxBlob == "" && keyVaultSecretId == "" { + return fmt.Errorf("Either `pfx_blob` or `key_vault_secret_id` must be set") + } + + if requireResourcesToBeImported && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing App Service Certificate %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_app_service_certificate", *existing.ID) + } + } + + certificate := web.Certificate{ + CertificateProperties: &web.CertificateProperties{ + Password: utils.String(password), + }, + Location: utils.String(location), + Tags: tags.Expand(t), + } + + if pfxBlob != "" { + decodedPfxBlob, err := base64.StdEncoding.DecodeString(pfxBlob) + if err != nil { + return fmt.Errorf("Could not decode PFX blob: %+v", err) + } + certificate.CertificateProperties.PfxBlob = &decodedPfxBlob + } + + if keyVaultSecretId != "" { + parsedSecretId, err := azure.ParseKeyVaultChildID(keyVaultSecretId) + if err != nil { + return err + } + + keyVaultBaseUrl := parsedSecretId.KeyVaultBaseUrl + + keyVaultId, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUrl) + if err != nil { + return fmt.Errorf("Error retrieving the Resource ID for the Key Vault at URL %q: %s", keyVaultBaseUrl, err) + } + if keyVaultId == nil { + return fmt.Errorf("Unable to determine the Resource ID for the Key Vault at URL %q", keyVaultBaseUrl) + } + + certificate.CertificateProperties.KeyVaultID = keyVaultId + certificate.CertificateProperties.KeyVaultSecretName = utils.String(parsedSecretId.Name) + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, certificate); err != nil { + return fmt.Errorf("Error creating/updating App Service Certificate %q (Resource Group %q): %s", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving App Service Certificate %q (Resource Group %q): %s", name, resourceGroup, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read App Service Certificate %q (Resource Group %q) ID", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmAppServiceCertificateRead(d, meta) +} + +func resourceArmAppServiceCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).web.CertificatesClient + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["certificates"] + + ctx := meta.(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] App Service Certificate %q (Resource Group %q) was not found - removing from state", name, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on App Service Certificate %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.CertificateProperties; props != nil { + d.Set("friendly_name", props.FriendlyName) + d.Set("subject_name", props.SubjectName) + d.Set("host_names", props.HostNames) + d.Set("issuer", props.Issuer) + d.Set("issue_date", props.IssueDate.Format(time.RFC3339)) + d.Set("expiration_date", props.ExpirationDate.Format(time.RFC3339)) + d.Set("thumbprint", props.Thumbprint) + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmAppServiceCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).web.CertificatesClient + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["certificates"] + + log.Printf("[DEBUG] Deleting App Service Certificate %q (Resource Group %q)", name, resourceGroup) + + ctx := meta.(*ArmClient).StopContext + resp, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting App Service Certificate %q (Resource Group %q): %s)", name, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_app_service_certificate_test.go b/azurerm/resource_arm_app_service_certificate_test.go new file mode 100644 index 000000000000..d28e419a4bb6 --- /dev/null +++ b/azurerm/resource_arm_app_service_certificate_test.go @@ -0,0 +1,227 @@ +package azurerm + +import ( + "fmt" + "testing" + + "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 TestAccAzureRMAppServiceCertificate_Pfx(t *testing.T) { + resourceName := "azurerm_app_service_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + config := testAccAzureRMAppServiceCertificatePfx(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "password", "terraform"), + resource.TestCheckResourceAttr(resourceName, "thumbprint", "7B985BF42467791F23E52B364A3E8DEBAB9C606E"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"pfx_blob", "password"}, + }, + }, + }) +} + +func TestAccAzureRMAppServiceCertificate_PfxNoPassword(t *testing.T) { + resourceName := "azurerm_app_service_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + config := testAccAzureRMAppServiceCertificatePfxNoPassword(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "thumbprint", "7B985BF42467791F23E52B364A3E8DEBAB9C606E"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"pfx_blob"}, + }, + }, + }) +} + +func TestAccAzureRMAppServiceCertificate_KeyVault(t *testing.T) { + resourceName := "azurerm_app_service_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + config := testAccAzureRMAppServiceCertificateKeyVault(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "thumbprint", "7B985BF42467791F23E52B364A3E8DEBAB9C606E"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_vault_secret_id"}, + }, + }, + }) +} + +func testAccAzureRMAppServiceCertificatePfx(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestwebcert%d" + location = "%s" +} + +resource "azurerm_app_service_certificate" "test" { + name = "acctest%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + pfx_blob = filebase64("testdata/app_service_certificate.pfx") + password = "terraform" +} +`, rInt, location, rInt) +} + +func testAccAzureRMAppServiceCertificatePfxNoPassword(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestwebcert%d" + location = "%s" +} + +resource "azurerm_app_service_certificate" "test" { + name = "acctest%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + pfx_blob = filebase64("testdata/app_service_certificate_nopassword.pfx") +} +`, rInt, location, rInt) +} + +func testAccAzureRMAppServiceCertificateKeyVault(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "test" {} + +data "azuread_service_principal" "test" { + display_name = "Microsoft Azure App Service" +} + +resource "azurerm_resource_group" "test" { + name = "acctestwebcert%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "acct%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + tenant_id = data.azurerm_client_config.test.tenant_id + + sku_name = "standard" + + access_policy { + tenant_id = data.azurerm_client_config.test.tenant_id + object_id = data.azurerm_client_config.test.service_principal_object_id + secret_permissions = ["delete", "get", "set"] + certificate_permissions = ["create", "delete", "get", "import"] + } + + access_policy { + tenant_id = data.azurerm_client_config.test.tenant_id + object_id = data.azuread_service_principal.test.object_id + secret_permissions = ["get"] + certificate_permissions = ["get"] + } +} + +resource "azurerm_key_vault_certificate" "test" { + name = "acctest%d" + key_vault_id = azurerm_key_vault.test.id + + certificate { + contents = filebase64("testdata/app_service_certificate.pfx") + password = "terraform" + } + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = false + } + + secret_properties { + content_type = "application/x-pkcs12" + } + } +} + +resource "azurerm_app_service_certificate" "test" { + name = "acctest%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + key_vault_secret_id = azurerm_key_vault_certificate.test.id +} +`, rInt, location, rInt, rInt, rInt) +} + +func testCheckAzureRMAppServiceCertificateDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).web.CertificatesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_app_service_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + + return nil +} diff --git a/azurerm/testdata/app_service_certificate.pfx b/azurerm/testdata/app_service_certificate.pfx new file mode 100644 index 0000000000000000000000000000000000000000..ddcfb937654a5d05de304b195e57742df9eb7e32 GIT binary patch literal 2629 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 literal 0 HcmV?d00001 diff --git a/azurerm/testdata/app_service_certificate_nopassword.pfx b/azurerm/testdata/app_service_certificate_nopassword.pfx new file mode 100644 index 0000000000000000000000000000000000000000..be04af726a1b6193c9eabae616e2d822322b6ad8 GIT binary patch literal 2629 zcmY+^c{CJ^8U}F7nBAT%qZr#4!!)uCLiT;%O}3IfiR?=lgRH|?BC=OwiHealW69W; zz7)oiERiLWRD`;9&b{}$_mB6y=RD6j&!0aG9;(g4%!F~u+bRX>;@F}%8=u{ zCKGb97y)VPT-$KX?NpcOZn=O_*On+KBt4{aL@X8uov_dETDX`mSj*?=qa*mpxJQj^ ztd3ulcYbb)v<>r~od;132-~L{EZA19_k7vvSXK%83sFW>p|Z}y0QzwN0RE!uwK5SSAx-f*JJZx6BlV0f(8W12pdLhfmoggQ7Aqw{Usx&r0FtzdD4c zjk8=5>0LijDwkXN&6+l9>1#T<5d}3CbZL3}W0}@1x{Y16dibTRP-1Ae5jJ-F$J$27 zA+YniFYDgoZFHZonUnHqBO_n`9)qE7d$v5{J&6Yhug*4RzIOvtwp~#xf&E`14gn&vXb-mW&(4W@6T<5U>iI>y-&tK1^-4&|5TrR)iT8N$dDM(DV9+LHm zC!R}Gzr3C^Q5bXIYW|A&?KULOpt=JzAcW_I%-FgppmWr)x8~Wz>lxb)>!Iy%Ml;YUL`T*wUe6b}kSTVExez*3oDk2OE4#Dm6Bp8CG3^X5gb5}S2a#2_1X8{ zARG#3*ci)=J_-S=3=+xvuFY;sZ|Gg@R`=ds^wU%SiMlN3_+2Ib_yJq#skBkUW=r%# zms3T2_1)H4!6%OM$dwB>|8_GVk%JI%OD^qtJmwfYoA&>JRDowZ2f(wTf5$SvPYMY8 z4^L2LmfwzT{|0R1|I}jrqZTw50qbo8H~vuzfCmg%OR~MuJ^@bh%{yvT|7PA4c36`! zr89fqqS;ni2X4^}I}k7Yaid+(y
Hb?+fN+U0Wx-2B$`mG^-&#f`MpEX4ycP5eU z81{zYl)g$%OMMrXIrW9r{rMe*;!8A!Np?n_K@sEm$$*2$OB$K;dm-H%!DmX_f~LfB z>Al5w3Xbv}waXAyih#8N?=JrG*HUzz-g%Qim)-fGAvMM`q4i*n^ZAR6 zWbL3L{kE?kbZg0~EVIS5Pe69y#*2xwjjh6EySt*0s2iI+)}CkwqMau;5gfy@x|sCT zIJ=UR)!-uEapJ%`wQ5(>>2d{O_-)X1&-aW9p?JyDUkCqgtMd`Y`JBEoS~%Xs%VMUa z+iCY4{n3r3jZ5HS$0)mV4t3y1uSdPM+|zrjCn*$R{(I;(&01Ife%2$JLA5*gdV2y$ z7`K@kR`W436@(2E2!vEwHP{NFTL<>0l=RFGrW8MBQeuq;MWdJoF&_pHp_E{cQ}6CX z7R`;%xqnI-Q7X-HSB}JitZ0fJpIeml2K-lybpqZv=IQ4UI7DH^t{I z4W5M|T5Ld9ZhYyFijU13$$u?E(w&c|nq%6{LU^P>RgQfUp@ss`Nh zvmlP$oamXp29xIbv6yX%dwdBLbw^J_QQ3p&y(ebgdsb6(bfQq(=!v4Eh69{1-u#Y$ zjxdd!Jj8#u?eQc2w+6GLN>TT#f| zFIUAMG#cHECR1Za1%;$eeF-f0aH>z20M_~kt}FdzA|LqWrHLs!ronedFu#Bf_Dmn5 zo-dZl;?vA$0PSC&QiE6JJpFbCR+tds$2y$MaDHXs=zsAEw3m43mwK!{D_iQAku&oo z^S$_BkKkjia=YjD%LG9Is~P4h{2{eX%UU(`y*x#cN@r9xEtkEWF(e{Rjl0C-Hbhw* znq}J4)gmSr+bRi?plsWGBH|(xXz=hFd3(dPNH;9>?j{7 z^%?de5=hySo3eIX=6FL6B@33#$G)Sc#XJBIifPWgJ`G{!hp=V?mvd#qqw(_}v-n!z zh$YfPh3AO!L)PBRndosa^8B<6lZ@o5gzlB1vs3Q)uOY;MmqYf`alC4(=1DET zDsCE{1q0-_Aj7SqK5b2KCQL_WlbaAF#?H(L==f8002a(GM-l@i7eO+)jOE7OR)o~H zKCQErm&AzwS4Rk+{7Jxxn4*h&5m(CcuQI2_?(SWPVR6r?I9^0C>}sD7rzyK>sNDFNOTaegFUf literal 0 HcmV?d00001 diff --git a/website/azurerm.erb b/website/azurerm.erb index a41c178da62d..c7781eb28ad2 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -490,6 +490,10 @@ azurerm_app_service_active_slot +
  • + azurerm_app_service_certificate +
  • +
  • azurerm_app_service_custom_hostname_binding
  • diff --git a/website/docs/r/app_service_certificate.html.markdown b/website/docs/r/app_service_certificate.html.markdown new file mode 100644 index 000000000000..84ce8a197c60 --- /dev/null +++ b/website/docs/r/app_service_certificate.html.markdown @@ -0,0 +1,75 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_app_service_certificate" +sidebar_current: "docs-azurerm-resource-app-service-certificate" +description: |- + Manages an App Service certificate. + +--- + +# azurerm_app_service_certificate + +Manages an App Service certificate. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_app_service_certificate" "example" { + name = "example-cert" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + pfx_blob = "${filebase64("certificate.pfx")}" + password = "terraform" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the certificate. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the certificate. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `pfx_blob` - (Optional) The base64-encoded contents of the certificate. Changing this forces a new resource to be created. + +-> **NOTE:** Either `pfx_blob` or `key_vault_secret_id` must be set - but not both. + +* `password` - (Optional) The password to access the certificate's private key. Changing this forces a new resource to be created. + +* `key_vault_secret_id` - (Optional) The ID of the Key Vault secret. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The App Service certificate ID. + +* `friendly_name` - The friendly name of the certificate. + +* `subject_name` - The subject name of the certificate. + +* `host_names` - List of host names the certificate applies to. + +* `issuer` - The name of the certificate issuer. + +* `issue_date` - The issue date for the certificate. + +* `expiration_date` - The expiration date for the certificate. + +* `thumbprint` - The thumbprint for the certificate. + +## Import + +App Service certificates can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_app_certificate.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/certificates/certificate1 +```