Skip to content

Commit

Permalink
azurerm_app_service_certificate - support for hosting_environment_pro…
Browse files Browse the repository at this point in the history
…file_id (#7087)

Co-authored-by: David Daniel <dhdanie@gmail.com>
  • Loading branch information
wmdave and dhdanie committed Jun 16, 2020
1 parent ba278ba commit 339934e
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
Expand Up @@ -73,6 +73,12 @@ func resourceArmAppServiceCertificate() *schema.Resource {
ConflictsWith: []string{"pfx_blob", "password"},
},

"hosting_environment_profile_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"friendly_name": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -130,6 +136,7 @@ func resourceArmAppServiceCertificateCreateUpdate(d *schema.ResourceData, meta i
pfxBlob := d.Get("pfx_blob").(string)
password := d.Get("password").(string)
keyVaultSecretId := d.Get("key_vault_secret_id").(string)
hostingEnvironmentProfileId := d.Get("hosting_environment_profile_id").(string)
t := d.Get("tags").(map[string]interface{})

if pfxBlob == "" && keyVaultSecretId == "" {
Expand Down Expand Up @@ -157,6 +164,12 @@ func resourceArmAppServiceCertificateCreateUpdate(d *schema.ResourceData, meta i
Tags: tags.Expand(t),
}

if len(hostingEnvironmentProfileId) > 0 {
certificate.CertificateProperties.HostingEnvironmentProfile = &web.HostingEnvironmentProfile{
ID: &hostingEnvironmentProfileId,
}
}

if pfxBlob != "" {
decodedPfxBlob, err := base64.StdEncoding.DecodeString(pfxBlob)
if err != nil {
Expand Down Expand Up @@ -237,6 +250,10 @@ func resourceArmAppServiceCertificateRead(d *schema.ResourceData, meta interface
d.Set("issue_date", props.IssueDate.Format(time.RFC3339))
d.Set("expiration_date", props.ExpirationDate.Format(time.RFC3339))
d.Set("thumbprint", props.Thumbprint)

if hep := props.HostingEnvironmentProfile; hep != nil {
d.Set("hosting_environment_profile_id", hep.ID)
}
}

return tags.FlattenAndSet(d, resp.Tags)
Expand Down
Expand Up @@ -139,6 +139,26 @@ func TestAccAzureRMAppServiceEnvironment_dedicatedResourceGroup(t *testing.T) {
})
}

func TestAccAzureRMAppServiceEnvironment_withCertificatePfx(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_app_service_environment", "test")
certData := acceptance.BuildTestData(t, "azurerm_app_service_certificate", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMAppServiceEnvironmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMAppServiceEnvironment_withCertificatePfx(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMCertHostingEnvProfileIdMatchesAseId(data.ResourceName, certData.ResourceName),
),
},
data.ImportStep(),
},
})
}

func testCheckAzureRMAppServiceEnvironmentExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).Web.AppServiceEnvironmentsClient
Expand Down Expand Up @@ -168,6 +188,45 @@ func testCheckAzureRMAppServiceEnvironmentExists(resourceName string) resource.T
}
}

func testCheckAzureRMCertHostingEnvProfileIdMatchesAseId(aseResourceName, certResourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
certsConn := acceptance.AzureProvider.Meta().(*clients.Client).Web.CertificatesClient
ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext

aseRs, ok := s.RootModule().Resources[aseResourceName]
if !ok {
return fmt.Errorf("Not found: %s", aseResourceName)
}
certRs, ok := s.RootModule().Resources[certResourceName]
if !ok {
return fmt.Errorf("Not found: %s", certResourceName)
}

aseId := aseRs.Primary.Attributes["id"]

certName := certRs.Primary.Attributes["name"]
certResourceGroup, hasResourceGroup := certRs.Primary.Attributes["resource_group_name"]
if !hasResourceGroup {
return fmt.Errorf("Bad: no resource group found in state for Certificate: %s", certName)
}

certResp, err := certsConn.Get(ctx, certResourceGroup, certName)
if err != nil {
if utils.ResponseWasNotFound(certResp.Response) {
return fmt.Errorf("Bad: Certificatet %q (resource group: %q) does not exist", certName, certResourceGroup)
}

return fmt.Errorf("Bad: Get on certificatesClient: %+v", err)
}

if *certResp.HostingEnvironmentProfile.ID != aseId {
return fmt.Errorf("Bad: Certificate hostingEnvironmentProfile.ID (%s) not equal to ASE ID (%s)", *certResp.HostingEnvironmentProfile.ID, aseId)
}

return nil
}
}

func testCheckAzureRMAppServiceEnvironmentDestroy(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).Web.AppServiceEnvironmentsClient

Expand Down Expand Up @@ -271,6 +330,22 @@ resource "azurerm_app_service_environment" "test" {
`, template, data.RandomInteger, data.Locations.Secondary)
}

func testAccAzureRMAppServiceEnvironment_withCertificatePfx(data acceptance.TestData) string {
template := testAccAzureRMAppServiceEnvironment_basic(data)
return fmt.Sprintf(`
%s
resource "azurerm_app_service_certificate" "test" {
name = "acctest-cert-%d"
resource_group_name = azurerm_app_service_environment.test.resource_group_name
location = azurerm_resource_group.test.location
pfx_blob = filebase64("testdata/app_service_certificate.pfx")
password = "terraform"
hosting_environment_profile_id = azurerm_app_service_environment.test.id
}
`, template, data.RandomInteger)
}

func testAccAzureRMAppServiceEnvironment_template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/app_service_certificate.html.markdown
Expand Up @@ -47,6 +47,8 @@ The following arguments are supported:

* `password` - (Optional) The password to access the certificate's private key. Changing this forces a new resource to be created.

* `hosting_environment_profile_id` - (Optional) Must be specified when the certificate is for an App Service Environment hosted App Service. 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.

-> **NOTE:** If using `key_vault_secret_id`, the WebApp Service Resource Principal ID `abfa0a7c-a6b6-4736-8310-5855508787cd` must have 'Secret -> get' and 'Certificate -> get' permissions on the Key Vault containing the certificate. (Source: [App Service Blog](https://azure.github.io/AppService/2016/05/24/Deploying-Azure-Web-App-Certificate-through-Key-Vault.html)) If you use Terraform to create the access policy you have to specify the Object ID of this Principal. This Object ID can be retrieved via following data reference, since it is different in every AAD Tenant:
Expand Down

0 comments on commit 339934e

Please sign in to comment.