Terraform - AAD - Add existing users on group with a specific department - azure

I need to add azure ad users with a specific department in a specific group.
My first block is to read all the users on my Azure Active Directory.
data "azuread_users" "users" {
return_all = true
}
Then, for each user who has the "codeur" department, they must go to my "cod-xxx01" group.
resource "azuread_group_member" "Terra-Aad-Member-Cod" {
for_each = { for allusers, cod in data.azuread_users.users : allusers => cod if cod.data.azuread_users.users.department == "codeur" }
group_object_id = azuread_group.Terra-Aad-Group["cod-xxx01"].object_id
member_object_id = each.value.object_id
}
My errors are :
│ Error: Unsupported attribute
│
│ on 3_ServiceGroupsMembers.tf line 32, in resource "azuread_group_member" "Terra-Aad-Member-Cod":
│ 32: for_each = { for allusers, cod in data.azuread_users.users : allusers => cod if cod.azuread_users.users.department == "codeur" }
│
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│ on 3_ServiceGroupsMembers.tf line 32, in resource "azuread_group_member" "Terra-Aad-Member-Cod":
│ 32: for_each = { for allusers, cod in data.azuread_users.users : allusers => cod if cod.azuread_users.users.department == "codeur" }
│
│ Can't access attributes on a list of objects. Did you mean to access an attribute for a specific element of the list, or across all elements of the list?
Output of the data source:
{
account_enabled = true
display_name = "Name SURNAME"
mail = ""
mail_nickname = "xxxxx"
object_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
onpremises_immutable_id = ""
onpremises_sam_account_name = ""
onpremises_user_principal_name = ""
usage_location = ""
user_principal_name = "xxx#xx.xx"
}

It seems , user stored in cod is again checked with overall users ,( cod if cod.data.azuread_users.users.department == "codeur" ) which is incorrect.
Please check to iterate for one user each time .
And correct the following values with id and each
group_object_id = azuread_group. Terra-Aad-Group.id
member_object_id = data.azuread_user.user[each.key].id
I have tried to reproduce in my environment.
Firstly downloaded azure ad users into csv as below to local drive.
Called them to local environment and used.
CODE:
locals {
users = csvdecode(file("C:/exportUsers.csv"))
}
resource "azuread_user" "users" {
for_each = { for i , user in local.users : i => user }
user_principal_name = each.value.UserPrincipalName
// for_each = { for user in local.users : user.UPN => user }
// user_principal_names = each.value.UPN
}
resource "azuread_group" "Terra-Aad-Group" {
display_name = "cod-xxx01"
security_enabled = true
}
resource "azuread_group_member" "Terra-Aad-Member-Cod" {
// for_each = { for i, user in data.azuread_users.users : i => user if user.department == " HR xxxxxxx Programs" }
for_each = { for i, user in data.azuread_user.users : i => user if user.department == "xxxxx" }
group_object_id = azuread_group.Terra-Aad-Group.object_id
member_object_id =data.azuread_users.users[each.key].id
}
Note: Please make sure you have User.ReadWrite.All or
Directory.ReadWrite.All and Group.ReadWrite.All , GroupMember.ReadWrite.All delegated and
application permissions to do these operations.
azuread_users | Terraform Registry doesnot have department attribute but azuread_user | Terraform Registry has department attribute.

Related

What does the error "GroupsClient.BaseClient.Post() An invalid operation was included in the following modified references: 'members'" mean?

