仅通过输入参数表格即可进行Cisco ACI的配置和管理! 〜通过 Terraform(IaC)简化 ACI 自动化〜

?这篇文章是由思科系统合同公司员工自愿投稿的2022年Advent Calendar 2的第15天内容?
?2022年版第一部分链接:https://qiita.com/advent-calendar/2022/cisco
?2022年版第二部分链接:https://qiita.com/advent-calendar/2022/cisco2

首先

在本文中,我们将介绍在Cisco ACI中使用Terraform(基础设施即代码)时的一种更简单的方法。

在使用Terraform的过程中,除了能够实现”自动配置”和”配置管理”的优势外,还可能逐渐发现

    • 設定項目が増えてくるとパラメタの管理・コードへの入力が煩雑に(variables/変数として定義するにも限界が。。。)

 

    コードが長くなり、構成を把握するのが困難

我觉得出现了一个新的问题。

那样的话,如果能够导入参数表的内容,并且能够完全相同地进行设置,

    • パラメタシートの内容をterraform のコードとして逐一変換する必要がない

 

    構成はパラメタシートを見ればすぐに把握できる(そして表形式になっていて分かりやすい!)

根据我认为自动化和配置管理双方面都有好处,我制作了一个实施方案。

我认为,由于定义和配置管理可以在一个参数表上完成,可以进一步提高日常运作的效率。

image.png

在解释本次使用的代码之前,我们提供了一般的基础设施即代码的解释和运作概述。

“基础设施即代码” 是指的什么?

image.png
    • 複雑な設定であっても迅速・正確に設定できる

 

    • コードを機械的に複製でき、拡張性に優れている

 

    設定内容がテキストとして記録されており、構成管理に活用できる

据说有以下优点。

使用Cisco ACI进行基础设施即代码的好处。

思うに、Cisco ACI是面向数据中心的SDN解决方案,其特点是可以灵活地从控制器(APIC)中设置虚拟网络。如果将上述优点应用于ACI,可以列举如下:

ACI特有のネットワーク設定・ポリシー設定をテンプレート化して、誰でも簡単に設定できるようになる

大規模な設定が発生する場合(既存ネットワークの移行や新規サービス・ユーザー用のネットワークを展開する際など)でもテンプレートを再利用して迅速に設定できる
ACIの設定内容の構成管理が可能

为什么在众多基础设施即代码工具中选择采用Terraform?

在本文中,选择使用Terraform的原因是因为Terraform可以简洁地编写为”声明式”代码。

在基础设施即代码中,有两种方式来描述代码的方式,分别为「命令式」和「声明式」。

命令型:実行する設定変更内容・手順を具体的に記述する必要あり
→コードを書くときに、既存の設定を踏まえた上で具体的な変更内容を記述 しなければならない

宣言型:最終的に必要な構成だけ記述し、必要となる設定変更内容・手順はツール側が調整
→ コードの記述が シンプル。

image.png

上面的图中说明了命令式和声明式的代码图像之间的差异。
在添加或删除基础设施配置时,
命令式的代码需要用户明确定义具体的配置更改内容(添加或删除),而声明式的代码只需说明所需的配置,无需详细描述实际的配置步骤。
此外,由于代码内容与环境配置相匹配,通过查看代码可以了解基础设施的配置。

使用Terraform配置ACI的操作概述

请参考今年 Cisco 圣诞日历第一天的文章,其中提供了关于 Terraform 的简明解释。尽管此处略去了详细说明,请以此作为参考!

image.png

1. 在 Terraform 的代码中描述想要配置的 ACI 设置
→ 使用名为 HCL 的 Terraform 专有格式来编写代码。以”声明式”的方式记录最终所需的配置。

2. 在状态文件中,Terraform 理解现有的 ACI 配置,并将其与代码中的配置进行比较,自动计算所需的配置更改。

3. 在执行 Terraform 代码时,一个名为 Provider 的插件将 HCL 代码转换为 ACI 的 API。

以下我要介绍的实现的内容

image.png

1. 使用Terraform代码来将ACI网络设置模板化
→ 为了在ACI中部署L3网络,需要创建一些对象,因此在这里将设置框架设置为模板。
本次将创建Tenant、VRF、Bridge Domain、Subnet、Application Profile和EPG这些对象。
2. 实际的设置内容,即模板设置内容的参数将在参数表(csv格式)中定义。
→ 根据所需的L3网络数量填写参数表并使用。
3. 根据输入的1和2,将设置应用到ACI中。

优点

    • ACIで繰り返し設定する内容を自動化でき、正確・迅速に設定ができる

 

    • パラメータシートに記載されている内容が直接インフラに設定されているので、パラメタシートと実際のインフラ設定が同期しており、シンプルに構成が管理 できる

 

    設定されている構成とそのパラメタを 見やすいシート形 式で一覧確認できる

这次使用的 Terraform 代码

# Required Provider :このTerraform のコードはACI設定用に変換するように定義
terraform {
    required_providers {
      aci = {
        source = "CiscoDevNet/aci"
        version = "2.2.1"
      }
    }
  }
 
# Provider の定義:このTerraform のコードで設定する対象(APIC)のアクセス情報を定義
# アクセス情報は外部ファイルにて定義
provider "aci" {
  # APIC のユーザーネームを変数で定義
    username = var.apic_username
  # APIC のユーザーネームを変数で定義
    password = var.apic_password
  # APIC のURLを変数で定義
    url      = var.apic_url
 # 証明書利用設定
    insecure = true
  }

