Local user databases are great, until you have a few dozen of them.
Your lab environment probably has a few users (such as yourself), and some of you might even be sharing the “admin” account, at least until Kyle breaks the fabric again and doesn’t tell anyone and all you see is an audit trail of “admin”. But you know it was Kyle, because he always breaks the network after a weekend bender of energy drinks…
Whatever. Now’s a good time to connect to your Active Directory or other LDAP server so you can leverage existing audit/logging policy when Kyle breaks the fabric…what? he didn’t break it this time? It was Jody? *sigh*
Anyway, if you have an Active Directory or other LDAP server in your environment, you’ll need to get some info from your directory team before you can configure the APIC for LDAP authentication. We use FreeIPA in our lab environment and in the examples below, since it’s free and easy to configure. It’s also purpose-built toward identity management rather than being a general purpose directory, so that keeps things simpler for us.
Note: this guide assumes an RFC2307bis schema is in use. If your organization uses the RFC2307 schema, you will need to extend your schema with additional attributes. Learn about the differences between the two schemas.
Configuring LDAP Providers
First, let’s look at the LDAP Provider pane in Admin -> AAA -> Authentication -> LDAP -> Providers.

I’ve already configured an LDAP server host here, and you should too. This one is a virtual machine running CentOS and FreeIPA; it’s connected to our lab’s management network and shares the same IP subnet as our APIC controllers. Double-click on the entry (if present) or click on the hammer and wrench icon to Create LDAP Provider to enter the LDAP configuration. I’ve pre-populated this screenshot with info from FreeIPA.

