azure-service-operator
azure-service-operator copied to clipboard
Feature: Support Azure Key Vault PurgeProtection and CreateMode
In order to support the purge protection scenarios supported by KeyVault, each of these properties must be possible to set in the spec.
See CreateMode and enablePurgeProtection for more details.
Specifically with CreateMode there's some awkward tension between goal-seeking to the customers desired state and the reality that KeyVault will fail creates if a KeyVault of the same name was previously deleted and needs to instead be recovered (needs confirmation).
So we're left with a few options...
- Automatically detect that we're failing to create the KeyVault because it instead needs to be recovered and automatically change the
CreateModetorecover. The downside of this is thatCreateModeis a property on KeyVault and we would effectively be saying that whatever the customer set there we're ignoring. That's awkward because we're not actually seeking to theSpecas specified by the customer. There are additional permissions required to escalate torecoveras well, which we may not have been granted (it's different than Create). - Force the customer to update the CRD to specify
CreateModerecover. This more closely matches the KeyVault API but gives a poor goal-seeking experience because customers may need to make modifications to their CRDs in order for them to successfully reconcile. - The most complicated but possibly the "best" is for us to fabricate a
CreateOrRecovermode for KeyVaults, which would allow customers to clarify that they want theCreatebehavior if they can get it but theRecoverbehavior if they have to. From a goal-seeking perspective this is best as it gives the customers a way to express their intent ahead of time so that when a KV is deleted it can be immediately recovered. We could even investigate if this was a feature the KeyVault team itself would be open to supporting as it would seem to have benefits for ARM templates and other declarative creation modes as well as ASO.
Will revisit once we support KV secrets
We do support KeyVault, and this is an issue for the KeyVault resource itself as if they also have purge protection enabled on the entire vault. It causes us issues in our CI because we delete and recreate KVs with the same names (for recording tests, etc).
We should do something about this.
There's 2 parts to this, key vault secrets, which we don't support in ASOv2 yet, and KeyVaults themselves, which we do.
We still need a solution for this for KeyVaults themselves.
We should write a doc about this, and also 100% confirm that the behavior works as well (it should but might be good to have a test)
Bringing into v2.2.0 as this is about smoothing the experience for users.
I did some testing around the properties mentioned above - works fine. Azure docs have good documentation already for the fields explaining how it works. Also, our API docs are clear enough to make users understand them.
I did some testing around the properties mentioned above ...
Given the above comment by @matthchr, I believe the standard properties are not sufficient for the ASO use case.
Extending CreateMode with a third option - autopurge - might get us close to what we need. We should revisit and rediscuss.
Another quirk - you can only specify createMode: recover if there is an existing vault to recover - so it's very much NOT a goal state design.
@matthchr are you planning to support secret creation through ASOv2?
@radirobi - it depends on what you mean by secret creation. If you mean, configure ASO to export secrets from Azure into KeyVault automatically, yes we have an item tracking that here: #2242. If you mean, create your secret as a Kubernetes secret and have that be saved as a KeyVault secret: no we deliberately didn't expose this option via ASO because we thought that it didn't meet most organizations security goals.
If you want direct KV secret key creation via user specified secret (not importing Azure secrets such as storage account keys into KV automatically like #2242 is talking about), could you expand some more on your use-case, possibly in a separate issue?