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

azurerm_app_service_certificate - support for hosting_environment_profile_id #7087

Merged
merged 8 commits into from Jun 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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