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_automation_certificate keeps recreating #12456

Closed
mfarrokhnia opened this issue Jul 2, 2021 · 14 comments · Fixed by #20627
Closed

azurerm_automation_certificate keeps recreating #12456

mfarrokhnia opened this issue Jul 2, 2021 · 14 comments · Fixed by #20627

Comments

@mfarrokhnia
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

I have created and applied a certificate using keyvault and assigned it to azure automation-run as account, whenever I run terraform plan it wants to recreate the certificate that is already created by terraform apply.

Terrom and Azurerm versions:
Terraform v0.15.1

azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 2.61.0"
    }

Terraform code which is applied:

resource "azurerm_key_vault_certificate" "azure_automation_cert" {
  name         = "mycertname"
  key_vault_id = azurerm_key_vault.kv.id #var.keyvault_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 = 180
      }
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }

    x509_certificate_properties {
      extended_key_usage = ["1.3.6.1.5.5.7.3.2"]

      key_usage = [
        "dataEncipherment",
        "digitalSignature",
        "keyCertSign",
        "keyEncipherment",
      ]

      subject            = "CN=${azuread_application.app.name}"
      validity_in_months = 12
    }
  }
}

data "azurerm_key_vault_secret" "certificate" {
  name = azurerm_key_vault_certificate.azure_automation_cert.name
  key_vault_id = azurerm_key_vault_certificate.azure_automation_cert.key_vault_id
  depends_on = [
    azurerm_key_vault_certificate.azure_automation_cert,
  ]
}
resource "azurerm_automation_certificate" "test" {
  name                    = "AzureRunAsCertificate"
  resource_group_name     = var.resource_group_name
  automation_account_name = "${azurerm_automation_account.auto_account.name}"
  base64                  = data.azurerm_key_vault_secret.certificate.value 
  depends_on = [
    azurerm_key_vault_certificate.azure_automation_cert,
  ]
}

resource "azurerm_automation_connection_service_principal" "test" {
  name                    = "AzureRunAsConnection"
  resource_group_name     = var.resource_group_name
  automation_account_name = "${azurerm_automation_account.auto_account.name}"
  application_id          = azuread_service_principal.sp.application_id
  tenant_id               = data.azurerm_client_config.current.tenant_id
  subscription_id         = data.azurerm_client_config.current.subscription_id
  certificate_thumbprint  = azurerm_automation_certificate.test.thumbprint
}

Debug Output

Bug->Recreating cert

$terraform plan

data "azurerm_key_vault_secret" "certificate"  {
      ~ content_type   = "application/x-pkcs12" -> (known after apply)
      ~ id             = "https://mykeyvaultname.vault.azure.net/secrets/mycertname/c2b*******" -> (known after apply)
        name           = "mycertname"
      ~ tags           = {} -> (known after apply)
      ~ value          = (sensitive value)
      ~ version        = "c2b*******" -> (known after apply)
      ~ versionless_id = "https://mykeyvaultname.vault.azure.net/secrets/mycertname" -> (known after apply)
        # (1 unchanged attribute hidden)

      + timeouts {
          + read = (known after apply)
        }
    }

  # azurerm_automation_certificate.cert_automation_account must be replaced
-/+ resource "azurerm_automation_certificate" "cert_automation_account" {
      ~ base64                  = (sensitive value)
      - description             = "" -> null
      ~ exportable              = false -> (known after apply)
      ~ id                      = "/subscriptions/my-sub-id/resourceGroups/my-rg/providers/Microsoft.Automation/automationAccounts/myaccount/certificates/AzureRunAsCertificate" -> (known after apply)
        name                    = "AzureRunAsCertificate"
      ~ thumbprint              = "849F*******" -> (known after apply)
        # (2 unchanged attributes hidden)
    }

  # azurerm_automation_connection_service_principal.sp_conn_auto_account will be updated in-place
  ~ resource "azurerm_automation_connection_service_principal" "sp_conn_auto_account" {
      ~ certificate_thumbprint  = "849F*******" -> (known after apply)
        id                      = "/subscriptions/my-sub-id/resourceGroups/my-rg/providers/Microsoft.Automation/automationAccounts/myaccount/connections/AzureRunAsConnection"
        name                    = "AzureRunAsConnection"
        # (5 unchanged attributes hidden)
    }

