This repo was created as a demo for the live stream session "NetGru" by Cisco DevNet, where I was a guest. The main goal of this demo is to show how you can start using Cisco Application Centric Infrastructure (ACI) with Terraform modules. The code represents a network-centric scenario where an ACI Tenant requires a single network segment, operating in a similar fashion to a legacy VLAN.
- Terraform
- Cisco ACI Always-on Sandbox: https://sandboxapicdc.cisco.com/
- Cisco FMC Sandbox: https://fmcrestapisandbox.cisco.com/
- Netbox
You should use Terraform variables to securely supply the credentials or utilize environment variables. Here's how you can export the variables to your environment:
export TF_VAR_aci_username=admin
export TF_VAR_aci_password=!v3G@!4@Y
export FMC_USERNAME=<Your Username for FMC>
export FMC_PASSWORD=<Your Password for FMC>
export FMC_HOST=fmcrestapisandbox.cisco.com
export FMC_INSECURE_SKIP_VERIFY=true
export NETBOX_API_TOKEN=<Your Netbox API Token>
Replace "Your Username for FMC", "Your Password for FMC" and "Your Netbox API Token" with your actual credentials. This approach ensures that sensitive information such as usernames and passwords are not hardcoded into your Terraform configuration files.
While tenant network policies are configured separately from fabric access policies, tenant policies are not activated unless their underlying access policies are in place. Fabric access external-facing interfaces connect to external devices such as virtual machine controllers and baremetals, hosts, routers, firewalls. In the policy model, EPGs are tightly coupled with VLANs. The domain profile associated to the EPG contains the VLAN instance profile. The domain profile contains both the VLAN instance profile (VLAN pool) and the attacheable Access Entity Profile (AEP), which are associated directly with application EPGs. For more information, see the Cisco's official guide.
So, three modules are defined to create networks, specifically in our case, to create one Application EPG:
- tenant_policies module
- fabric_policies module (Fabric Access Policies)
- network module
- epg_creation.tf file represents the way, how can you create one network in the root module. It is commented.
To call a child module you need to add Instance of the module to the root module. Module Block have to consist:
- source argument
- arguments corresponding to input variables defined by the modules
- module output values
In order to create a new L3 network you need to add Instance of the module in networks.tf file located in the root module:
```
module "devvie_project_1" {
source = "./network"
name = "devvie_project_1"
tenant = module.tenant_policies.devvie_tenant
vrf = module.tenant_policies.devvie_vrf
vlan_id = 15
aep_access = module.fabric_policies.aep_generic
physical_domain = module.fabric_policies.physical_domain
mode = "regular"
gateway_address = "192.168.15.1/24"
route_scope = ["public", "shared"]
provided_contract = module.tenant_policies.established_ct
}
```
"name" variable sets the project name of the network.
"tenant" variable declares the tenant of the network (the output of the predefined resource).
"vrf" variable defines the vrf of the network (the output of the predefined resource).
"vlan_id" variable depicts Vlan id of the project.
"aep_access" variable assigns this EPG with specific AEP (the output of the predefined resource).
"physical_domain" variable deploys EPG on a leaf port with a VLAN in a physical domain (the output of the predefined resource).
"mode" stands for Layer 2 Interface Modes. Allowed values: trunk(regular)/access(untagged)/native(native). Default value: "regular".
"gateway_address" variable's name speaks for itself.
"route_scope" the List of network visibility of the subnet. Allowed values are "private", "public" and "shared".
"provided_contract" variable identifies the default set of contracts that contract type is "Provided" (the output of the predefined resource).
To store the remote state, Terraform uses S3 backend.
For GitHub Actions to access the S3 bucket in AWS, OpenID Connect is used. Detailed steps for configuring AWS part can be found here.
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform provided by GitHub. It enables you to automate various tasks within your repository, such as building, testing, and deploying your code.
In this demo, GitHub Actions are used to automate the Terraform workflow for managing infrastructure as code (IaC) deployments. The workflow consists of two jobs: "plan" and "apply."
- Plan: Executes Terraform commands for planning changes, including formatting, initializing, validating, and generating a plan.
- Apply: Automatically applies Terraform changes upon pushing to the main branch.
- Push: Triggered when changes are pushed to the main branch.
- Pull Request: Triggered when pull requests are opened or updated.
- id-token: Write access for AWS OpenID Connect connection.
- contents: Read access for actions/checkout.
- pull-requests: Write access for GitHub bot to comment on pull requests.
Terraform Import is a Terraform CLI command used to read real-world infrastructure and update the state so that future updates to the same set of infrastructure can be applied via IaC. For this demo, a simple bash script is prepared to import necessary objects on ACI with an input file.
For more details on how Terraform Import is utilized in this demo, please watch the accompanying stream.
Terraform Provider Documentation for ACI
Terraform Provider Documentation for FMC
Terraform Provider Documentation for Netbox
In the demo for the Netbox netbox-docker was used. Token creation is described here. The Netbox Docker container is deployed inside an EC2 instance. It's important to note that you need at least a t3.medium type instance to launch Docker Compose successfully.
If you have any questions, feel free to ask ! =)