らくがきちょう

なんとなく ~所属組織/団体とは無関係であり、個人の見解です~

Terraform で ACI 上に Route Leak 有りの Tenant を作成する (aci_rest 未使用版)

以前に Terraform で Route Leak 設定を含む Tenant を作成する というメモを書きました。 このメモの中で「現時点の Terraform には Application EPG Subnet を定義する Resource が有りません」と書いたのですが、これは誤りでした。 考えてみたら BD Subnet も Application EPG Subnet も、どちらも fv:Subnet でした… そこで今回は改めて aci_rest は使わずに RouteLeak 設定を含む Tenant を定義してみました。

構成

Terraform で以下の構成を設定します。

f:id:sig9:20210202225033p:plain

Terraform の実行

Tenant を作成する場合は以下のように実行します。

terraform init
terraform apply -auto-approve

Terraform で作成した Tenant を削除する場合は以下のように実行します。

terraform destroy -auto-approve

Terraform の設定ファイル

Terraform の設定ファイルは以下の通りです。

  1. main.tf
  2. aci.tf

パラメータの再利用頻度が高い場合、パラメータを変数化すると良いと思います。 今回はパラメータを変数化すると不必要に .tf ファイルが長くなってしまう為、変数化はしませんでした。

main.tf

terraform {
  required_providers {
    aci = {
      source  = "CiscoDevNet/aci"
      version = "0.5.4"
    }
  }
}

provider "aci" {
  username = "admin"
  password = "password"
  url      = "https://10.0.0.1"
  insecure = true
}

aci.tf

# Tenant
resource "aci_tenant" "tenant" {
  name = "Tenant1"
}

# VRF
resource "aci_vrf" "vrf1" {
  tenant_dn = aci_tenant.tenant.id
  name      = "Vrf1"
}

resource "aci_vrf" "vrf2" {
  tenant_dn = aci_tenant.tenant.id
  name      = "Vrf2"
}

# BD1
resource "aci_bridge_domain" "bd1" {
  tenant_dn          = aci_tenant.tenant.id
  name               = "Bd1"
  relation_fv_rs_ctx = aci_vrf.vrf1.id
}

resource "aci_subnet" "bd1_subnet" {
  parent_dn = aci_bridge_domain.bd1.id
  ip        = "10.0.101.254/24"
  preferred = "yes"
  scope     = ["private", "shared"]
}

# BD2
resource "aci_bridge_domain" "bd2" {
  tenant_dn          = aci_tenant.tenant.id
  name               = "Bd2"
  relation_fv_rs_ctx = aci_vrf.vrf2.id
}

resource "aci_subnet" "bd2_subnet" {
  parent_dn = aci_bridge_domain.bd2.id
  ip        = "10.0.102.254/24"
  preferred = "yes"
  scope     = ["private", "shared"]
}

# Contract / Subject / Filter
resource "aci_filter" "any" {
    tenant_dn = aci_tenant.tenant.id
    name      = "Filter_Any"
}

resource "aci_filter_entry" "entry1" {
    name        = "0010"
    filter_dn   = aci_filter.any.id
    ether_t     = "unspecified"
}

resource "aci_contract" "contract1" {
    tenant_dn = aci_tenant.tenant.id
    name      = "Contract1"
    scope     = "tenant"
}

resource "aci_contract_subject" "subject1" {
    contract_dn                  = aci_contract.contract1.id
    name                         = "Subject1"
    relation_vz_rs_subj_filt_att = [aci_filter.any.id]
}

# Application Profile
resource "aci_application_profile" "ap1" {
  tenant_dn = aci_tenant.tenant.id
  name      = "Ap1"
}

# Domain
data "aci_physical_domain" "physdom" {
  name = "PhysDom"
}

# EPG1
resource "aci_application_epg" "epg1" {
  application_profile_dn = aci_application_profile.ap1.id
  name                   = "Epg1"
  relation_fv_rs_bd      = aci_bridge_domain.bd1.id
}

resource "aci_epg_to_domain" "epg1_physdom" {
  application_epg_dn = aci_application_epg.epg1.id
  tdn                = data.aci_physical_domain.physdom.id
}

resource "aci_epg_to_static_path" "egp1_port1" {
  application_epg_dn = aci_application_epg.epg1.id
  tdn                = "topology/pod-1/paths-201/pathep-[eth1/1]"
  encap              = "vlan-101"
}

resource "aci_subnet" "epg1_subnet" {
  parent_dn = aci_application_epg.epg1.id
  ctrl      = ["no-default-gateway"]
  ip        = "10.0.101.254/24"
  scope     = ["private", "shared"]
}

resource "aci_epg_to_contract" "epg1_contract1" {
    application_epg_dn = aci_application_epg.epg1.id
    contract_dn        = aci_contract.contract1.id
    contract_type      = "consumer"
}

# EPG2
resource "aci_application_epg" "epg2" {
  application_profile_dn = aci_application_profile.ap1.id
  name                   = "Epg2"
  relation_fv_rs_bd      = aci_bridge_domain.bd2.id
}

resource "aci_epg_to_domain" "epg2_physdom" {
  application_epg_dn = aci_application_epg.epg2.id
  tdn                = data.aci_physical_domain.physdom.id
}

resource "aci_epg_to_static_path" "egp2_port1" {
  application_epg_dn = aci_application_epg.epg2.id
  tdn                = "topology/pod-1/paths-202/pathep-[eth1/1]"
  encap              = "vlan-102"
}

resource "aci_subnet" "epg2_subnet" {
  parent_dn = aci_application_epg.epg2.id
  ctrl      = ["no-default-gateway"]
  ip        = "10.0.102.254/24"
  scope     = ["private", "shared"]
}

resource "aci_epg_to_contract" "epg2_contract1" {
    application_epg_dn = aci_application_epg.epg2.id
    contract_dn        = aci_contract.contract1.id
    contract_type      = "provider"
}