Closed aussietexan closed 1 year ago
Hey @aussietexan , there's no an unique resource because it is a trigger on ciscoise_active_directory
resource, if you add groups, it will call to /ers/config/activedirectory/{{id}}/addGroups
API.
Hi @fmunozmiranda. I'm not sure I see how that would work given ISE has to be joined to the domain first before we can do a lookup to find the group name/SID/type attributes.
I tried creating a second resource block using the 'ciscoise_active_directory' resource to add the groups, but I get an error from the API stating "Failed to create Active Directory. Domain Name is not unique in the deployment"
TF code
resource "ciscoise_active_directory" "tui-ad" {
provider = ciscoise.ise31-2
parameters {
ad_attributes {
#attributes {}
}
ad_scopes_names = "Default_Scope"
adgroups {
#groups { }
}
description = ""
domain = var.domain_name
name = var.join_point_name
}
}
output "ciscoise_active_directory_id" {
value = ciscoise_active_directory.tui-ad.parameters[0].id
}
resource "ciscoise_active_directory_join_domain_with_all_nodes" "tui-ad" {
provider = ciscoise.ise31-2
lifecycle {
create_before_destroy = true
}
parameters {
id = ciscoise_active_directory.tui-ad.parameters[0].id
additional_data {
name = "username"
value = var.ad_admin_name
}
additional_data {
name = "password"
value = var.ise-password
}
}
}
resource "ciscoise_active_directory" "tui-ad-groups" {
provider = ciscoise.ise31-2
parameters {
ad_attributes {
#attributes {}
}
ad_scopes_names = "Default_Scope"
adgroups {
groups {
name = "domain.com/Users/Domain Computers"
sid = "S-1-5-21-3064845550-2309088537-4239914413-515"
type = "GLOBAL"
}
}
description = ""
domain = var.domain_name
name = var.join_point_name
}
}
Without having to update the code after doing the domain join operation and getting the information from the data source, can you suggest how this workflow could be accomplished with a single 'ciscoise_active_directory' resource?
@aussietexan , if you don´t want that error you should make a terraform import of the pre-existing resource, or you can turn true the provider variable enable_auto_import
. Here´s documentation about it.https://registry.terraform.io/providers/CiscoISE/ciscoise/latest/docs#example-usage
Trigger of addGroups
endpoint is in Update terraform context, you may follow next steps to add a group.
adGroup
struct, so terraform will detect a change, and call addGroup API.Hi @fmunozmiranda. I enabled the auto import setting in the provider and added the second resource block with the same AD domain settings with the added adGroup attributes. When I run in, the AD join point is created, but I get the following error when it tries to run the second resource block to add the groups.
Error
│ Error: Failure when executing CreateActiveDirectory
│
│ with ciscoise_active_directory.tui-ad-groups,
│ on ad_join.tf line 62, in resource "ciscoise_active_directory" "tui-ad-groups":
│ 62: resource "ciscoise_active_directory" "tui-ad-groups" {
│
│ error with operation CreateActiveDirectory
│ {
│ "ERSResponse" : {
│ "operation" : "POST-create-activedirectory",
│ "messages" : [ {
│ "title" : "com.cisco.epm.pap.api.exceptions.TransactionFailureException: TransactionFailureException~Failed to creation of Resource Name: NAC Group:NAC:DictionaryBucket:TUI-AD",
│ "type" : "ERROR",
│ "code" : "CRUD operation exception"
│ } ],
│ "link" : {
│ "rel" : "related",
│ "href" : "https://192.168.222.54:9060/ers/config/activedirectory",
│ "type" : "application/xml"
│ }
│ }
│ }
Code
resource "ciscoise_active_directory" "tui-ad" {
provider = ciscoise.ise31-2
parameters {
ad_attributes {
#attributes {}
}
ad_scopes_names = "Default_Scope"
adgroups {
#groups {}
}
description = ""
domain = var.domain_name
name = var.join_point_name
}
}
resource "ciscoise_active_directory_join_domain_with_all_nodes" "tui-ad" {
provider = ciscoise.ise31-2
lifecycle {
create_before_destroy = true
}
parameters {
id = ciscoise_active_directory.tui-ad.parameters[0].id
additional_data {
name = "username"
value = var.ad_admin_name
}
additional_data {
name = "password"
value = var.ise-password
}
}
}
resource "ciscoise_active_directory" "tui-ad-groups" {
provider = ciscoise.ise31-2
parameters {
ad_attributes {
#attributes {}
}
ad_scopes_names = "Default_Scope"
adgroups {
groups {
name = "domain.com/Users/Domain Computers"
sid = "S-1-5-21-3064845550-2309088537-4239914413-515"
type = "GLOBAL"
}
}
description = ""
domain = var.domain_name
name = var.join_point_name
}
}
If I do the run again immediately (without changes), it appears to complete but the group is not actually added in ISE.
ciscoise_active_directory.tui-ad: Refreshing state... [id=id:=252862b0-4ffc-11ed-beb0-56d4acca1b2a\name:=TUI-AD]
ciscoise_active_directory_join_domain_with_all_nodes.tui-ad: Refreshing state... [id=1666217989]
Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# ciscoise_active_directory.tui-ad-groups will be created
+ resource "ciscoise_active_directory" "tui-ad-groups" {
+ id = (known after apply)
+ item = (known after apply)
+ last_updated = (known after apply)
+ parameters {
+ ad_scopes_names = "Default_Scope"
+ description = ""
+ domain = "trappedunderise.com"
+ enable_domain_allowed_list = (known after apply)
+ enable_domain_white_list = (known after apply)
+ id = (known after apply)
+ link = (known after apply)
+ name = (sensitive)
+ ad_attributes {
}
+ adgroups {
+ groups {
+ name = "domain.com/Users/Domain Computers"
+ sid = "S-1-5-21-3064845550-2309088537-4239914413-515"
+ type = "GLOBAL"
}
}
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
ciscoise_active_directory.tui-ad-groups: Creating...
ciscoise_active_directory.tui-ad-groups: Creation complete after 1s [id=id:=252862b0-4ffc-11ed-beb0-56d4acca1b2a\name:=TUI-AD]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Doing this also causes an issue when I execute a destroy...
│ Error: Failure when executing DeleteActiveDirectoryByID
│
│ error with operation DeleteActiveDirectoryById
│ {
│ "ERSResponse" : {
│ "operation" : "DELETE-delete-activedirectory",
│ "messages" : [ {
│ "title" : "com.cisco.cpm.nsf.api.exceptions.NSFEntityDeleteFailed: com.cisco.cpm.nsf.api.exceptions.NSFEntityDeleteFailed: java.rmi.RemoteException: Resource 'NAC Group:NAC:TUI-AD' dosen't exists.",
│ "type" : "ERROR",
│ "code" : "CRUD operation exception"
│ } ],
│ "link" : {
│ "rel" : "related",
│ "href" : "https://192.168.222.54:9060/ers/config/activedirectory/252862b0-4ffc-11ed-beb0-56d4acca1b2a",
│ "type" : "application/xml"
│ }
│ }
│ }
Hey @aussietexan, why do you need to add the groups later? could it be added from the first active_directory resource you have?
Hi @fmunozmiranda. There is a particular order-of-operations most often used when adding Active Directory groups in ISE.
Create the AD Join Point
Join the node(s) to the domain
Query the domain for the required groups and add them to ISE
The domain query to find and add the necessary AD groups (name, SID, type) cannot happen until the nodes are joined to the domain.
The AD groups can be included at the time of the AD Join Point creation (using the 'ciscoise_active_directory' resource), but only if the SID is known beforehand. Without joining ISE to the domain and doing the query, the only way to know the SID would be to get that information directly from Active Directory. An ISE Admin would typically not have this access, so it would require engaging an AD Admin to find the SID values and provide them ahead of time.
@aussietexan , ok thanks for aclaration, it help us, I believe if you do something like this, your tf plan it´s going to work. We first have to create the active_directory
resource, then we would have the chance to update it, in this case, add groups, so we only have to add the struct of adgroups
to the already created resource in a second apply.
Here is how your tf plan looks at first run
resource "ciscoise_active_directory" "tui-ad" {
provider = ciscoise.ise31-2
parameters {
ad_attributes {
#attributes {}
}
ad_scopes_names = "Default_Scope"
adgroups {
#groups {}
}
description = ""
domain = var.domain_name
name = var.join_point_name
}
}
resource "ciscoise_active_directory_join_domain_with_all_nodes" "tui-ad" { provider = ciscoise.ise31-2 lifecycle { create_before_destroy = true } parameters { id = ciscoise_active_directory.tui-ad.parameters[0].id additional_data {
name = "username"
value = var.ad_admin_name
}
additional_data {
name = "password"
value = var.ise-password
}
} }
2. Now, we can add to first active_directory resource, the groups, here´s how should look the second apply run without destroy anything, because this is only an update for active_directory resource:
```tf
resource "ciscoise_active_directory" "tui-ad" {
provider = ciscoise.ise31-2
parameters {
ad_attributes {
#attributes {}
}
ad_scopes_names = "Default_Scope"
adgroups {
groups {
name = "domain.com/Users/Domain Computers"
sid = "S-1-5-21-3064845550-2309088537-4239914413-515"
type = "GLOBAL"
}
}
description = ""
domain = var.domain_name
name = var.join_point_name
}
}
resource "ciscoise_active_directory_join_domain_with_all_nodes" "tui-ad" {
provider = ciscoise.ise31-2
lifecycle {
create_before_destroy = true
}
parameters {
id = ciscoise_active_directory.tui-ad.parameters[0].id
additional_data {
name = "username"
value = var.ad_admin_name
}
additional_data {
name = "password"
value = var.ise-password
}
}
}
If it doesn´t work, update us and pass your test with debug to help you please. Thanks.
Hi @fmunozmiranda. I can try that approach and have little doubt that it will work, but using that approach seems to negate the reason and value of using terraform to automate the ISE deployment and configuration. If one has to apply the configuration, then update the code and apply it again, that does not seem to be a reasonable workflow for terraform. If there is not a way to make this workflow work with a single TF module, it seems like it would be better to have a separate module that specifically calls the 'addGroups' API to support the order-of-operations required by ISE. With that, one would have the option of either adding the groups in the initial 'cisco_active_directory' resource (if they already know the SID) or adding them after the join using a query to get the SID and use that captured value.
It would also be ideal if the 'add_groups' resource could support the for_each meta argument if possible so one could create a set or list of group name (key), sid (value.sid), and type (value.type) that could be looped through rather than having multiple "groups" blocks. Some customer deployments have 100+ AD groups added to ISE, so creating a variable set or list (or some other method) that could be read in would be much better than having a huge number of those blocks in a single monolithic code.
@aussietexan , a terraform resource was added for this. Here's documentation: https://registry.terraform.io/providers/CiscoISE/ciscoise/latest/docs/resources/active_directory_add_groups
Please try it with this, and let us now if it works for you.
Hi @fmunozmiranda. I tested the new resource and it works as expected. I was also able to use the data source to query the domain with a filter and use those values in the resource block.
Example code
data "ciscoise_active_directory_get_groups_by_domain_info" "domain-computers" {
provider = ciscoise.ise31-2
id = ciscoise_active_directory.tui-ad.parameters[0].id
additional_data {
name = "domain"
value = "domain.com"
}
additional_data {
name = "filter"
value = "*Domain Computers"
}
}
resource "ciscoise_active_directory_add_groups" "domain-computers" {
provider = ciscoise.ise31-2
parameters {
adgroups {
groups {
name = data.ciscoise_active_directory_get_groups_by_domain_info.domain-computers.item[0].groups[0].name
sid = data.ciscoise_active_directory_get_groups_by_domain_info.domain-computers.item[0].groups[0].sid
type = data.ciscoise_active_directory_get_groups_by_domain_info.domain-computers.item[0].groups[0].type
}
}
description = ""
domain = var.domain_name
name = var.join_point_name
id = ciscoise_active_directory.tui-ad.parameters[0].id
}
}
Just a note on the resource and documentation... the blocks for 'ad_attributes' and 'advanced_settings' are probably not necessary for this 'ciscoise_active_directory_add_groups' resource. Those parameters are related to the 'ciscoise_active_directory' resource so any updates to those parameters would be done there instead of using the 'add_groups' resource.
Thanks for infomation @aussietexan
Is your feature request related to a problem? Please describe. There is a particular order-of-operations most often used when adding Active Directory groups in ISE.
The domain query to find and add the necessary AD groups (name, SID, type) cannot happen until the nodes are joined to the domain.
Describe the solution you'd like We need a resource for 'ciscoise_active_directory_add_groups' that uses the 'addGroups' API as documented here: https://developer.cisco.com/docs/identity-services-engine/v1/#!activedirectory
This would allow building a terraform workflow that suits the order-of-operations required by ISE:
Describe alternatives you've considered The AD groups can be included at the time of the AD Join Point creation (using the 'ciscoise_active_directory' resource), but only if the SID is known beforehand. This would require either using the ISE GUI to search and find the SID, using the ISE API separately to find the SID, or getting the SID directly from AD.