Skip to content

Commit

Permalink
Add radius support (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdewulfPersonal authored Jan 25, 2024
1 parent bc334f0 commit de1f999
Show file tree
Hide file tree
Showing 23 changed files with 471 additions and 15 deletions.
4 changes: 4 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,10 @@ repos:
args: ["./modules/terraform-aci-qos-policy"]
- id: terraform-docs-system
args: ["./modules/terraform-aci-qos-policy/examples/complete"]
- id: terraform-docs-system
args: ["./modules/terraform-aci-radius"]
- id: terraform-docs-system
args: ["./modules/terraform-aci-radius/examples/complete"]
- id: terraform-docs-system
args: ["./modules/terraform-aci-redirect-backup-policy"]
- id: terraform-docs-system
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Make L3 PBR destination MAC optional
- Add `apic_include` option to `port_tracking` configuration
- Add support for Radius Provider

## 0.8.0

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ Additional example repositories:
| <a name="module_aci_ptp"></a> [aci\_ptp](#module\_aci\_ptp) | ./modules/terraform-aci-ptp | n/a |
| <a name="module_aci_qos"></a> [aci\_qos](#module\_aci\_qos) | ./modules/terraform-aci-qos | n/a |
| <a name="module_aci_qos_policy"></a> [aci\_qos\_policy](#module\_aci\_qos\_policy) | ./modules/terraform-aci-qos-policy | n/a |
| <a name="module_aci_radius"></a> [aci\_radius](#module\_aci\_radius) | ./modules/terraform-aci-radius | n/a |
| <a name="module_aci_redirect_backup_policy"></a> [aci\_redirect\_backup\_policy](#module\_aci\_redirect\_backup\_policy) | ./modules/terraform-aci-redirect-backup-policy | n/a |
| <a name="module_aci_redirect_health_group"></a> [aci\_redirect\_health\_group](#module\_aci\_redirect\_health\_group) | ./modules/terraform-aci-redirect-health-group | n/a |
| <a name="module_aci_redirect_policy"></a> [aci\_redirect\_policy](#module\_aci\_redirect\_policy) | ./modules/terraform-aci-redirect-policy | n/a |
Expand Down
24 changes: 24 additions & 0 deletions aci_fabric_policies.tf
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,24 @@ module "aci_tacacs" {
mgmt_epg_name = try(each.value.mgmt_epg, local.defaults.apic.fabric_policies.aaa.tacacs_providers.mgmt_epg) == "oob" ? try(local.node_policies.oob_endpoint_group, local.defaults.apic.node_policies.oob_endpoint_group) : try(local.node_policies.inb_endpoint_group, local.defaults.apic.node_policies.inb_endpoint_group)
}

module "aci_radius" {
source = "./modules/terraform-aci-radius"

for_each = { for radius in try(local.fabric_policies.aaa.radius_providers, []) : radius.hostname_ip => radius if local.modules.aci_radius && var.manage_fabric_policies }
hostname_ip = each.value.hostname_ip
description = try(each.value.description, "")
protocol = try(each.value.protocol, local.defaults.apic.fabric_policies.aaa.radius_providers.protocol)
monitoring = try(each.value.monitoring, local.defaults.apic.fabric_policies.aaa.radius_providers.monitoring)
monitoring_username = try(each.value.monitoring_username, "")
monitoring_password = try(each.value.monitoring_password, "")
key = try(each.value.key, "")
port = try(each.value.port, local.defaults.apic.fabric_policies.aaa.radius_providers.port)
retries = try(each.value.retries, local.defaults.apic.fabric_policies.aaa.radius_providers.retries)
timeout = try(each.value.timeout, local.defaults.apic.fabric_policies.aaa.radius_providers.timeout)
mgmt_epg_type = try(each.value.mgmt_epg, local.defaults.apic.fabric_policies.aaa.radius_providers.mgmt_epg)
mgmt_epg_name = try(each.value.mgmt_epg, local.defaults.apic.fabric_policies.aaa.radius_providers.mgmt_epg) == "oob" ? try(local.node_policies.oob_endpoint_group, local.defaults.apic.node_policies.oob_endpoint_group) : try(local.node_policies.inb_endpoint_group, local.defaults.apic.node_policies.inb_endpoint_group)
}

module "aci_user" {
source = "./modules/terraform-aci-user"

Expand Down Expand Up @@ -615,14 +633,20 @@ module "aci_login_domain" {
hostname_ip = prov.hostname_ip
priority = try(prov.priority, local.defaults.apic.fabric_policies.aaa.login_domains.tacacs_providers.priority)
}]
radius_providers = [for prov in try(each.value.radius_providers, []) : {
hostname_ip = prov.hostname_ip
priority = try(prov.priority, local.defaults.apic.fabric_policies.aaa.login_domains.radius_providers.priority)
}]
ldap_providers = [for prov in try(each.value.ldap_providers, []) : {
hostname_ip = prov.hostname_ip
priority = try(prov.priority, local.defaults.apic.fabric_policies.aaa.login_domains.ldap_providers.priority)
}]

depends_on = [
module.aci_tacacs,
module.aci_radius,
]

}

module "aci_ca_certificate" {
Expand Down
9 changes: 9 additions & 0 deletions defaults/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,21 @@ defaults:
retries: 1
timeout: 5
mgmt_epg: inb
radius_providers:
protocol: pap
monitoring: false
port: 1812
retries: 1
timeout: 5
mgmt_epg: inb
login_domains:
auth_choice: CiscoAVPair
tacacs_providers:
priority: 0
ldap_providers:
priority: 0
radius_providers:
priority: 0
users:
status: active
expires: false
Expand Down
1 change: 1 addition & 0 deletions defaults/modules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ modules:
aci_ptp: true
aci_qos: true
aci_qos_policy: true
aci_radius: true
aci_redirect_backup_policy: true
aci_redirect_health_group: true
aci_redirect_policy: true
Expand Down
4 changes: 2 additions & 2 deletions modules/terraform-aci-aaa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ module "aci_aaa" {
|------|-------------|------|---------|:--------:|
| <a name="input_remote_user_login_policy"></a> [remote\_user\_login\_policy](#input\_remote\_user\_login\_policy) | Remote user login policy. Choices: `assign-default-role`, `no-login` | `string` | `"no-login"` | no |
| <a name="input_default_fallback_check"></a> [default\_fallback\_check](#input\_default\_fallback\_check) | Default fallback check. | `bool` | `false` | no |
| <a name="input_default_realm"></a> [default\_realm](#input\_default\_realm) | Default realm. Choices: `local`, `tacacs`. | `string` | `"local"` | no |
| <a name="input_default_realm"></a> [default\_realm](#input\_default\_realm) | Default realm. Choices: `local`, `tacacs`, `radius`. | `string` | `"local"` | no |
| <a name="input_default_login_domain"></a> [default\_login\_domain](#input\_default\_login\_domain) | Default login domain. | `string` | `""` | no |
| <a name="input_console_realm"></a> [console\_realm](#input\_console\_realm) | Console realm. Choices: `local`, `tacacs`. | `string` | `"local"` | no |
| <a name="input_console_realm"></a> [console\_realm](#input\_console\_realm) | Console realm. Choices: `local`, `tacacs`, `radius`. | `string` | `"local"` | no |
| <a name="input_console_login_domain"></a> [console\_login\_domain](#input\_console\_login\_domain) | Console login domain. | `string` | `""` | no |
| <a name="input_security_domains"></a> [security\_domains](#input\_security\_domains) | List of security domains. | <pre>list(object({<br> name = string<br> description = optional(string, "")<br> restricted_rbac_domain = optional(bool, false)<br> }))</pre> | `[]` | no |
| <a name="input_password_strength_check"></a> [password\_strength\_check](#input\_password\_strength\_check) | Password strength check. | `bool` | `false` | no |
Expand Down
4 changes: 2 additions & 2 deletions modules/terraform-aci-aaa/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ resource "aci_rest_managed" "aaaDefaultAuth" {
content = {
fallbackCheck = var.default_fallback_check ? "true" : "false"
realm = var.default_realm
providerGroup = var.default_realm == "tacacs" ? var.default_login_domain : ""
providerGroup = var.default_realm == "tacacs" || var.default_realm == "radius" ? var.default_login_domain : ""
}
}

Expand All @@ -21,7 +21,7 @@ resource "aci_rest_managed" "aaaConsoleAuth" {
class_name = "aaaConsoleAuth"
content = {
realm = var.console_realm
providerGroup = var.console_realm == "tacacs" ? var.console_login_domain : ""
providerGroup = var.console_realm == "tacacs" || var.console_realm == "radius" ? var.console_login_domain : ""
}
}

Expand Down
12 changes: 6 additions & 6 deletions modules/terraform-aci-aaa/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ variable "default_fallback_check" {
}

variable "default_realm" {
description = "Default realm. Choices: `local`, `tacacs`."
description = "Default realm. Choices: `local`, `tacacs`, `radius`."
type = string
default = "local"

validation {
condition = contains(["local", "tacacs"], var.default_realm)
error_message = "Valid values are `local` or `tacacs`."
condition = contains(["local", "tacacs", "radius"], var.default_realm)
error_message = "Valid values are `local`, `tacacs` or `radius`."
}
}

Expand All @@ -38,13 +38,13 @@ variable "default_login_domain" {
}

variable "console_realm" {
description = "Console realm. Choices: `local`, `tacacs`."
description = "Console realm. Choices: `local`, `tacacs`, `radius`."
type = string
default = "local"

validation {
condition = contains(["local", "tacacs"], var.console_realm)
error_message = "Valid values are `local` or `tacacs`."
condition = contains(["local", "tacacs", "radius"], var.console_realm)
error_message = "Valid values are `local`, `tacacs` or `radius`."
}
}

Expand Down
17 changes: 16 additions & 1 deletion modules/terraform-aci-login-domain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ module "aci_login_domain" {
priority = 10
}]
}
module "aci_login_domain" {
source = "netascode/nac-aci/aci//modules/terraform-aci-login-domain"
version = ">= 0.8.0"
name = "RADIUS1"
description = "My Description"
realm = "radius"
radius_providers = [{
hostname_ip = "10.2.1.10"
priority = 10
}]
}
```

## Requirements
Expand All @@ -42,10 +55,11 @@ module "aci_login_domain" {
|------|-------------|------|---------|:--------:|
| <a name="input_name"></a> [name](#input\_name) | Login domain name. | `string` | n/a | yes |
| <a name="input_description"></a> [description](#input\_description) | Description. | `string` | `""` | no |
| <a name="input_realm"></a> [realm](#input\_realm) | Realm. Choices: `local`, `tacacs`, `ldap`. | `string` | n/a | yes |
| <a name="input_realm"></a> [realm](#input\_realm) | Realm. Choices: `local`, `tacacs`, `ldap`, `radius`. | `string` | n/a | yes |
| <a name="input_auth_choice"></a> [auth\_choice](#input\_auth\_choice) | Authentication choice. Choices: `CiscoAVPair`, `LdapGroupMap`. | `string` | `"CiscoAVPair"` | no |
| <a name="input_ldap_group_map"></a> [ldap\_group\_map](#input\_ldap\_group\_map) | LDAP group map. | `string` | `""` | no |
| <a name="input_tacacs_providers"></a> [tacacs\_providers](#input\_tacacs\_providers) | List of TACACS providers. Allowed values `priority`: 0-16. Default value `priority`: 0 | <pre>list(object({<br> hostname_ip = string<br> priority = optional(number, 0)<br> }))</pre> | `[]` | no |
| <a name="input_radius_providers"></a> [radius\_providers](#input\_radius\_providers) | List of RADIUS providers. Allowed values `priority`: 0-16. Default value `priority`: 0 | <pre>list(object({<br> hostname_ip = string<br> priority = optional(number, 0)<br> }))</pre> | `[]` | no |
| <a name="input_ldap_providers"></a> [ldap\_providers](#input\_ldap\_providers) | List of LDAP providers. Allowed values `priority`: 0-16. Default value `priority`: 0 | <pre>list(object({<br> hostname_ip = string<br> priority = optional(number, 0)<br> }))</pre> | `[]` | no |

## Outputs
Expand All @@ -65,4 +79,5 @@ module "aci_login_domain" {
| [aci_rest_managed.aaaProviderRef](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.aaaProviderRef_ldap](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.aaaTacacsPlusProviderGroup](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.aaaRadiusProviderGroup](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
<!-- END_TF_DOCS -->
13 changes: 13 additions & 0 deletions modules/terraform-aci-login-domain/examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,18 @@ module "aci_login_domain" {
priority = 10
}]
}
module "aci_login_domain" {
source = "netascode/nac-aci/aci//modules/terraform-aci-login-domain"
version = ">= 0.8.0"
name = "RADIUS1"
description = "My Description"
realm = "radius"
radius_providers = [{
hostname_ip = "10.2.1.10"
priority = 10
}]
}
```
<!-- END_TF_DOCS -->
21 changes: 20 additions & 1 deletion modules/terraform-aci-login-domain/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ resource "aci_rest_managed" "aaaDomainAuth" {
class_name = "aaaDomainAuth"
content = {
realm = var.realm
providerGroup = contains(["tacacs", "ldap"], var.realm) ? var.name : null
providerGroup = contains(["tacacs", "radius", "ldap"], var.realm) ? var.name : null
}
}

Expand All @@ -35,6 +35,25 @@ resource "aci_rest_managed" "aaaProviderRef" {
}
}

resource "aci_rest_managed" "aaaRadiusProviderGroup" {
count = var.realm == "radius" ? 1 : 0
dn = "uni/userext/radiusext/radiusprovidergroup-${var.name}"
class_name = "aaaRadiusProviderGroup"
content = {
name = var.name
}
}

resource "aci_rest_managed" "aaaProviderRef_radius" {
for_each = { for prov in var.radius_providers : prov.hostname_ip => prov if var.realm == "radius" }
dn = "${aci_rest_managed.aaaRadiusProviderGroup[0].dn}/providerref-${each.value.hostname_ip}"
class_name = "aaaProviderRef"
content = {
name = each.value.hostname_ip
order = each.value.priority
}
}

resource "aci_rest_managed" "aaaLdapProviderGroup" {
count = var.realm == "ldap" ? 1 : 0
dn = "uni/userext/ldapext/ldapprovidergroup-${var.name}"
Expand Down
22 changes: 19 additions & 3 deletions modules/terraform-aci-login-domain/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ variable "description" {
}

variable "realm" {
description = "Realm. Choices: `local`, `tacacs`, `ldap`."
description = "Realm. Choices: `local`, `tacacs`, `radius`, `ldap`."
type = string

validation {
condition = contains(["local", "tacacs", "ldap"], var.realm)
error_message = "Allowed values: `local`, `tacacs` or `ldap`."
condition = contains(["local", "tacacs", "radius", "ldap"], var.realm)
error_message = "Allowed values: `local`, `tacacs`, `radius` or `ldap`."
}
}

Expand Down Expand Up @@ -67,6 +67,22 @@ variable "tacacs_providers" {
}
}

variable "radius_providers" {
description = "List of Radius providers. Allowed values `priority`: 0-16. Default value `priority`: 0"
type = list(object({
hostname_ip = string
priority = optional(number, 0)
}))
default = []

validation {
condition = alltrue([
for p in var.radius_providers : (p.priority >= 0 && p.priority <= 16)
])
error_message = "`priority`: Minimum value: 0. Maximum value: 16."
}
}

variable "ldap_providers" {
description = "List of LDAP providers. Allowed values `priority`: 0-16. Default value `priority`: 0"
type = list(object({
Expand Down
34 changes: 34 additions & 0 deletions modules/terraform-aci-radius/.terraform-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: '>= 0.14.0'

formatter: markdown table

content: |-
# Terraform ACI RADIUS Module
Manages ACI RADIUS
Location in GUI:
`Admin` » `AAA` » `Authentication` » `RADIUS`
## Examples
```hcl
{{ include "./examples/complete/main.tf" }}
```
{{ .Requirements }}
{{ .Providers }}
{{ .Inputs }}
{{ .Outputs }}
{{ .Resources }}
output:
file: README.md
mode: replace

sort:
enabled: false
Loading

0 comments on commit de1f999

Please sign in to comment.