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

bugfix: azuread_application - delete password block #1430

Merged
merged 3 commits into from
Oct 18, 2024

Conversation

HappyTobi
Copy link
Contributor

FIX:
Update function of application resource to update / remove the password when the inline password block is removed.

@HappyTobi HappyTobi force-pushed the remove-app-password branch from 89227cd to d1fb644 Compare July 11, 2024 08:55
@github-actions github-actions bot added size/M and removed size/S labels Jul 11, 2024
@HappyTobi HappyTobi force-pushed the remove-app-password branch 2 times, most recently from 00f3897 to 8709641 Compare October 1, 2024 12:30
@HappyTobi HappyTobi force-pushed the remove-app-password branch from 8709641 to ccdebd9 Compare October 1, 2024 12:31
@HappyTobi
Copy link
Contributor Author

HappyTobi commented Oct 1, 2024

Hi @katbyte

I update the pr and run all the required tests:

make testacc TESTARGS='-run=TestAccApplicationPassword_with_ApplicationInlinePassword'
make testacc TESTARGS='-run=TestAccApplication_PasswordSetAndRemove'

Both passed without any issue.

Can you please take a look the the rebased pr?

Copy link
Member

@jackofallops jackofallops left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @HappyTobi - Thanks for this, just a couple minor changes to take a look at below if you could, and then I think this will be good to go.

Copy link
Member

@jackofallops jackofallops left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @HappyTobi - this LGTM now 👍

@jackofallops jackofallops merged commit 656030a into hashicorp:main Oct 18, 2024
25 checks passed
jackofallops added a commit that referenced this pull request Oct 18, 2024
@andersthorbeck
Copy link

AzureAD (Entra ID) application passwords can be represented in Terraform in two ways:

These both affect the same password property of an Entra ID application.

The changes from this PR was rolled into release v3.1.0, which was released yesterday.

When running terraform plan with provider azuread version v3.1.0, I suddenly get a number of azuread_application resources planned to be updated, to remove the password block. Redacted example:

  # azuread_application.my_application will be updated in-place
  ~ resource "azuread_application" "my_application" {
        id                             = "/applications/12345678-abcd-1234-1234-1234567890ab"
        tags                           = []
        # (25 unchanged attributes hidden)

      - password {
          # At least one attribute in this block is (or was) sensitive,
          # so its contents will not be displayed.
        }

        # (8 unchanged blocks hidden)
    }

The majority of these affected azuread_application resources have corresponding azuread_application_password resources:

resource "azuread_application_password" "my_application" {
  application_id = azuread_application.my_application.id
  display_name   = "terraform managed"
  end_date       = "2025-03-30T09:00:00Z"
}

@HappyTobi @jackofallops My question is this:
These planned changes to delete the password block form the azuread_application resources: will they delete the actual password of the Entra ID applications, even though there exist separate azuread_application_password resources representing these passwords? If so, that doesn't sound intentional. Is there any sensible way to avoid this?

@patst
Copy link

patst commented Jan 17, 2025

AzureAD (Entra ID) application passwords can be represented in Terraform in two ways:

These both affect the same password property of an Entra ID application.

The changes from this PR was rolled into release v3.1.0, which was released yesterday.

When running terraform plan with provider azuread version v3.1.0, I suddenly get a number of azuread_application resources planned to be updated, to remove the password block. Redacted example:

  # azuread_application.my_application will be updated in-place
  ~ resource "azuread_application" "my_application" {
        id                             = "/applications/12345678-abcd-1234-1234-1234567890ab"
        tags                           = []
        # (25 unchanged attributes hidden)

      - password {
          # At least one attribute in this block is (or was) sensitive,
          # so its contents will not be displayed.
        }

        # (8 unchanged blocks hidden)
    }

The majority of these affected azuread_application resources have corresponding azuread_application_password resources:

resource "azuread_application_password" "my_application" {
  application_id = azuread_application.my_application.id
  display_name   = "terraform managed"
  end_date       = "2025-03-30T09:00:00Z"
}

@HappyTobi @jackofallops My question is this: These planned changes to delete the password block form the azuread_application resources: will they delete the actual password of the Entra ID applications, even though there exist separate azuread_application_password resources representing these passwords? If so, that doesn't sound intentional. Is there any sensible way to avoid this?

we observed the same behaviour, which is really annoying.

After another run of terraform apply, the passwords are getting recreated by the azuread_application_password resource, but in between the passwords are gone.

Which is annoying and surprising at the same time.

@mrtireyIH
Copy link

mrtireyIH commented Jan 17, 2025

We are experiencing the same issue reported by others in this thread with our Terraform Plan overnight after upgrading from azuread v3.0.2 to v3.1.0. A total of 43 service principals showed changes, and passwords may have been deleted. This is highly disruptive. Upon cross-referencing the 43 service principals, we found that some had their secrets deleted while others did not.

