-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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_container_app
add support for key vault secret references as secret
#23958
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR!
I've taken a look through and left some comments inline, but this is mostly looking good to me 👍
} | ||
secret { | ||
name = "key-vault-secret" | ||
identity = azurerm_user_assigned_identity.test.id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also test for the system assigned identity case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this in a separate test or within the existing one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be in the same test case, but in some separate steps, e.g. UAI -> UAI,SAI -> SAI, so that we can test out the update logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i've added withKeyVaultSecretIdentityUpdate
which does:
- User Assigned
- User Assigned & System Assigned
- System Assigned
I've included the provisioning of the System Assigned identity within the User Assigned template (withKeyVaultSecretUserIdentity
). This is as the API validates managed identity access to secrets when the container app is updated - so the identity and role assignment need to be created prior to the secret reference. I couldn't think of a cleaner way of doing this - any suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically, this requires a separate TF resource which extract these key vault parts out, e.g. https://github.com/hashicorp/terraform-provider-azurerm/blob/7596b072d0b8bf04585d0b77facd8296640d8a2a/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go. In the container app case, there probably wants a azurerm_container_app_secret
resource, which allows users to manage a secret at one time.
With above, users then are able to provision the resources in the following order: container app -> role assignment to the container app system assigned identity -> one or more container app secrets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay cool i'll work on getting that created
thanks for taking a look at this so quickly @magodo - will make the requested changes this evening |
…cret_id, added validation for MI
I need to update the docs for the dapr secrets still |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @x-delfino - I've left a few comments in addition to the earlier review. If you can take a look at those, I'll continue review.
Thanks
} | ||
|
||
func SecretsSchema() *pluginsdk.Schema { | ||
return &pluginsdk.Schema{ | ||
Type: pluginsdk.TypeSet, | ||
Type: pluginsdk.TypeList, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, this has to be a set as the API does not guarantee secret order on return, meaning that it can cause a diff in cases where there are 2 or more secrets.
Type: pluginsdk.TypeList, | |
Type: pluginsdk.TypeSet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked with the service team about this, they told me:
Currently, it is ordered. But we recommend you not depend on the order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked with the service team about this, they told me:
Currently, it is ordered. But we recommend you not depend on the order.
@magodo - I tested this as part of the review, and the response is not ordered unfortunately I saw intermittent diffs on the responses. If it's supposed to be ordered per the service team, we should have an issue on the API specs to track this bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From their response, the service team doesn't mean to guarantee the order as their goal, as they strongly recommend me not depend on the order..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apologies for delayed response. okay, my rudimentary testing was returning them in the same order but good to have clarification from the service team.
The issue is that the response includes the key vault secret value when key vault references are used. So we need to be able to ignore the secret value for secrets that use key vault references, but can't use ignore_changes
on a list. I'm not sure of the best way to approach this. I think we could strip the secret value in FlattenContainerAppSecrets
if a key vault reference is being used? Would that be an acceptable approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reverted to a set now. The secret value is not being stored when key vault references are used now (done in FlattenContainerAppSecrets
). Is this an acceptable approach @jackofallops, @magodo?
stateSecrets := stateSecretsRaw.(*schema.Set).List() | ||
configSecrets := configSecretsRaw.(*schema.Set).List() | ||
stateSecrets := stateSecretsRaw.([]interface{}) | ||
configSecrets := configSecretsRaw.([]interface{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See below, this needs to remain a TypeSet
unfortunately.
@x-delfino Will you continue in this PR with the suggested changes? |
apologies, i've been away. I'll have time to work on this over the next couple of days |
Co-authored-by: jackofallops <[email protected]>
Any more changes needed or is this ready for review and merge? |
@@ -2214,17 +2218,33 @@ func SecretsSchema() *pluginsdk.Schema { | |||
Sensitive: true, | |||
Elem: &pluginsdk.Resource{ | |||
Schema: map[string]*pluginsdk.Schema{ | |||
"identity": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you should use RequireWith and ConflictWith to not allow a user to fill in all 4 fields at once
Description: "The identity to use for accessing key vault reference.", | ||
}, | ||
|
||
"key_vault_secret_id": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not using key_vault_secret_url
? the value is an URL and not an identifier and keeping the same name everywhere may be better for understanding
commonids.ValidateUserAssignedIdentityID, | ||
validation.StringInSlice([]string{"System"}, false), | ||
), | ||
Description: "The identity to use for accessing key vault reference.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description: "The identity to use for accessing key vault reference.", | |
Description: "Resource ID of a managed identity to authenticate with Azure Key Vault, or System to use a system-assigned identity.", |
Type: pluginsdk.TypeString, | ||
Optional: true, | ||
ValidateFunc: keyVaultValidate.NestedItemIdWithOptionalVersion, | ||
Description: "The id of the key vault secret.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description: "The id of the key vault secret.", | |
Description: "Azure Key Vault URL pointing to the secret referenced by the container app.", |
"key_vault_secret_id": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
Description: "The id of the key vault secret.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description: "The id of the key vault secret.", | |
Description: "Azure Key Vault URL pointing to the secret referenced by the container app.", |
"identity": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
Description: "The identity to use for accessing key vault reference.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description: "The identity to use for accessing key vault reference.", | |
Description: "Resource ID of a managed identity to authenticate with Azure Key Vault, or System to use a system-assigned identity.", |
@@ -2257,21 +2289,36 @@ func SecretsDataSourceSchema() *pluginsdk.Schema { | |||
} | |||
} | |||
|
|||
func ExpandContainerSecrets(input []Secret) *[]containerapps.Secret { | |||
func validateContainerSecret(s Secret) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this useful if you use RequireWith and ConflictWith?
@x-delfino: Do you know when you have time to continue this PR? Thanks in advance for your reply and work on this. |
unfortunately a few other commitments have taken priority and I'm not going to have time to give this attention for a couple of weeks realistically. If anyone has a bit more capacity to look at this in the meantime - feel free, otherwise I'll work on it when I have some time |
@x-delfino Any idea when you would have time to pick this up? Or are there others capable of doing this? |
Look at #24773 |
Thanks for all your effort on this @x-delfino! Since you're unable to continue this in the near future and another PR has been opened building on the work done here, I'm going to close this so that the work and review effort can be consolidated in one PR. For everyone interested in this feature please subscribe to #24773 for updates. Thanks! |
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. |
Adding support for key vault references for container apps. Resolving #23668 and #21739. Introduces the following properties for
secret
blocks forazurerm_container_app
resources:identity
key_vault_url
Have included tests & docs and have run
make pr-check
- all tests are passing successfully.I had to split out the Dapr secrets as they don't look to actually support these additional properties. I know that the API reference for Dapr components includes them, but the API doesn't actually support them as far as I can tell. Trying to use these values against the API results in:
Secret with name 'secretName' cannot have have a null value.
And includingvalue
just adds a normal secret.I believe Dapr component key vault secret references are actually handled as follows:
secretsRef
metadata properties for another component as detailed here.I can take a look at raising a separate PR for adding secret reference support for the Dapr components. Apologies this took a while, I got a bit thrown off by the Dapr bits and never got round into reading up on it properly - but I'm fairly confident in my conclusion