CiscoDevNet / terraform-provider-aci

Terraform Cisco ACI provider
https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs
Mozilla Public License 2.0
89 stars 101 forks source link

Ressource aci_l3out_vpc_member does not support to configure secondary ipv4 or ipv6 address information #930

Closed seth1972 closed 1 year ago

seth1972 commented 2 years ago

Community Note

Description

Hello Team, I´m using the ressource aci_l3out_vpc_member to configure the layer3 out inside of ACI With the aci.provider version 2.5.2 it is not possible to configure a SVI secondary additional address for Ipv4 and IPv6. (for vpc members)

To make it possible to configure the secondary ip I used at the noment the "rest" ressource. It would be great if you could add this functionality to the ressource aci_l3out_vpc_member to make it possible to handle that in future in a easier way.

Below can you see how I handle it in the moment with the rest resource.

Here can you see the part where I confiugre the secondary ip address for side a / b

resource "aci_rest" "configuration_sec_ip_mem_a_node_1_2_ipv4" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-A.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-A/addr-[${var.svinodesecondaryipv4}]",
      "addr": "${var.svinodesecondaryipv4}",
      "rn": "addr-[${var.svinodesecondaryipv4}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

New or Affected Resource(s) + ACI Class(es):

aci_l3out_vpc_member

APIC version and APIC Platform

4.2.5(n) 5.2.3(g) 5.2.6(e)

Potential Terraform Configuration

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key.

terraform {
  required_providers {
    aci = {
      source = "ciscodevnet/aci"
    }
  }
}

#configure provider with your cisco aci credentials.
provider "aci" {
  # cisco-aci user name
  username = var.aci_user
  # cisco-aci password
  password = var.aci_password
  # cisco-aci url
  url      = var.url 
  insecure = true
}

data "aci_tenant" "tenant" {
  name  = var.tenant_name
}

data "aci_vrf" "vrf" {
  tenant_dn  = data.aci_tenant.tenant.id
  name       = var.vrf
}

data "aci_l3_domain_profile" "domain" {
  name  = var.l3_domain
}

resource "aci_l3_outside" "l3_out" {
        tenant_dn      = data.aci_tenant.tenant.id
        name           = "L3Out_CN_${var.contentname1}_${var.contentname2}"
        relation_l3ext_rs_ectx = data.aci_vrf.vrf.id
        relation_l3ext_rs_l3_dom_att  = data.aci_l3_domain_profile.domain.id

  }
# Create Node Profiles

resource "aci_logical_node_profile" "node_profile1" {
        l3_outside_dn = aci_l3_outside.l3_out.id
        description   = "L3Out Content Node Profil"
        name          = "LoNP_${var.node1}_${var.node2}"
    }

resource "aci_logical_node_profile" "node_profile2" {
        l3_outside_dn = aci_l3_outside.l3_out.id
        description   = "L3Out Content Node Profil"
        name          = "LoNP_${var.node3}_${var.node4}"
     }

# Create logical interface profiles for node 1 and node 2
resource "aci_logical_interface_profile" "logical_interface_profile_node1_2_ipv4" {
        logical_node_profile_dn = aci_logical_node_profile.node_profile1.id
        description             = "LoIP_${var.node1}_${var.node2}_IPv4"
        name                    = "LoIP_${var.node1}_${var.node2}_IPv4"
  }
resource "aci_logical_interface_profile" "logical_interface_profile_node1_2_ipv6" {
        logical_node_profile_dn = aci_logical_node_profile.node_profile1.id
        description             = "LoIP_${var.node1}_${var.node2}_IPv6"
        name                    = "LoIP_${var.node1}_${var.node2}_IPv6"
  }

#  Create logical interface profiles for node 3 and node 4
resource "aci_logical_interface_profile" "logical_interface_profile_node3_4_ipv4" {
        logical_node_profile_dn = aci_logical_node_profile.node_profile2.id
        description             = "LoIP_${var.node3}_${var.node4}_IPv4"
        name                    = "LoIP_${var.node3}_${var.node4}_IPv4"
  }
resource "aci_logical_interface_profile" "logical_interface_profile_node3_4_ipv6" {
        logical_node_profile_dn = aci_logical_node_profile.node_profile2.id
        description             = "LoIP_${var.node3}_${var.node4}_IPv6"
        name                    = "LoIP_${var.node3}_${var.node4}_IPv6"
  }