I am trying to add an existing Azure Registered Application to an existing Azure Active Directory Group via Terraform. I used the following sequence to complete the task:
// References the existing AAD group
data "azuread_group" "existing_aad_group" {
display_name = "<display name of the aad group>"
security_enabled = true
}
// References the existing registered application
data "azuread_application" "existing_registered_application" {
display_name = "<display name of the registered application>"
}
// --> Adds the application as a member of the AAD group.
resource "azuread_group_member" "registered_app_member" {
group_object_id = data.azuread_group.existing_aad_group.object_id
member_object_id = data.azuread_application.existing_registered_application.object_id
}
The above code fails with the following error:
╷
│ Error: Adding group member "ceb93cb8XXXXX" to group "2f16446cXXXX"
│
│ with module.service.azuread_group_member.function_app,
│ on ../../resources/aad_group.tf line 6, in resource "azuread_group_member" "function_app":
│ 6: resource "azuread_group_member" "function_app" {
│
│ GroupsClient.BaseClient.Post(): unexpected status 400 with OData error:
│ Request_BadRequest: An invalid operation was included in the following
│ modified references: 'members'.
╵
Question
What does this error mean and how can I fix it?
I tried to reproduce the same in my environment :
Code used:
resource "azuread_group" "example" {
display_name = "kavyaMyGroup"
owners = [data.azuread_client_config.current.object_id]
security_enabled = true
members = [
azuread_user.example.object_id,
# more users
]
}
resource "azuread_group_member" "registered_app_member" {
group_object_id = azuread_group.example.object_id
member_object_id = azuread_application.example.object_id
}
resource "azuread_application" "example" {
display_name = "example"
owners = [data.azuread_client_config.current.object_id]
sign_in_audience = "AzureADMultipleOrgs"
required_resource_access {
resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
resource_access {
id = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
type = "Role"
}
resource_access {
id = "b4e74841-8e56-480b-be8b-910348b18b4c" # User.ReadWrite
type = "Scope"
}
}
web {
homepage_url = "https://app.example.net"
logout_url = "https://app.example.net/logout"
redirect_uris = ["https://app.example.net/account"]
implicit_grant {
access_token_issuance_enabled = true
id_token_issuance_enabled = true
}
}
}
Received same Error:
azuread_group_member.registered_app_member: Creating... │ Error:
Adding group member "xxx" to group "xxxx"
│ with azuread_group_member.registered_app_member, │ on main.tf
line 84, in resource "azuread_group_member" "registered_app_member": │
84: resource "azuread_group_member" "registered_app_member" {
│ GroupsClient.BaseClient.Post(): unexpected status 400 with OData
error: Request_BadRequest: An invalid operation │ was included in
the following modified references: 'members'.
As it could not add the application , directly , i tried creating service principal of the existing application and then assigned to the group using its object ID:
Code:
resource "azuread_application" "example" {
display_name = "example"
owners = [data.azuread_client_config.current.object_id]
sign_in_audience = "AzureADMultipleOrgs"
required_resource_access {
resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
resource_access {
id = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
type = "Role"
}
resource_access {
id = "b4e74841-8e56-480b-be8b-910348b18b4c" # User.ReadWrite
type = "Scope"
}
}
web {
homepage_url = "https://app.example.net"
logout_url = "https://app.example.net/logout"
redirect_uris = ["https://app.example.net/account"]
implicit_grant {
access_token_issuance_enabled = true
id_token_issuance_enabled = true
}
}
}
resource "azuread_service_principal" "example" {
application_id = azuread_application.example.application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.current.object_id]
}
#below code adds Enterprise app to required group
resource "azuread_service_principal" "example" {
application_id = azuread_application.example.application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.current.object_id]
}
Terraform code is successfully run with terraform apply
Could see the app added to the group in the form of enterprise app as we are using service principal of app:
App:
Reference:
azuread_service_principal | Resources | hashicorp/azuread | Terraform Registry

Terraform & GCP : Cannot add Owner in a group, can only add members