# csvファイルで定義したパラメタシートのインポート
locals {
    nw = csvdecode(file("networks.csv")) 
}

### 以下、ACI における L3 ネットワークの設定を resource ブロックで定義 ###
 # Define an ACI Tenant Resource.
resource "aci_tenant" "terraform_tenant" {
    name = "ACI-Tenant"
}

# Denine an ACI VRF Resource.
resource "aci_vrf" "VRF1" {
  tenant_dn = aci_tenant.terraform_tenant.id
  name      = "VRF1"
}

# Define an ACI Bridge Domain Resource.
resource "aci_bridge_domain" "BD" {
  for_each = { for nw in local.nw : nw.NW_id => nw }
  tenant_dn          = aci_tenant.terraform_tenant.id
  relation_fv_rs_ctx = aci_vrf.VRF1.id
  name               = each.value.bd
}

# Define an ACI Bridge Domain subnet Resource.
resource "aci_subnet" "bd_subnet" {
  for_each = { for nw in local.nw : nw.NW_id => nw }
  parent_dn = aci_bridge_domain.BD[each.key].id
  ip               = each.value.subnet
}

# Define an ACI Application Profile Resource.
resource "aci_application_profile" "terraform_ap" {
    tenant_dn  = aci_tenant.terraform_tenant.id
    name       = "AP1"
    description = "App Profile Created Using Terraform"
}

# Define an ACI Application EPG Resource.
resource "aci_application_epg" "terraform_epg" {
    for_each = { for nw in local.nw : nw.NW_id => nw }
    application_profile_dn  = aci_application_profile.terraform_ap.id
    name                    = each.value.epg
    relation_fv_rs_bd       = aci_bridge_domain.BD[each.key].id
    description             = "EPG Created Using Terraform"
}

导入参数表( csv 文件) 的图像

每一行参数表上都会创建一个L3网络。
当在参数表上进行配置的添加或删除时,配置更改将同步进行。

VRFNW_idBDsubnetepgVRF11BD1192.168.1.254/24EPG1VRF22BD2192.168.2.254/24EPG2VRF33BD3192.168.3.254/24EPG3VRF44BD4192.168.4.254/24EPG4VRF55BD5192.168.5.254/24EPG5……………VRF1010BD10192.168.10.254/24EPG10

用于导入和使用参数表(csv文件)的设置点。

使用Terraform的函数来导入csv文件的参数,并映射到在Terraform中创建的模板上的变量。
在代码中进行导入和映射的设置。

由于有几个阶段的设置,将按顺序进行记录。

locals {
    nw = csvdecode(file("networks.csv")) 
}

在这里,通过 file 从目录导入文件,
使用 csvdecode 把 csv 文件转换成列表,
使用 locals 定义一个名为 nw 的本地变量。

接下来是将导入的csv文件参数与Terraform模板进行映射。

resource "aci_bridge_domain" "BD" {
  for_each = { for nw in local.nw : nw.NW_id => nw }
  tenant_dn          = aci_tenant.terraform_tenant.id
  relation_fv_rs_ctx = aci_vrf.VRF1.id
  name               = each.value.bd
}

在 “for_each = { for nw in local.nw : nw.NW_id => nw }” 的代码行中,

通过”により”,首先将之前导入的csv文件的列表形式的局部变量nw转换为键值对形式的映射。
其中csv文件的参数中,NW_id作为键,其他参数作为值。
通过”for_each”循环对象并复制,同时利用转换为映射形式的nw的参数进行循环处理。
例如,在each.value.bd的位置,将映射的value中的bd参数进行映射。

在这段代码中,将根据参数表中的内容创建BD(桥接域)对象。

image.png

总结一下,可以按照以下步骤进行操作:
1. 使用 file 指定 csv 文件的路径进行读取,
2. 使用 csvdecode 将 csv 文件转换为“列表”形式,
3. 使用 for 将“列表”转换为“映射”形式,
4. 使用 for each 根据映射创建循环对象,并使用 each.value.XX 进行参数映射。

演示视频

这是一段使用此代码进行ACI配置并捕捉到的视频。希望能够传达出ACI环境配置内容会同步随参数表的更改而变化的想法。

※添加说明:很抱歉,视频之前由于权限问题设为了非公开,但现已修正。非常抱歉给您带来不便。
感谢您的指正。

总之

通过对Terraform代码进行修改,我们现在可以在与参数表保持同步的同时进行基础架构配置的更改。
通过参数表的维护来完成日常运营,我认为可以更简单地利用自动化。

一方面,由于参数映射设置有点复杂,我想继续尝试是否有其他更简单的方法。
此外,在不使用Terraform这样的工具(Postman等)时,可以在GUI界面上轻松地对csv文件的参数和模板中的变量进行映射,如果Terraform也能实现类似的功能,将会大大提高易用性,我暗中期待着。

免责声明

在本网站以及相应评论中表达的意见是发表者个人的意见,不代表思科公司的意见。本网站的内容仅供信息提供,并不旨在推荐或表达思科或其他相关方的意见。每个用户在本网站上发表、链接或以其他方式上传的所有信息内容由其个人承担全部责任,并同意解除思科公司对使用本网站所产生的任何责任。