@HappyTobi
Copy link
Contributor Author

HappyTobi commented Jan 17, 2025

AzureAD (Entra ID) application passwords can be represented in Terraform in two ways:

These both affect the same password property of an Entra ID application.

The changes from this PR was rolled into release v3.1.0, which was released yesterday.

When running terraform plan with provider azuread version v3.1.0, I suddenly get a number of azuread_application resources planned to be updated, to remove the password block. Redacted example:

  # azuread_application.my_application will be updated in-place
  ~ resource "azuread_application" "my_application" {
        id                             = "/applications/12345678-abcd-1234-1234-1234567890ab"
        tags                           = []
        # (25 unchanged attributes hidden)

      - password {
          # At least one attribute in this block is (or was) sensitive,
          # so its contents will not be displayed.
        }

        # (8 unchanged blocks hidden)
    }

The majority of these affected azuread_application resources have corresponding azuread_application_password resources:

resource "azuread_application_password" "my_application" {
  application_id = azuread_application.my_application.id
  display_name   = "terraform managed"
  end_date       = "2025-03-30T09:00:00Z"
}

@HappyTobi @jackofallops My question is this: These planned changes to delete the password block form the azuread_application resources: will they delete the actual password of the Entra ID applications, even though there exist separate azuread_application_password resources representing these passwords? If so, that doesn't sound intentional. Is there any sensible way to avoid this?

Hi @andersthorbeck
Thanks for reporting the issue.

To you question:
The application itself will not be deleted (see your output) only the inline password definition.
The azuread_application_password is independent from the inline one so you have 2 secrets and the external one is not touched.

The password resources / secrets are handled by the "keyId". You can see the keyId in your terraform state file and at Microsoft Entra Id as Secret ID

I will try to reproduce the issue to check why that happen.

What I can tell you at the moment is, when you create the application with the latest release release v3.1.0 and do a plan after the apply you don't see any changes.

Update:
I cant reproduce the issue when I update from 2.5.3 to 3.1.0.

@enorlando
Copy link

We are experiencing the same behaviour. How do we avoid this as it is highly disruptive?

@HappyTobi
Copy link
Contributor Author

@enorlando like mentioned, I'm currently not able to reproduce the issue.
Can you share a bit more that I'm able the reproduce the issue please.

@patst
Copy link

patst commented Jan 20, 2025

@enorlando like mentioned, I'm currently not able to reproduce the issue. Can you share a bit more that I'm able the reproduce the issue please.

I think the steps are quite simple:

With the old provider version create:

  • an azuread_application
  • an azuread_application_password for that application

Upgrade the provider and run terraform apply.
As a result the secret will be deleted in the Azure Portal.

Another Terraform apply will then create a new secret, because the azuread_application_password resource detected it does not exist.

After that everything works fine. Since we use the passwords only in the same terraform module we just run apply twice to get it fixed once.
Nevertheless it ended in a unwanted downtime until we recognized the root cause

@HappyTobi
Copy link
Contributor Author

Yes that is what I also have done.

I used the following snippet and I cant reproduce the issue:

terraform {
  required_providers {
    azuread = {
      source  = "hashicorp/azuread"
      version = "= 2.5.3" #"=3.1.0"
    }
  }
}

data "azuread_client_config" "current" {}

resource "azuread_application" "app_tf_example" {
  display_name = "terraform-test-user"
  owners           = [data.azuread_client_config.current.object_id  ]

  password {
    display_name = "MySecret-1"
  }
}

resource "azuread_application_password" "my_application" {
  application_id = azuread_application.app_tf_example.id
  display_name   = "terraform managed"
  end_date       = "2025-03-30T09:00:00Z"
}

output "secret" {
  sensitive = true
  value =  tolist(azuread_application.app_tf_example.password).0.value
}

@andersthorbeck
Copy link

Hi @andersthorbeck Thanks for reporting the issue.

To you question: The application itself will not be deleted (see your output) only the inline password definition.

@HappyTobi Indeed, I was not worried about the deletion of the application itself, but of its password, which may be used in a number of different contexts to authenticate as the application and thus acquire the required access to perform whichever Azure actions the application (or corresponding service principal) has been granted roles for.

The azuread_application_password is independent from the inline one so you have 2 secrets and the external one is not touched.

The password resources / secrets are handled by the "keyId". You can see the keyId in your terraform state file and at Microsoft Entra Id as Secret ID

You say that the azuread_application.my_application.password password and azuread_application_password.my_application password are different. Judging by the fact that it seems applications can have multiple passwords, I guess it's theoretically true that they could be different.