@markwong-synechron
Copy link

Encounter the same issue since Azurerm 2.57 and also 2.87

@lonegunmanb
Copy link
Contributor

Hi @mina69 and @markwong-citihub , I've tried to reproduce this issue with the following code but failed to reproduce:

provider "azurerm" {
  features {
    resource_group {
      prevent_deletion_if_contains_resources = false
    }
  }
}

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "example" {
  name     = "zjhe-f12456"
  location = "West Europe"
}

resource "azurerm_key_vault" "example" {
  name                = "zjhef12456"
  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            = "premium"

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    certificate_permissions = [for p in [
      "create",
      "delete",
      "deleteIssuers",
      "get",
      "getIssuers",
      "import",
      "list",
      "listIssuers",
      "manageContacts",
      "ManageIssuers",
      "SetIssuers",
      "update",
    ] : title(p)]

    key_permissions = [for op in [
      "backup",
      "create",
      "decrypt",
      "delete",
      "encrypt",
      "get",
      "import",
      "list",
      "purge",
      "recover",
      "restore",
      "sign",
      "unwrapKey",
      "update",
      "verify",
      "wrapKey",
    ]:title(op)]

    secret_permissions = [
      "Backup",
      "Delete",
      "Get",
      "List",
      "Purge",
      "Recover",
      "Restore",
      "Set",
    ]
  }
}

resource "azurerm_key_vault_certificate" "azure_automation_cert" {
  name         = "zjhef12456"
  key_vault_id = azurerm_key_vault.example.id #var.keyvault_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 = 180
      }
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }

    x509_certificate_properties {
      extended_key_usage = ["1.3.6.1.5.5.7.3.2"]

      key_usage = [
        "dataEncipherment",
        "digitalSignature",
        "keyCertSign",
        "keyEncipherment",
      ]

      subject            = "CN=test"
      validity_in_months = 12
    }
  }
}

data "azurerm_key_vault_secret" "certificate" {
  name = azurerm_key_vault_certificate.azure_automation_cert.name
  key_vault_id = azurerm_key_vault_certificate.azure_automation_cert.key_vault_id
  depends_on = [
    azurerm_key_vault_certificate.azure_automation_cert,
  ]
}

resource "azurerm_automation_account" "example" {
  name                = "zjhe-f12456"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku_name            = "Basic"

  tags = {
    environment = "development"
  }
}

resource "azurerm_automation_certificate" "test" {
  name                    = "AzureRunAsCertificate"
  resource_group_name     = azurerm_resource_group.example.name
  automation_account_name = azurerm_automation_account.example.name
  base64                  = data.azurerm_key_vault_secret.certificate.value
  depends_on = [
    azurerm_key_vault_certificate.azure_automation_cert,
  ]
}

Would you please provide a minimum sample code that could reproduce this issue? Thanks!

@markwong-synechron
Copy link

markwong-synechron commented Apr 21, 2022

resource "azurerm_automation_certificate" "csc-cert" {
  name                    = "AzureRunAsCertificate"
  resource_group_name     = var.rg_name
  automation_account_name = azurerm_automation_account.example.name
  base64                  = filebase64("${var.certificate_fullpath}")  
}

@markwong-synechron
Copy link

markwong-synechron commented Apr 21, 2022

In the TF plan the follow fields are being updated:

  • base64
  • exportable
  • id
  • thumbprint

@lonegunmanb
Copy link
Contributor

Hi @markwong-citihub , I tried the following code but I cannot reproduce this issue:

provider "azurerm" {
  features {
    resource_group {
      prevent_deletion_if_contains_resources = false
    }
  }
}

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "example" {
  name     = "zjhe-f12456"
  location = "West Europe"
}