# Create Configured Nodes 
resource "aci_logical_node_to_fabric_node" "node1" {
  logical_node_profile_dn  = aci_logical_node_profile.node_profile1.id
  tdn               = "topology/pod-${var.pod_id_1}/node-${var.node1}"
  rtr_id            = var.routeridnode1
  rtr_id_loop_back  = "no"
}
resource "aci_logical_node_to_fabric_node" "node2" {
  logical_node_profile_dn  = aci_logical_node_profile.node_profile1.id
  tdn               = "topology/pod-${var.pod_id_1}/node-${var.node2}"
  rtr_id            = var.routeridnode2
  rtr_id_loop_back  = "no"
}
resource "aci_logical_node_to_fabric_node" "node3" {
  logical_node_profile_dn  = aci_logical_node_profile.node_profile2.id
  tdn               = "topology/pod-${var.pod_id_2}/node-${var.node3}"
  rtr_id            = var.routeridnode3
  rtr_id_loop_back  = "no"
}
resource "aci_logical_node_to_fabric_node" "node4" {
  logical_node_profile_dn  = aci_logical_node_profile.node_profile2.id
  tdn               = "topology/pod-${var.pod_id_2}/node-${var.node4}"
  rtr_id            = var.routeridnode4
  rtr_id_loop_back  = "no"
}

#Create SVI Interface for Node 1 and Node 2

resource "aci_l3out_path_attachment" "node1_2_ipv4" {
  logical_interface_profile_dn  = aci_logical_interface_profile.logical_interface_profile_node1_2_ipv4.id
  target_dn  = "topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}]"
  if_inst_t = "ext-svi"
  encap  = var.vlan_id
  mode = "regular"
 }

resource "aci_l3out_vpc_member" "vpc_node_1_2_a_ipv4" {
  leaf_port_dn  = aci_l3out_path_attachment.node1_2_ipv4.id
  side  = "A"
  addr  = var.svinode1ipv4
  ipv6_dad = "enabled"

}

# Create SVI Interface for Layer 3 out Node 1 _ 2
resource "aci_l3out_vpc_member" "vpc_node_1_2_b_ipv4" {
  leaf_port_dn  = aci_l3out_path_attachment.node1_2_ipv4.id
  side  = "B"
  addr  = var.svinode2ipv4
  ipv6_dad = "enabled"

}
resource "aci_l3out_path_attachment" "node1_2_ipv6" {
  logical_interface_profile_dn  = aci_logical_interface_profile.logical_interface_profile_node1_2_ipv6.id
  target_dn  = "topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}]"
  if_inst_t = "ext-svi"
  encap  = var.vlan_id
  mode = "regular"
 }

resource "aci_l3out_vpc_member" "vpc_node_1_2_a_ipv6" {
  leaf_port_dn  = aci_l3out_path_attachment.node1_2_ipv6.id
  side  = "A"
  addr  = var.svinode1ipv6
  ipv6_dad = "enabled"

}
resource "aci_l3out_vpc_member" "vpc_node_1_2_b_ipv6" {
  leaf_port_dn  = aci_l3out_path_attachment.node1_2_ipv6.id
  side  = "B"
  addr  = var.svinode2ipv6
  ipv6_dad = "enabled"

  }

####################Create SVI Interface for Node 3 and Node 4

resource "aci_l3out_path_attachment" "node3_4_ipv4" {
  logical_interface_profile_dn  = aci_logical_interface_profile.logical_interface_profile_node3_4_ipv4.id
  target_dn  = "topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]"
  if_inst_t = "ext-svi"
  encap  = var.vlan_id
  mode = "regular"
 }

resource "aci_l3out_vpc_member" "vpc_node_3_4_a_ipv4" {
  leaf_port_dn  = aci_l3out_path_attachment.node3_4_ipv4.id
  side  = "A"
  addr  = var.svinode3ipv4
  ipv6_dad = "enabled"

}