I am trying to create a group that will list all the people allowed in my organization by using the following blocks :
resource "google_cloud_identity_group" "all-org-users-to-whitelist" {
display_name = "all-org-users-to-whitelist"
description = "A group that onboards a user on the organization, and enables org level policies such as IP restriction of connection to the console."
initial_group_config = "WITH_INITIAL_OWNER"
group_key {
id = "all-org-users-to-whitelist#domain.fr"
}
parent = "customers/${data.google_organization.org.directory_customer_id}"
labels = {
"cloudidentity.googleapis.com/groups.discussion_forum" = "" # Required by doc
}
}
resource "google_cloud_identity_group_membership" "all-org-users" {
group = google_cloud_identity_group.all-org-users-to-whitelist.id
for_each = {
for user in var.all_org_users :
user.email_id => user.role
}
preferred_member_key {
id = each.key
}
roles {
name = each.value
}
}
Input example :
all_org_users = [
{
role = "MEMBER"
email_id = "user1#domain.fr"
},
{
role = "MEMBER"
email_id = "user2#domain.fr"
},
]
This adds these users into the group as members. The problem arrises when I try adding a user as Owner...
{
role = "OWNER"
email_id = "user3#domain.fr"
},
I get the following error :
│ Error: Error creating GroupMembership: googleapi: Error 400: MEMBER role must be specified
│ Details:
│ [
│ {
│ "#type": "type.googleapis.com/google.rpc.BadRequest",
│ "fieldViolations": [
│ {
│ "description": "MEMBER role must be specified",
│ "field": "resource.roles"
│ }
│ ]
│ }
│ ]
│
│ with google_cloud_identity_group_membership.all-org-users["user3#domain.fr"],
│ on groups_x_users.tf line 15, in resource "google_cloud_identity_group_membership" "all-org-users":
│ 15: resource "google_cloud_identity_group_membership" "all-org-users" {
│
Mind you, I can do this on the console with a super-user account... What am I missing here?
Okay... So there was a bit of an issue in the syntax, although I don't know why it is this way.
In order to add an Owner the google_cloud_identity_group_membership needs to be set up this way :
resource "google_cloud_identity_group_membership" "all-org-owners" {
group = google_cloud_identity_group.all-org-users-to-whitelist.id
for_each = toset(var.all_org_owners)
preferred_member_key {
id = each.value
}
roles {
name = "MEMBER"
}
roles {
name = "OWNER"
}
}
With the roles parameter set to MEMBER AND OWNER

Okta - AUtomate users and group assignments via Terraform

Terraform Version
Terraform v1.3.2
provider registry.terraform.io/okta/okta v3.36.0
Affected Resource(s)
okta_app_group_assignments
okta_group_memberships
okta_user
I am trying to configure and implement Okta SSO / MFA via Terraform. Reasoning is because I want to manage my organisation accounts and app integrations via terraform as I am wanting to achieve an automated approach to creating a user > assigning user to a group dependent on department > assign apps to user all through a github repo where the user can change the auto .tfvars file, input their user information and request via a PR (approved by myself who is a super admin).
This will be very cool, as the config will ultimately automate group assignment and apps dependent on the department inputted.
I am struggling discovering a nice easy way to loop over an iterate user / group ids with a conditional on where, lets say;
okta_user.user.department == okta_group_description (this would be very cool)
I have tried conditional logic with an if statement similar to code below and had no luck.
The code below may not necessarily show a clear understanding, but almost an attempt to get this working.
If anyone could aid or show configured code for my use case. That would be brill :)
Actual Behavior
errors on multiple different reasons on my attempts to configure like this.
Steps to Reproduce
I have also tried adding users like this in the group_membership resource:
["${okta_user.user[each.key].id}"]
But get an error:
│ Error: Invalid index
│
│ on main.tf line 115, in resource "okta_group_memberships" "ba":
│ 115: users = ["${okta_user.user[each.key].id}"]
│ ├────────────────
│ │ each.key is "BA"
│ │ okta_user.user is object with 2 attributes
│
│ The given key does not identify an element in this collection value.
Terraform Configuration Files
resource "okta_group" "groups" {
for_each = var.groupList
name = each.value.name
description = each.value.description
}
resource "okta_user" "user"{
#for_each = {for i, v in var.userList: i => v}
for_each = var.userList
first_name = each.value.first_name
last_name = each.value.last_name
display_name = each.value.display_name
email = each.value.email
login = each.value.login
department = each.value.department
organization = each.value.organization
}
resource "okta_group_memberships" "devops" {
for_each = {for group, n in var.groupList: group => n if n.name == "DevOps"}
group_id = okta_group.groups[each.key].id
users = []
depends_on = [okta_group.groups]
}
resource "okta_app_group_assignments" "everyone" {
for_each = { for k in compact([for k, v in var.samlAppList: v.admin_note ? k : ""]): k => var.samlAppList[k] }
app_id = okta_app_saml.saml_apps[each.key].id
group {
id = okta_group.everyone.id
priority = 1
}
}
#variables.tf
variable "groupList"{
type = map(object({
name = string
description = string
}))
}
#auto.tfvars
groupList = {
devOps = {
name : "DevOps"
description : "DevOps"
},
DS = {
name : "DS"
description : "DS"
},
BA = {
name : "BA"
description : "BA"
},
FrontEnd = {
name : "FrontEnd"
description : "FrontEnd"
},
BackEnd = {
name : "BackEnd"
description : "BackEnd"
}
}
#User Information
variable "userList" {
type = map(object({
first_name = string
last_name = string
display_name = string
email = string
login = string
department = string
organization = string
}))
}
#User Details
userList = {
tom = {
first_name : ""
last_name : ""
display_name : ""
email : ""
login : ""
department : ""
organization : ""
}
}

