Hi, I am trying to deploy a keyvault with explicit...
# general
k
Hi, I am trying to deploy a keyvault with explicit 'PurgeProtection = false' via the dotnet AzureNative provider. Oddly however, pulumi up shows this as creating a resource but ARM returns an error related to 'updating' the keyvault. Of course because pulumi up then fails the resource does not exist. In the AzureNative keyvault args I see: /// summary /// Property specifying whether protection against purge is enabled for this vault. Setting this property to true activates protection against purge for this vault and its content - only the Key Vault service may initiate a hard, irrecoverable deletion. The setting is effective only if soft delete is also enabled. Enabling this functionality is irreversible - that is, the property does not accept false as its value. /// /summary [Input("enablePurgeProtection")] public Inputbool? EnablePurgeProtection { get; set; } Specifically this line 'that is, the property does not accept false as its value.' is very odd to me as I am trying to configure it as false on creation while soft-delete is enabled. My questions: • Is it impossible to initially provision the keyvault as EnablePurgeProtection = false? • Does Pulumi AzureNative provider first create the keyvault in memory and then update it? (So a POST then PUT request)? ◦ This would explain the problem to me because my company has a policy that explicitly does not allow 'updating' the PurgeProtection setting. For context, my pipeline returns the azure company policy as if I am attempting to update a keyvault that is supposed to be created. After failure, the keyvault resource does not exist. If EnablePurgeProtection = false on creation is impossible due to how the provider requests this to ARM this would be a massive blocker for my team and project. Typically we don't want this setting on false like everyone else but we require a company endpoint whose job it is to create/remove secrets from a dedicated keyVault. So this would not be done on a keyVault meant for storing regular keys.
b
Without actually writing any code to test this resource, I am reading the
Enabling this functionality is irreversible - that is, the property does not accept false as its value.
statement as "if you create this resource with this input set to true, you cannot update the resource later to set it to be false". Since the
EnablePurgeProtection
is nullable, if you left it out (i.e. didn't set it at all) then this is the same as disabling the purge protection. What is your end goal here? Are you trying to create a new vault that has purge protection turned off?
k
Yea so I interpret that sentence exactly as you do. In fact, that sentence is a company policy here as well. Once created, it cannot be modified. Goal: I am trying to create a KeyVault with the setting on false, this is needed for a specific purpose. However, creating a new keyvault with the setting on false fails within pulumi up. Upon failure I am certain of the following facts: • The keyvault to create does not exist in Azure • Pulumi up states in the urn that the resource (Keyvault) will be created and not updated • The physical and logical names are unique • Our company policy 'PurgeProtection cannot be changed after creation' is triggered when attempting to provision a KeyVault via Pulumi with the value being 'false' So I am wondering, is the AzureNative provider setup in such a way that it first Creates (POST) and then attempts to Update (PUT) the setting? That is the only explanation I can think of as to why creation fails with that policy being triggered. I am woefully aware that we can't modify after creation but then why would a fresh creation fail?
Another strange behavior I observed which may or may not be related is the following. I attempted to use
pulumi import
on a KeyVault in Azure which already exists. This KeyVault was manually created and had
PurgeProtection = Disabled
as property. After
pulumi import
all properties and settings were exported into a class except for
PurgeProtection
. I don't know why that is. But it immediately made me think, is the provider behaving in a way where it always assumes the setting is False? How does the AzureNative provider treat this property? Such questions immediately arose after that observation.
b
This looks like it's an Azure thing, not a Pulumi thing. If I create a vault with purge protection enabled, this is what it looks like in the portal:
But if I remove the
EnablePurgeProtection
input altogether, I get this:
So you can't actually set it to be false, but you can remove it, or set it to be
null
(in csharp), but once it's
true
then that's it - you can't change it to not be true
k
I am aware of screenshot 1. That is the exact company policy we have and that is not my issue. But screenshot 2, did you create a keyvault manually with it disabled or did you provision this with Pulumi? If you mean to say you provisioned this with pulumi by completely omitting
EnablePurgeProtection
then I am in shock. My understanding was that explicitly setting
EnablePurgeProtection = false
in .NET that it would THEN create a KeyVault with the setting
disabled
as seen in your second screenshot. My issue is that I defined a brand new KeyVault with
EnablePurgeProtection = false
and a name that does not exist, thereby showing in the urn that the KeyVault is in [create] status. However when
pulumi up
attempts to create the KeyVault, it fails stating that the value cannot be changed. But I am creating a brand new keyvault, I am not 'changing' anything. Please correct me if I misunderstood and thanks a lot for replying, I really appreciate it!
b
Screenshot 2 I removed
EnablePurgeProtection
altogether. Which suggests that the azure api sees the default value as “false”. I don't believe it is possible to create a vault with that input set to
false
. What was the error message that you got when you tried to run
pulumi up
with it set to false?
k
Really? So that suggests that
EnablePurgeProtection=false
does something else? What I received with it set to false from
pulumi up
was: error: Status=400 Code="BadRequest" Message="The property "enablePurgeProtection" cannot be set to false. Enabling the purge protection for a vault is an irreverisible action" Which is why I suspected that provider must've done a POST then PUT to create the resource. Because that was the first time I tried to create it. In fact I can use any random
VaultName
or fresh stack and it would happen. In essence, I just want to provision a keyvault with the setting
disabled
. Could the POST then PUT be a correct theory?
Update: I provisioned it while omitting
EnablePurgeProtection
altogether and it provisioned as disabled! Thank you so much! I truly don't understand why setting it to
false
causes the policy to trigger.
b
Copy code
error: Status=400 Code="BadRequest" Message="The property "enablePurgeProtection" cannot be set to false. Enabling the purge protection for a vault is an irreverisible action"
That error message comes straight from the API response, so something internal to that is what's not allowing the value to be
false
k
So if that is the case, any clue why omitting it works? My current theory is that omitting the property also omits it entirely from the request body and thus defaults to disabled. When we choose to provide
EnablePurgeProtection=false
it triggers the policy because it is then included in the body and saying that it should be
false
is not allowed. Though the policy clearly states
is an irreverisible action
which then implies you're modifying the vault. So the provider must be doing a POST then PUT request to ARM, no? I would love to understand this because I can't imagine anything but it being a pattern for some other resources in the AzureNative provider.
b
That question is best posed to the KeyVault team. Looking at the ARM docs for keyvault, under
enablePurgeProtection
it literally says "the property does not accept false as its value". i.e. not a Pulumi decision but an Azure one
Let me check the logs to see if we do a POST and then a PUT...
When we do a create on this where I've set the input to be true (not
null
) I can see we just do a straight
PUT
on it. So not a
POST
then
PUT
k
Hmm I see, I wonder if this is about how Azure processes a
PUT
then. While I agree with the method of
CreateOrUpdate
via provider requests but this could cause difficulties in Azure. For instance, in the past we have provisioned a
KeyVault
with the setting on
disabled
explicitly. This went fine but in those cases it was a
POST
. I suppose that is an important nuance to know. Piers, genuinely thank you for your effort.