resource "aci_l3out_vpc_member" "vpc_node_3_4_b_ipv4" {
  leaf_port_dn  = aci_l3out_path_attachment.node3_4_ipv4.id
  side  = "B"
  addr  = var.svinode4ipv4
  ipv6_dad = "enabled"

}
resource "aci_l3out_path_attachment" "node3_4_ipv6" {
  logical_interface_profile_dn  = aci_logical_interface_profile.logical_interface_profile_node3_4_ipv6.id
  target_dn  = "topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]"
  if_inst_t = "ext-svi"
  encap  = var.vlan_id
  mode = "regular"
 }

resource "aci_l3out_vpc_member" "vpc_node_3_4_a_ipv6" {
  leaf_port_dn  = aci_l3out_path_attachment.node3_4_ipv6.id
  side  = "A"
  addr  = var.svinode3ipv6
  ipv6_dad = "enabled"

}
resource "aci_l3out_vpc_member" "vpc_node_3_4_b_ipv6" {
  leaf_port_dn  = aci_l3out_path_attachment.node3_4_ipv6.id
  side  = "B"
  addr  = var.svinode4ipv6
  ipv6_dad = "enabled"

}

###################### Create IP Secondary Node 1 and Node 2

**Here can you see the part where I confiugre the secondary ip address for side a / b **

resource "aci_rest" "configuration_sec_ip_mem_a_node_1_2_ipv4" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-A.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-A/addr-[${var.svinodesecondaryipv4}]",
      "addr": "${var.svinodesecondaryipv4}",
      "rn": "addr-[${var.svinodesecondaryipv4}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

resource "aci_rest" "configuration_sec_ip_mem_b_node_1_2_ipv4" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-B.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}]]/mem-B/addr-[${var.svinodesecondaryipv4}]",
      "addr": "${var.svinodesecondaryipv4}",
      "rn": "addr-[${var.svinodesecondaryipv4}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

resource "aci_rest" "configuration_sec_ip_mem_a_node_1_2_ipv6" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-A.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-A/addr-[${var.svinodesecondaryipv6}]",
      "addr": "${var.svinodesecondaryipv6}",
      "rn": "addr-[${var.svinodesecondaryipv6}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

resource "aci_rest" "configuration_sec_ip_mem_b_node_1_2_ipv6" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-B.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node1}_${var.node2}/lifp-LoIP_${var.node1}_${var.node2}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}_LACP]]/mem-B/addr-[${var.svinodesecondaryipv6}]",
      "addr": "${var.svinodesecondaryipv6}",
      "rn": "addr-[${var.svinodesecondaryipv6}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

##############Configuration Secondary IP node 3 and 4 ###########################

**resource "aci_rest" "configuration_sec_ip_mem_a_node_3_4_ipv4" {**
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]]/mem-A.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}]]/mem-A/addr-[${var.svinodesecondaryipv4}]",
      "addr": "${var.svinodesecondaryipv4}",
      "rn": "addr-[${var.svinodesecondaryipv4}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

resource "aci_rest" "configuration_sec_ip_mem_b_node_3_4_ipv4" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]]/mem-B.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv4/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}]]/mem-B/addr-[${var.svinodesecondaryipv4}]",
      "addr": "${var.svinodesecondaryipv4}",
      "rn": "addr-[${var.svinodesecondaryipv4}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

resource "aci_rest" "confiuration_sec_ip_mem_a_node_3_4_ipv6" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]]/mem-A.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]]/mem-A/addr-[${var.svinodesecondaryipv6}]",
      "addr": "${var.svinodesecondaryipv6}",
      "rn": "addr-[${var.svinodesecondaryipv6}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

resource "aci_rest" "confiuration_sec_ip_mem_b_node_3_4_ipv6" {
  path       = "api/node/mo/uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]]/mem-B.json"
  payload = <<EOF
{
  "l3extIp": {
    "attributes": {
      "dn": "uni/tn-${var.tenant_name}/out-L3Out_CN_${var.contentname1}_${var.contentname2}/lnodep-LoNP_${var.node3}_${var.node4}/lifp-LoIP_${var.node3}_${var.node4}_IPv6/rspathL3OutAtt-[topology/pod-${var.pod_id_2}/protpaths-${var.node3}-${var.node4}/pathep-[LPG_Content_${var.contentname2}_LACP]]/mem-B/addr-[${var.svinodesecondaryipv6}]",
      "addr": "${var.svinodesecondaryipv6}",
      "rn": "addr-[${var.svinodesecondaryipv6}]",
      "status": "created"
    },
    "children": []
  }
}
  EOF
}