using service principal password created in config later on in same config

I have the following code:
resource "random_string" "password" {
length = 16
special = true
override_special = "_%#"
}
resource "azuread_service_principal_password" "auth" {
service_principal_id = azuread_service_principal.auth.id
value = random_string.password.result
end_date_relative = "240h"
}
I want to use the password in a resource to create an AKS cluster:
resource "azurerm_kubernetes_cluster" "default" {
name = "${random_pet.prefix.id}-aks"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
dns_prefix = "${random_pet.prefix.id}-k8s"
default_node_pool {
name = var.node_pool
node_count = var.node_count
vm_size = var.vm_size
os_disk_size_gb = 30
}
service_principal {
client_id = azuread_service_principal.auth.application_id
client_secret = azuread_service_principal_password.auth.value
}
role_based_access_control {
enabled = true
}
tags = {
environment = "Demo"
}
}
However, when I run terraform apply, I get:
Error: Value for unconfigurable attribute
│
│ with azuread_service_principal_password.auth,
│ on aks-cluster.tf line 26, in resource "azuread_service_principal_password" "auth":
│ 26: value = random_string.password.result
│
│ Can't configure a value for "value": its value will be decided automatically based on the result of applying this
│ configuration.
Is there a way of generating the service principal password in my config and then using it later on in the same configuration ?
Is there a way of generating the service principal password in my
config and then using it later on in the same configuration?
If your question is to set a user defined password/secret for a Service Principal, then it is not possible to do so.
azuread_service_principal_password is essentially a wrapper over servicePrincipal: addPassword Graph API call which does not allow you to specify your own password/secret.
You need to use azuread_application_password instead of azuread_service_principal_password so you can specify the random string value.

How to create multiple azure ad users using terraform?

I am trying to create multiple users using terraform. For now I am declaring them as locals but later on i will be using json file to create multiple users in my azuread environment.
Here is how i declare the locals:
locals {
users = [
[
"user1",
"Example User1",
"Password#1234#"
],
[
"user2",
"Example User2",
"Password#09876#"
]
]
}
But when I use the below code I am getting an error:
resource "azuread_user" "test" {
for_each = local.users
user_principal_name = "${each.value[0]}#tenantname.OnMicrosoft.com"
display_name = each.value[1]
mail_nickname = each.value[0]
password = each.value[2]
}
Error:
╷
│ Error: Invalid for_each argument
│
│ on main.tf line 18, in resource "azuread_user" "test":
│ 18: for_each = local.users
│ ├────────────────
│ │ local.users is tuple with 2 elements
│
│ The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type tuple.
╵
Will really appreciate any help on how to resolve this?
You have to covert it to a map:
resource "azuread_user" "test" {
for_each = {for idx, user in local.users: idx => user}
user_principal_name = "${each.value[0]}#M365B109047.OnMicrosoft.com"
display_name = each.value[1]
mail_nickname = each.value[0]
password = each.value[2]
}
As you have been told in the other answer, you need it to be a map, but before doing a for as in the other answer, it would use terraform's own tomap () function.
resource "azuread_user" "test" {
for_each = tomap({users=local.users})
user_principal_name = "${each.value[0]}#M365B109047.OnMicrosoft.com"
display_name = each.value[1]
mail_nickname = each.value[0]
password = each.value[2]

Resources