terraform-provider-azuread
terraform-provider-azuread copied to clipboard
azuread_invitation: support same properties as in azuread_user
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritise this request
- Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritise the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Description
The azuread_user
resource supports many properties like department
, company
etc, and most notably account_enabled
-- pretty much all fields I can set manually in AAD.
The azuread_invitation
doesn't have any of these at all. And again most notably it doesn't have account_enabled
. At the same time, we can edit and populate all these fields manually in AAD.
We use many external users in our AAD and we use the metadata extensively to document their roles and why they are in our AAD at all.
The proposal is to "beef up" azuread_invitation
to support all the same properties as azuread_user
(except there is no need for password of course).
Looking at the graph SDK, the Invitation
struct does have the *User
member, and it is the same type being used by azuread_user
, so in theory this should be just a matter of exposing the properties and fill out this object in azuread_invitation
?
type Invitation struct {
ID *string `json:"id,omitempty"`
InvitedUserDisplayName *string `json:"invitedUserDisplayName,omitempty"`
InvitedUserEmailAddress *string `json:"invitedUserEmailAddress,omitempty"`
SendInvitationMessage *bool `json:"sendInvitationMessage,omitempty"`
InviteRedirectURL *string `json:"inviteRedirectUrl,omitempty"`
InviteRedeemURL *string `json:"inviteRedeemUrl,omitempty"`
Status *string `json:"status,omitempty"`
InvitedUserType *InvitedUserType `json:"invitedUserType,omitempty"`
InvitedUserMessageInfo *InvitedUserMessageInfo `json:"invitedUserMessageInfo,omitempty"`
InvitedUser *User `json:"invitedUser,omitempty"` // <== THIS
}
Of course if this is possible and is implemented, then we'd want azuread_invitation
to return extra attributes too.
Hi @ppanyukov, thanks for requesting this. Whilst the Invitation object contains a User container, this is read-only and only the user's ID is returned by the API.
We could potentially implement this by updating the guest user separately after the invitation is created, but I'd first like to experiment and see if this can be done with the existing user resource, and also investigate to see which properties are updateable for guest users yet to accept their invitation.
Hmm, I really hoped this wouldn't be the case but oh well...
Would it be breaking "tf resource best practice" if we do two operations (create and then update) on a single resource? Say create succeeds but update fails for some reason (network issue), what happens with the tf state? Tainted? Although azurerm
provider does lots of these "combined operations", e.g. azurerm_app_service
is full of them.
Another alternative is to have separate resource say azuread_invitation_metadata
which will just update these meta properties and will take an object_id
as required parameter?
Of course having all these just in azuread_invitation
resource is much more convenient from the usage perspective.
Judging from the Azure Portal, we can edit all the same properties for invited users as for the regular ones. I don't know if this helps?
Performing multiple operations for a single logical operation in Terraform is fine, as you say we do this in lots of places. If the create operation gets far enough to assign a resource ID, then it is in fact tainted on failure.
Oh, while we are at it, this makes me very sad :(
This resource does not support importing.
There's no way to read back invitations as it's a POST only endpoint - however you can import guest users into an azuread_user
resource! :)
What we struggle with not having any way to set the First and Last names for the created object, this is an issue with things like AAD SCIM sync to sync the guests to other 3rd party apps, (AWS SSO for example) that require First and Last name attributes.
I understand this is likely limitation on the azure api but still my 2 cents
Seems like it should be possible to support the attributes in the Azure Portal when inviting a New User. Looking at the code there is an update of the newly created user that takes place following the actual invitation so this could support updating attributes like the First Name and Last Name, etc. (I guess at least should be able to set the First Name, Last Name, Job Title, Department, Company name and possibly Usage location).
The resource is already reading the Email from the existing user in the read
hook which would be able to update these attributes, this would trigger a change in the resource if there are differences. I guess the question is whether these additional attributes trigger an update
(not currently implemented) or whether they force a new resource.
Proposed changes:
- add the attributes First Name, Last Name, Job Title, Department, Company name to the resource
- should these attributes be defined with
forceNew: true
??
- should these attributes be defined with
- change the second update in the
create
hook to pass these values (if present) - update
read
hook to update these attributes from the User object retrieved from AD - add an
update
dependent on the answer of the forceNew question above
I don't mind looking at making the changes and creating pull request, that is if the suggested changes are appropriate!
This would at least provide the same level of functionality as the Invite user form in Azure AD (excluding Groups, Roles and Manager)
I'm unsure why you need this as the user_id
is an output variable of azuread_invitation
, we do e.g.
locals {
invited_folks = yamldecode(file("${path.module}/../invited_folks.yml"))
}
resource "azuread_invitation" "invite" {
for_each = local.invited_folks
user_email_address = each.key
redirect_url = "https://example.com"
message {
additional_recipients = [each.value.inviter]
body = <<-EOT
Hello ${each.key}
You have been invited to example.com
Please accept this invite to get access.
Have a nice day!
EOT
}
}
resource "azuread_group_member" "example" {
group_object_id = "<an object id>"
for_each = local.invited_folks
member_object_id = azuread_invitation.invite[each.key].user_id
}
with a invited_folks.yml
looking like this:
---
[email protected]:
inviter: [email protected]
[email protected]:
inviter: [email protected]
We intend to approach this by incorporating invite functionality into the azuread_user
resource rather than expand the azuread_invitation
resource.
Any updates on this? This is quite and urgent requirement for out needs as we manage ALL our users through terraform using the azuread_invitation resource and we are currently unable to set any of the additional attributes