########################################Add IPv4 VIP Routes Node 1 - 4 #######################

resource "aci_l3out_static_route" "node1vipipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node1.id
    ip  = var.vip_ip
}

resource "aci_l3out_static_route_next_hop" "node1vipipv4nh" {

  static_route_dn  = aci_l3out_static_route.node1vipipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node2vipipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node2.id
    ip  = var.vip_ip
}

resource "aci_l3out_static_route_next_hop" "node2vipipv4nh" {

  static_route_dn  = aci_l3out_static_route.node2vipipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node3vipipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node3.id
    ip  = var.vip_ip
}

resource "aci_l3out_static_route_next_hop" "node3vipipv4nh" {

  static_route_dn  = aci_l3out_static_route.node3vipipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node4vipipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node4.id
    ip  = var.vip_ip
}

resource "aci_l3out_static_route_next_hop" "node4vipipv4nh" {

  static_route_dn  = aci_l3out_static_route.node4vipipv4.id
  nh_addr  = var.nexthopipv4
}

########################################Add IPv6 VIP Routes Node 1 - 4 #######################

resource "aci_l3out_static_route" "node1vipipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node1.id
    ip  = var.vip_ipv6
}

resource "aci_l3out_static_route_next_hop" "node1vipipv6nh" {

  static_route_dn  = aci_l3out_static_route.node1vipipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node2vipipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node2.id
    ip  = var.vip_ipv6
}

resource "aci_l3out_static_route_next_hop" "node2vipipv6nh" {

  static_route_dn  = aci_l3out_static_route.node2vipipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node3vipipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node3.id
    ip  = var.vip_ipv6
}

resource "aci_l3out_static_route_next_hop" "node3vipipv6nh" {

  static_route_dn  = aci_l3out_static_route.node3vipipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node4vipipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node4.id
    ip  = var.vip_ipv6
}

resource "aci_l3out_static_route_next_hop" "node4vipipv6nh" {

  static_route_dn  = aci_l3out_static_route.node4vipipv6.id
  nh_addr  = var.nexthopipv6
}

########################################Add IPv4 SNAT Routes Node 1 - 4 #######################

resource "aci_l3out_static_route" "node1snatipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node1.id
    ip  = var.snat_ip
}

resource "aci_l3out_static_route_next_hop" "node1snatipv4nh" {

  static_route_dn  = aci_l3out_static_route.node1snatipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node2snatipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node2.id
    ip  = var.snat_ip
}

resource "aci_l3out_static_route_next_hop" "node2snatipv4nh" {

  static_route_dn  = aci_l3out_static_route.node2snatipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node3snatipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node3.id
    ip  = var.snat_ip
}

resource "aci_l3out_static_route_next_hop" "node3snatipv4nh" {

  static_route_dn  = aci_l3out_static_route.node3snatipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node4snatipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node4.id
    ip  = var.snat_ip
}

resource "aci_l3out_static_route_next_hop" "node4snatipv4nh" {

  static_route_dn  = aci_l3out_static_route.node4snatipv4.id
  nh_addr  = var.nexthopipv4
}

########################################Add IPv6 SNAT Routes Node 1 - 4 #######################

resource "aci_l3out_static_route" "node1snatipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node1.id
    ip  = var.snat_ipv6
}

resource "aci_l3out_static_route_next_hop" "node1snatipv6nh" {

  static_route_dn  = aci_l3out_static_route.node1snatipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node2snatipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node2.id
    ip  = var.snat_ipv6
}

resource "aci_l3out_static_route_next_hop" "node2snatipv6nh" {

  static_route_dn  = aci_l3out_static_route.node2snatipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node3snatipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node3.id
    ip  = var.snat_ipv6
}

resource "aci_l3out_static_route_next_hop" "node3snatipv6nh" {

  static_route_dn  = aci_l3out_static_route.node3snatipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node4snatipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node4.id
    ip  = var.snat_ipv6
}

resource "aci_l3out_static_route_next_hop" "node4snatipv6nh" {

  static_route_dn  = aci_l3out_static_route.node4snatipv6.id
  nh_addr  = var.nexthopipv6
}

########################################Add IPv4 TRF Routes Node 1 - 4 #######################

resource "aci_l3out_static_route" "node1trfipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node1.id
    ip  = var.trf_ip
}