However, our experience when merging the tfupdate pull request in one of our Terraform repositories, which changed only the azuread version from 3.0.2 to 3.1.0, was that both azuread_application.my_application.password and azuread_application_password.my_application in fact referenced the same password.

This was implied by the terraform plan of the PR bumping azuread to 3.1.0, to delete a password which had never been explicitly defined in the azuread_application resource:

  # azuread_application.my_application will be updated in-place
  ~ resource "azuread_application" "my_application" {
        id                             = "/applications/12345678-abcd-1234-1234-1234567890ab"
        tags                           = []
        # (25 unchanged attributes hidden)

      - password {
          # At least one attribute in this block is (or was) sensitive,
          # so its contents will not be displayed.
        }

        # (6 unchanged blocks hidden)
    }

and the corresponding terraform apply run log:

module.my_application.azuread_application.main: Modifying... [id=/applications/12345678-abcd-1234-1234-1234567890ab]
module.my_application.azuread_application.main: Modifications complete after 26s [id=/applications/12345678-abcd-1234-1234-1234567890ab]

which was then followed, in the subsequent Terraform plan (from the next PR) of the same Terraform state, by a plan to create an azuread_application_password tied to that very same azuread_application:

  # azuread_application_password.my_application will be created
  + resource "azuread_application_password" "my_application" {
      + application_id = "/applications/12345678-abcd-1234-1234-1234567890ab"
      + display_name   = (known after apply)
      + end_date       = "2099-01-01T01:02:03Z"
      + id             = (known after apply)
      + key_id         = (known after apply)
      + start_date     = (known after apply)
      + value          = (sensitive value)
    }

with terraform apply run log:

module.bgr.azuread_application_password.main: Creating...
module.bgr.azuread_application_password.main: Creation complete after 6s [id=12345678-abcd-1234-1234-1234567890ab/password/87654321-abcd-1234-1234-ba0987654321]

This is corroborated by looking at the Terraform statefile for a Terraform state where we did not bump to azuread 3.1.0, but are still on 3.0.2.
In that state, I was able to verify that the password of the azuread_application has the same key_id as the separate azuread_application_password resource. Neither the azuread_application nor the azuread_application_password resource config here has been touched since before the password block was released in 2.53.0.

$ terraform show -json | jq '.values.root_module | ((.resources[] | select(.address == "azuread_application.my_other_application") | [{address, values: .values | {id, password}}]) + (.resources[] | select(.address == "azuread_application_password.my_other_application") | [{address, values: .values | {application_id, id, key_id}}]))'
[
  {
    "address": "azuread_application.my_other_application",
    "values": {
      "id": "/applications/34567890-abcd-1234-1234-1234567890ab",
      "password": [
        {
          "display_name": "terraform managed",
          "end_date": "2025-03-30T09:00:00Z",
          "key_id": "567890ab-abcd-1234-1234-1234567890ab",
          "start_date": "2024-04-03T11:30:18.4182226Z",
          "value": ""
        }
      ]
    }
  },
  {
    "address": "azuread_application_password.my_other_application",
    "values": {
      "application_id": "/applications/34567890-abcd-1234-1234-1234567890ab",
      "id": "34567890-abcd-1234-1234-1234567890ab/password/567890ab-abcd-1234-1234-1234567890ab",
      "key_id": "567890ab-abcd-1234-1234-1234567890ab"
    }
  }
]

I will try to reproduce the issue to check why that happen.

What I can tell you at the moment is, when you create the application with the latest release release v3.1.0 and do a plan after the apply you don't see any changes.

Update: I cant reproduce the issue when I update from 2.5.3 to 3.1.0.

For the record, I tried my best to reproduce this from scratch myself, using only an azuread_application resource and a azuread_application_password, but was unable to. I tried bumping from azuread versions 2.14.0 to 2.52.0 to 2.53.0 to 3.0.2 to 3.1.0, but I couldn't reproduce the unexpected Terraform plan.

@klemmari1
Copy link

klemmari1 commented Jan 21, 2025

This change will delete all azuread_application secrets that are created with the az CLI, even though the secrets are not referenced in terraform

az ad sp create-for-rbac --name YOUR_APP_NAME

@andersthorbeck
Copy link

However, our experience when merging the tfupdate pull request in one of our Terraform repositories, which changed only the azuread version from 3.0.2 to 3.1.0, was that both azuread_application.my_application.password and azuread_application_password.my_application in fact referenced the same password.

To be more explicit, this actually did trigger an incident and downtime for us, where the application password was deleted and a new one created. The old password had (seemingly) been manually added as a secret in an Azure Key Vault, so that when it was rotated, there was no automation which also rotated the corresponding key vault secret. Thus the workload which depended on this password effectively lost the requisite Azure access.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants