Skip to content

azurerm_data_factory - customer-managed encryption key "cannot parse an empty string" bug fix#28621

Merged
sreallymatt merged 9 commits intohashicorp:mainfrom
gerrytan:gerrytan/datafactory-cmk-bugfix
Dec 15, 2025
Merged

azurerm_data_factory - customer-managed encryption key "cannot parse an empty string" bug fix#28621
sreallymatt merged 9 commits intohashicorp:mainfrom
gerrytan:gerrytan/datafactory-cmk-bugfix

Conversation

@gerrytan
Copy link
Collaborator

@gerrytan gerrytan commented Jan 29, 2025

Community Note

  • Please vote on this PR by adding a 👍 reaction to the original PR to help the community and maintainers prioritize for review
  • Please do not leave comments along the lines of "+1", "me too" or "any updates", they generate extra noise for PR followers and do not help prioritize for review

Description

This PR fixes a bug where if customer_managed_key_id is set on an existing data factory, customer_managed_key_identity_id is assumed to be present, but it could be an empty string when Managed Service Identity (MSI) is used. As a result user see a parsing error when the provider attempted to parse the json payload back into state.

To reproduce the bug:

  1. In Terraform, deploy a data factory without customer_managed_key_id set and with SystemAssigned identity
  2. Setup a key vault and key for encryption (refer to detailed instruction here)
  3. Set the customer_managed_key_id to the URL of the key created in step 2 and perform another deploy

Expected: Terraform deploy completed with no errors

Actual: Terraform deploy failed with error: Error: parsing "": parsing "": cannot parse an empty string

The reproduction step above reflects the TestAccDataFactory_keyVaultKeyEncryptionWithExistingDataFactoryAndManagedServiceIdentity I implemented in this PR.

PR Checklist

  • I have followed the guidelines in our Contributing Documentation.
  • I have checked to ensure there aren't other open Pull Requests for the same update/change.
  • I have checked if my changes close any open issues. If so please include appropriate closing keywords below.
  • I have updated/added Documentation as required written in a helpful and kind way to assist users that may be unfamiliar with the resource / data source.
  • I have used a meaningful PR title to help maintainers and other users understand this change and help prevent duplicate work.
    For example: “resource_name_here - description of change e.g. adding property new_property_name_here

Changes to existing Resource / Data Source

  • I have added an explanation of what my changes do and why I'd like you to include them (This may be covered by linking to an issue above, but may benefit from additional explanation).
  • I have written new tests for my resource or datasource changes & updated any relevent documentation.
  • I have successfully run tests with my changes locally. If not, please provide details on testing challenges that prevented you running the tests.
  • (For changes that include a state migration only). I have manually tested the migration path between relevant versions of the provider.

Testing

  • My submission includes Test coverage as described in the Contribution Guide and the tests pass. (if this is not possible for any reason, please include details of why you did or could not add test coverage)

https://hashicorp.teamcity.com/buildConfiguration/TF_AzureRM_AZURERM_SERVICE_PUBLIC_DATAFACTORY/531907

Unfortunately there are 34 pre-existing failures in main, but I have diffed and checked there are no new regressions introduced by this change

image

Change Log

Below please provide what should go into the changelog (if anything) conforming to the Changelog Format documented here.

This is a (please select all that apply):

  • Bug Fix
  • New Feature (ie adding a service, resource, or data source)
  • Enhancement
  • Breaking Change

Related Issue(s)

Fixes #27717, #28256

Note

If this PR changes meaningfully during the course of review please update the title and description as required.

Copy link
Collaborator

@sreallymatt sreallymatt left a comment

Choose a reason for hiding this comment

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

Thanks @gerrytan, I've left some comments inline

}