resource "aci_l3out_static_route_next_hop" "node1trfipv4nh" {

  static_route_dn  = aci_l3out_static_route.node1trfipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node2trfipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node2.id
    ip  = var.trf_ip
}

resource "aci_l3out_static_route_next_hop" "node2trfipv4nh" {

  static_route_dn  = aci_l3out_static_route.node2trfipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node3trfipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node3.id
    ip  = var.trf_ip
}

resource "aci_l3out_static_route_next_hop" "node3trfipv4nh" {

  static_route_dn  = aci_l3out_static_route.node3trfipv4.id
  nh_addr  = var.nexthopipv4
}

resource "aci_l3out_static_route" "node4trfipv4" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node4.id
    ip  = var.trf_ip
}

resource "aci_l3out_static_route_next_hop" "node4trfipv4nh" {

  static_route_dn  = aci_l3out_static_route.node4trfipv4.id
  nh_addr  = var.nexthopipv4
}

########################################Add IPv6 TRF Routes Node 1 - 4 #######################

resource "aci_l3out_static_route" "node1trfipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node1.id
    ip  = var.trf_ipv6
}

resource "aci_l3out_static_route_next_hop" "node1trfipv6nh" {

  static_route_dn  = aci_l3out_static_route.node1trfipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node2trfipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node2.id
    ip  = var.trf_ipv6
}

resource "aci_l3out_static_route_next_hop" "node2trfipv6nh" {

  static_route_dn  = aci_l3out_static_route.node2trfipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node3trfipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node3.id
    ip  = var.trf_ipv6
}

resource "aci_l3out_static_route_next_hop" "node3trfipv6nh" {

  static_route_dn  = aci_l3out_static_route.node3trfipv6.id
  nh_addr  = var.nexthopipv6
}

resource "aci_l3out_static_route" "node4trfipv6" {
  fabric_node_dn  = aci_logical_node_to_fabric_node.node4.id
    ip  = var.trf_ipv6
}

resource "aci_l3out_static_route_next_hop" "node4trfipv6nh" {

  static_route_dn  = aci_l3out_static_route.node4trfipv6.id
  nh_addr  = var.nexthopipv6
}

 ############################   Create External EPG for Content Switch Pair 

resource "aci_external_network_instance_profile" "create_external_epg_vip" {
        l3_outside_dn  = aci_l3_outside.l3_out.id
        name           = "ENIP_CN_${var.contentname1}_${var.contentname2}_VIP"
        pref_gr_memb   = "include"

    }
resource "aci_l3_ext_subnet" "vip_ip_subnet" {
      external_network_instance_profile_dn  = aci_external_network_instance_profile.create_external_epg_vip.id
      description                           = "VIP IPv4 Segment"
      ip                                    = var.vip_ip
    }
resource "aci_l3_ext_subnet" "vip_ipv6_subnet" {
      external_network_instance_profile_dn  = aci_external_network_instance_profile.create_external_epg_vip.id
      description                           = "VIP IPv6 Segment"
      ip                                    = var.vip_ipv6
   }

resource "aci_external_network_instance_profile" "create_external_epg_snat" {
        l3_outside_dn  = aci_l3_outside.l3_out.id

        name           = "ENIP_CN_${var.contentname1}_${var.contentname2}_SNAT"
        pref_gr_memb   = "include"

    }
resource "aci_l3_ext_subnet" "snat_ip_subnet" {
      external_network_instance_profile_dn  = aci_external_network_instance_profile.create_external_epg_snat.id
      description                           = "SNAT IPv4 Segment"
      ip                                    = var.snat_ip
    }
resource "aci_l3_ext_subnet" "snat_ipv6_subnet" {
      external_network_instance_profile_dn  = aci_external_network_instance_profile.create_external_epg_snat.id
      description                           = "SNAT IPv6 Segment"
      ip                                    = var.snat_ipv6
   }   