Hostname and Port should be self-explanatory to my readers. If you don’t know what this is, get yourself promoted into management immediately!
The Bind DN is the directory user account that you use to authenticate in order to search the directory. Often, this is a system account with non-expiring password. If your LDAP server supports anonymous access to search the LDAP tree, you can leave this empty. FreeIPA allows anonymous bind by default for limited search capabilities, but your Directory Admins probably require an authenticated account to search LDAP in production. If so, they can provide you the distinguished name (DN) to use here. In the example above, I’m using the DN for FreeIPA’s admin user, which is not best practice.
You’ll also need the Base DN, which is the starting container to search for a matching user. This will take a little bit of explanation.
We use the domain “coastlab.local”, so we have a root DN of “dc=coastlab,dc=local”. The “dc” means “domain component”. However, we can also narrow down our search to a specific container. According to the FreeIPA site, users are stored in “cn=users,cn=accounts” container (along with the domain components suffix).
So our Base DN should be “cn=users,cn=accounts,dc=coastlab,dc=local”. Yours will be different depending on your LDAP schema; it might look something like “cn=staff,ou=People,dc=coastlab,dc=local”. If you’re not sure how to find the info and your LDAP/AD guys aren’t being super-helpful, we have posted some ldapsearch examples to play around with.
If you Enable SSL (we didn’t in our lab), check this box and then decide on the SSL Certificate Validation Level, that is, whether strict checking is required for certificates (eg, choose Permissive if you use self-signed certs). If you use an internal CA and/or self-signed certificates, you may need to select Permissive instead.
Enter the Password for your Bind DN user in the next two fields, or leave blank if your directory supports anonymous bind.
Filter and Attribute can a bit challenging to an LDAP novice, as the Cisco Configuration Guides don’t really explain the options that well.
The default Filter setting is “cn=$userid”. This assumes the schema defines the user as an object with a common name (cn), and looks for this object in the container of your Base DN above. FreeIPA uses the “uid” atttribute, so we changed our Filter to “uid=$userid”.
The Attribute field is how we determine group membership and roles, since Cisco assumes (probably correctly) that ACI access isn’t granted to just everyone in the organization. You have two options here: “memberOf” and “CiscoAVPair”. We’re using memberOf, which is an RFC2307bis attribute to identify group memberships for a given user. (Note: if your organization uses RFC2307 schema, you may need to contact Cisco TAC for assistance.
For a bit more explanation on the difference between RFC2307 and RFC2307bis attributes, see our post on the topic.
We disregarded the Server Monitoring option, which simply checks the server periodically to ensure it can process requests. You can also specify the Management EPG if you use one for management traffic.
LDAP Group Map Rules
We also need to establish a mapping between LDAP groups APIC policies. For your lab, you can probably keep this pretty simple. We have a single LDAP group (cn=apic,cn=groups,cn=accounts,dc=coastlab,dc=local) that we use to establish which of our LDAP users are actually APIC administrators and which are users with different permissions (eg, L1 Helpdesk). We’ll set up admins in this post, but setting up additional role mappings should be fairly straightforward.
Select Admin -> AAA -> Authentication (left sidebar) -> LDAP -> LDAP Group Maps. In the main workpane, select the hammer and wrench icon to Create New Group Map Rule (or edit an existing one, if desired).

In the first modal window, enter a name for the Rule (FreeIPA-admins in this example), and the group DN you need to match against. My example references the “apic” group by its DN. Select all the APIC security domains that need a policy for this role and click “Next”.

On the next screen, select the role assignment for each security domain, and whether the LDAP group will have read or write privs. We mapped our LDAP apic group to an admin role with write privileges in each security domain. Remember, this is a specific rule. You can map other groups to other domain privileges, such as read access on All, and no access on Common and Mgmt, while another rule might provide write access to Mgmt domain and read access to the others. ACI will use the greater of any policy/role for users that match multiple groups. That is, if an LDAP users is a member of two groups with conflicting permissions, the APIC will match the greater permission available.

LDAP Group Maps
When your rules are completed, select Admin -> AAA -> Authentication -> LDAP -> LDAP Group Maps, and use the Hammer/Wrench to Create LDAP Group Map.

This one’s pretty easy. Give it a name and add the Rule(s) you just created. We just have one, FreeIPA-admins, but you might have more complex group mappings where you wish to collect multiple rules under a single group mapping. Click submit when done.
Configuring Authentication
The final step is to bring it all together. Go to Admin -> AAA -> Authentication -> AAA (again!) -> Policy. We’ve provided a completed screenshot of our configuration below:

Remote user login policy tells the APIC how to handle users with valid accounts but no Group Map Rule. We have “No Access”, but maybe you have a Default Role you wish to use instead.
Default Authentication defines how to handle authentication when only a username and password are provided. When LDAP authentication is enabled, an additional login field is available in the GUI for Login Domain to select which system to authentication against. Default identifies which one to use when none is explicitly selected. We have local defined here, since we don’t rely on LDAP for our lab. In production, we’d probably select LDAP as the default provider for authentication, while admins could explicitly login with a local user for troubleshooting if needed.
We selected False for Fallback Check, since our “fallback” is local and it’s also the default. However, you can configure a secondary source to verify a user if the first system is unavailable. This might be a secondary directory server in another site or availability zone, but is not a ranked order of systems to search. That is, if the user doesn’t exist in the default system or in the selected Login Domain, the fallback will not be consulted unless the Default system is offline.
Finally, we created two Login Domains, coastlab and local, while the fallback is an entry created by the system.
I explicitly created Local to provide a selectable option in the login screen indicating the local user database (“admin” and the like). The coastlab domain is defined to use the LDAPGroupMap instead of CiscoAVPair to define how we determine access, the Group Map to be consulted for Group Mapping Rules (who gets what policy and roles within a security domain), and of course, the LDAP Provider(s) we’ve configured. You may configure ranked priorities here for multiple LDAP Providers for a given login domain. Because we have a simple lab, we have only one entry.

Testing testing…1…2…3…check…
Of course, we need to verify all this. I strongly recommend staying logged in as your local admin user and open a new browser window in Private/Incognito mode to test authentication.
Notice the option of a Login Domain, if you didn’t have one before.

Try logging in as your local admin user first. Then test with an LDAP user that should have admin access, then test with an LDAP user that shouldn’t have admin access. You’ve done this before; you know the routine. Try it with various user accounts in different systems, with and without selecting a Login Domain.
You can also play with the DefaultAuth and see what works and under what conditions. Try changing Default Authentication above to use LDAP, or possibly test different fallback options (eg, RADIUS or TACACS if configured).