resource "azurerm_key_vault" "example" {
  name                = "zjhef12456"
  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            = "premium"

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    certificate_permissions = [for p in [
      "create",
      "delete",
      "deleteIssuers",
      "get",
      "getIssuers",
      "import",
      "list",
      "listIssuers",
      "manageContacts",
      "ManageIssuers",
      "SetIssuers",
      "update",
    ] : title(p)]

    key_permissions = [for op in [
      "backup",
      "create",
      "decrypt",
      "delete",
      "encrypt",
      "get",
      "import",
      "list",
      "purge",
      "recover",
      "restore",
      "sign",
      "unwrapKey",
      "update",
      "verify",
      "wrapKey",
    ]:title(op)]

    secret_permissions = [
      "Backup",
      "Delete",
      "Get",
      "List",
      "Purge",
      "Recover",
      "Restore",
      "Set",
    ]
  }
}

resource "azurerm_key_vault_certificate" "azure_automation_cert" {
  name         = "zjhef12456"
  key_vault_id = azurerm_key_vault.example.id #var.keyvault_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 = 180
      }
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }

    x509_certificate_properties {
      extended_key_usage = ["1.3.6.1.5.5.7.3.2"]

      key_usage = [
        "dataEncipherment",
        "digitalSignature",
        "keyCertSign",
        "keyEncipherment",
      ]

      subject            = "CN=test"
      validity_in_months = 12
    }
  }
}

data "azurerm_key_vault_secret" "certificate" {
  name = azurerm_key_vault_certificate.azure_automation_cert.name
  key_vault_id = azurerm_key_vault_certificate.azure_automation_cert.key_vault_id
  depends_on = [
    azurerm_key_vault_certificate.azure_automation_cert,
  ]
}

resource "azurerm_automation_account" "example" {
  name                = "zjhe-f12456"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku_name            = "Basic"

  tags = {
    environment = "development"
  }
}

resource "azurerm_automation_certificate" "test" {
  name                    = "AzureRunAsCertificate"
  resource_group_name     = azurerm_resource_group.example.name
  automation_account_name = azurerm_automation_account.example.name
  base64                  = filebase64("${path.module}/automation_certificate_test.pfx")
  depends_on = [
    azurerm_key_vault_certificate.azure_automation_cert,
  ]
}

After apply, the terraform plan generated no update. Would you please provide your terraform plan output? And if you can provide a minimum sample code that could reproduce this issue, it'll be a great help to solve this issue. Thanks!

@markwong-synechron
Copy link

This particular example is on terraform 0.13.6 but the same issue persist in 1.0.11

12456-1
12456-2
12456-3

Sorry for the messy screenshot. Company policy block me from copy can paste code.

@lonegunmanb
Copy link
Contributor

Hi @markwong-citihub , thank you for your detailed information. I've checked the code, the document missed something, that changing base64 argument would cause a recreation. Would you please check that the base64 content has not been changed? You can access the content via terraform console command, just input module.xxxxxx.app-csc-cert.base64 then you can see the content. Would you please verify that the base64 content has not been changed? Thanks!

lonegunmanb added a commit to lonegunmanb/terraform-provider-azurerm that referenced this issue Apr 25, 2022
@markwong-synechron
Copy link

@lonegunmanb Ar... think you hit the nail on the head. Each time we run our pipeline, the Certificate's pfx file are regenerated from it's .pem format using openssl pkcs12 command. Each time the binary would be different, thus the base64 would be different. (Even it is the same certficiate with the same thumbprint) Thus, a replacement everytime.

Thanks for helping solving this mystery.

stephybun pushed a commit that referenced this issue Apr 25, 2022
@lonegunmanb
Copy link
Contributor

@markwong-citihub I'm glad that your issue has been solved! Would you please close this issue if you don't have any further question? Thanks!

@markwong-synechron
Copy link

@mina69 is the original creator. Not my issue to close. Sorry.

@lonegunmanb
Copy link
Contributor

Hello @mina69 , would you please check if base64 has been changed? The document has been corrected, now base64 is documented as ForceNew.

@lonegunmanb
Copy link
Contributor

Hello @mina69, is there any update?

@rcskosir
Copy link
Contributor

Thanks for opening this issue. Since time has passed and @lonegunmanb was not able to reproduce this issue, and documentation has been updated related to base64, I am going to close this issue. If this is still an issue with the 3.x version of the provider please do let us know by opening a new issue, thanks!

Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
5 participants