resource "aci_external_network_instance_profile" "create_external_epg_trf" {
        l3_outside_dn  = aci_l3_outside.l3_out.id

        name           = "ENIP_CN_${var.contentname1}_${var.contentname2}_TRF"
        pref_gr_memb   = "include"

    }
 resource "aci_l3_ext_subnet" "TRF_ip_subnet" {
      external_network_instance_profile_dn  = aci_external_network_instance_profile.create_external_epg_trf.id
      description                           = "trf IPv4 Segment"
      ip                                    = var.trf_ip
    }
 resource "aci_l3_ext_subnet" "TRF_ipv6_subnet" {
     external_network_instance_profile_dn  = aci_external_network_instance_profile.create_external_epg_trf.id
     description                           = "trf IPv6 Segment"
     ip                                    = var.trf_ipv6
   }

 ############################   Add Route to Layer 3 CN (Redistribution) 

data "aci_l3_outside" "l3_out_cn" {
  tenant_dn  = data.aci_tenant.tenant.id 
  name       = var.nameL3outcn
}

data "aci_external_network_instance_profile" "ext_l3out_cn" {
  l3_outside_dn  = data.aci_l3_outside.l3_out_cn.id
  name           = var.exnameL3outcn
}

resource "aci_l3_ext_subnet" "vip_ip_subnet_cn" {
      external_network_instance_profile_dn  = data.aci_external_network_instance_profile.ext_l3out_cn.id
      description                           = "VIP IPv4 Segment"
      ip                                    = var.vip_ip
      scope                                 = ["export-rtctrl"]
    }
resource "aci_l3_ext_subnet" "vip_ipv6_subnet_cn" {
      external_network_instance_profile_dn  = data.aci_external_network_instance_profile.ext_l3out_cn.id
      description                           = "VIP IPv6 Segment"
      ip                                    = var.vip_ipv6
      scope                                 = ["export-rtctrl"]
    }
resource "aci_l3_ext_subnet" "snat_ip_subnet_cn" {
      external_network_instance_profile_dn  = data.aci_external_network_instance_profile.ext_l3out_cn.id
      description                           = "SNAT IPv4 Segment"
      ip                                    = var.snat_ip
      scope                                 = ["export-rtctrl"]
    }
resource "aci_l3_ext_subnet" "snat_ipv6_subnet_cn" {
      external_network_instance_profile_dn  = data.aci_external_network_instance_profile.ext_l3out_cn.id
      description                           = "SNAT IPv6 Segment"
      ip                                    = var.snat_ipv6
      scope                                 = ["export-rtctrl"]
    }
resource "aci_l3_ext_subnet" "trf_ip_subnet_cn" {
      external_network_instance_profile_dn  = data.aci_external_network_instance_profile.ext_l3out_cn.id
      description                           = "TRF IPv4 Segment"
      ip                                    = var.trf_ip
      scope                                 = ["export-rtctrl"]
    }
resource "aci_l3_ext_subnet" "trf_ipv6_subnet_cn" {
      external_network_instance_profile_dn  = data.aci_external_network_instance_profile.ext_l3out_cn.id
      description                           = "TRF IPv6 Segment"
      ip                                    = var.trf_ipv6
      scope                                 = ["export-rtctrl"]
    }

#vip_ip = "10.2.54.0/24"
#snat_ip = "10.2.55.0/24"
#trf_ip = "10.12.6.32/28"

References

seth1972 commented 2 years ago

ACI_Configuration

In the picture can you see a apic gui hardcopy about which settings I´m talking about

shrsr commented 1 year ago

@seth1972 There is a resource called aci_l3out_path_attachment_secondary_ip in the ACI provider which is used to configure secondary IP addresses. The resource aci_l3out_vpc_member needs to be passed as a reference to the attribute: _l3out_path_attachment_dn_ in the resource aci_l3out_path_attachment_secondary_ip I suggest using the following example in your configuration to attach the IP addresses.

#Create SVI Interface for Node 1 and Node 2

resource "aci_l3out_path_attachment" "node1_2_ipv4" {
  logical_interface_profile_dn  = aci_logical_interface_profile.logical_interface_profile_node1_2_ipv4.id
  target_dn  = "topology/pod-${var.pod_id_1}/protpaths-${var.node1}-${var.node2}/pathep-[LPG_Content_${var.contentname1}]"
  if_inst_t = "ext-svi"
  encap  = var.vlan_id
  mode = "regular"
 }

resource "aci_l3out_vpc_member" "vpc_node_1_2_a_ipv4" {
  leaf_port_dn  = aci_l3out_path_attachment.node1_2_ipv4.id
  side  = "A"
  addr  = var.svinode1ipv4
  ipv6_dad = "enabled"

}