if encIdentity := enc.Identity; encIdentity != nil && encIdentity.UserAssignedIdentity != nil {
if encIdentity := enc.Identity; encIdentity != nil && encIdentity.UserAssignedIdentity != nil && *encIdentity.UserAssignedIdentity != "" {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can make use of pointer.From here to simplify the condition

Suggested change
if encIdentity := enc.Identity; encIdentity != nil && encIdentity.UserAssignedIdentity != nil && *encIdentity.UserAssignedIdentity != "" {
if encIdentity := enc.Identity; encIdentity != nil && pointer.From(encIdentity.UserAssignedIdentity) != "" {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, will fix.

parsed, err := commonids.ParseUserAssignedIdentityIDInsensitively(*encIdentity.UserAssignedIdentity)
if err != nil {
return fmt.Errorf("parsing %q: %+v", *encIdentity.UserAssignedIdentity, err)
return fmt.Errorf("parsing %q: %+v", "customer_managed_key_identity_id", err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

While here, we can remove the wrapped error, for ID parsing errors we generally just return the error directly

Suggested change
return fmt.Errorf("parsing %q: %+v", "customer_managed_key_identity_id", err)
return err

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, will fix

@github-actions
Copy link
Contributor

This PR is being labeled as "stale" because it has not been updated for 30 or more days.

If this PR is still valid, please remove the "stale" label. If this PR is blocked, please add it to the "Blocked" milestone.

If you need some help completing this PR, please leave a comment letting us know. Thank you!

@github-actions github-actions bot added the stale label Nov 17, 2025
@gerrytan gerrytan removed the stale label Nov 17, 2025
@gerrytan
Copy link
Collaborator Author

@sreallymatt I have addressed all your feedbacks, and acctest has been run against latest commit (see description). Please have another look.

@gerrytan gerrytan requested a review from sreallymatt November 18, 2025 06:45
Copy link
Collaborator

@sreallymatt sreallymatt left a comment

Choose a reason for hiding this comment

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

Thanks for adding the CustomizeDiff @gerrytan, I do think for safety it needs minor adjustments, would you mind taking a look at the comment I've left inline?

Copy link
Collaborator

@sreallymatt sreallymatt left a comment

Choose a reason for hiding this comment

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

Forgot to submit comment... 🙃

func CMKIdentityIdRequiredAtCreation(ctx context.Context, d *pluginsdk.ResourceDiff, meta interface{}) error {
if d.Id() == "" &&
d.Get("customer_managed_key_id").(string) != "" &&
d.Get("customer_managed_key_identity_id").(string) == "" {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since these 2 CMK properties are IDs, it's likely these will be unknown at initial plan time, while it won't cause issues if both are unknown/computed it will be problematic if only customer_managed_key_identity_id is.

To be safe, we should probably use RawConfig and .IsNull checks, e.g.

if d.Id() == "" {
		rawConfig := d.GetRawConfig().AsValueMap()
	
		rawCMK := rawConfig["customer_managed_key_id"]
		rawCMKIdentity := rawConfig["customer_managed_key_identity_id"]
	
		if !rawCMK.IsNull() && rawCMKIdentity.IsNull() {
			return fmt.Errorf("`customer_managed_key_identity_id` is required when creating a new Data Factory with `customer_managed_key_id`")
		}
	}

What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hey that is a good trick, thank you @sreallymatt I have pushed this change. Also I will document this in the best-practices.md in a separate PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@sreallymatt can you please have a look at this follow up PR where I documented this in the best-practices.md: #31355 🙏

@gerrytan
Copy link
Collaborator Author

gerrytan commented Dec 14, 2025

Thanks for the feedback @sreallymatt , good for you to take another look.

I have triggered another acctest run: https://hashicorp.teamcity.com/buildConfiguration/TF_AzureRM_AZURERM_SERVICE_PUBLIC_DATAFACTORY/556638

image

Failures have been checked pre-existing on main

Copy link
Collaborator

@sreallymatt sreallymatt left a comment

Choose a reason for hiding this comment

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

Thanks @gerrytan - LGTM ✅

@sreallymatt sreallymatt merged commit c3b45ca into hashicorp:main Dec 15, 2025
35 checks passed
@github-actions github-actions bot added this to the v4.57.0 milestone Dec 15, 2025
@github-actions
Copy link
Contributor

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, 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 Jan 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

azurerm_data_factory changes and corrupts customer_managed_key_id implicitly

2 participants