resource "aci_l3out_vpc_member" "vpc_node_1_2_b_ipv4" {
  leaf_port_dn  = aci_l3out_path_attachment.node1_2_ipv4.id
  side  = "B"
  addr  = var.svinode2ipv4
  ipv6_dad = "enabled"

}

resource "aci_l3out_path_attachment_secondary_ip" "secondary_ip_addr_A" {
  l3out_path_attachment_dn = aci_l3out_vpc_member.vpc_node_1_2_a_ipv4.id
  addr                     = "Your secondary IP address A"
  ipv6_dad = "enabled"
}

resource "aci_l3out_path_attachment_secondary_ip" "secondary_ip_addr_B" {
  l3out_path_attachment_dn = aci_l3out_vpc_member.vpc_node_1_2_b_ipv4.id
  addr                     = "Your secondary IP address B"
  ipv6_dad = "enabled"
}

Please give it a try and let me know if you have any questions.

shrsr commented 1 year ago

@seth1972 Please let us know if the suggested configuration worked for you or if you have other questions.

seth1972 commented 1 year ago

Hi today I had time to test the new resource. For my use case it does not work. If you create a logical interface profile inside of ACI you can define if you want to work with a router interface or sub-router interface or SVI interface. In my case i want to work with a SVI.

Inside of the resource "aci_l3out_path_attachment_secondary_ip" you can not define which interface type you are using. The resource map in my case, the secondary ip not to the svi interface.

I will upload tomorrow a few picture where you can see the details

Kind regards

Stefan

seth1972 commented 1 year ago

Try new ressource

resource "aci_l3out_path_attachment_secondary_ip" "node1_2_ipv4" { l3out_path_attachment_dn = aci_l3out_path_attachment.node1_2_ipv4.id addr = var.svinodesecondaryipv4 }

The resource will add the secondary ip not to the SVI interface.

SVI_Configuration

Unbenannt

Please let me know when you will need more feedback

shrsr commented 1 year ago

@seth1972 Let me look into it

shrsr commented 1 year ago

@seth1972 If you provide a reference in the resource "aci_l3out_path_attachment_secondary_ip" to the resource "aci_l3out_path_attachment" which has the attribute if_inst_t = "ext-svi", then the secondary IP address will be automatically configured in the SVI.

In the example below I am setting l3out_path_attachment_dn with a reference _aci_l3out_pathattachment.path.id which is referring to the resource aci_l3out_path_attachment.path which has if_inst_t set to ext-svi.

resource "aci_tenant" "tenant" {
  name = "tf_tenant_l3out"
}

resource "aci_l3_outside" "l3" {
  tenant_dn = aci_tenant.tenant.id
  name      = "demo_l3out"
}

resource "aci_logical_node_profile" "node_profile" {
  l3_outside_dn = aci_l3_outside.l3.id
  name          = "demo_node"
}

resource "aci_logical_interface_profile" "interface_profile" {
  logical_node_profile_dn = aci_logical_node_profile.node_profile.id
  name                    = "demo_int_prof"
}

resource "aci_l3out_path_attachment" "path" {
  logical_interface_profile_dn = aci_logical_interface_profile.interface_profile.id
  target_dn                    = "topology/pod-1/paths-101/pathep-[eth1/1]"
  if_inst_t                    = "ext-svi"
  addr                         = "0.0.0.0"
  annotation                   = "example"
  autostate                    = "disabled"
  encap                        = "vlan-1"
  encap_scope                  = "ctx"
  ipv6_dad                     = "disabled"
  ll_addr                      = "::"
  mac                          = "0F:0F:0F:0F:FF:FF"
  mode                         = "native"
  mtu                          = "inherit"
  target_dscp                  = "AF11"
}

resource "aci_l3out_path_attachment_secondary_ip" "secondary" {
  l3out_path_attachment_dn = aci_l3out_path_attachment.path.id
  addr                     = "10.0.0.1/24"
  annotation               = "example"
  ipv6_dad                 = "disabled"
  name_alias               = "example"
}

Please give it a try and let me know if it worked.

shrsr commented 1 year ago

@seth1972 Did you get a chance to try the example I posted above?

lhercot commented 1 year ago

Closing this issue as we have provided an example of a solution and did not hear back. Please re-open an issue if you still need help.