👋 Hi, I’m Bjørnar Lintvedt
I’m a Senior Network Consultant at Bluetree, working at the intersection of networking and software development.
As mentioned in my first blog post, I’m preparing for the CCIE Automation lab exam — Cisco’s most advanced certification for network automation and programmability. I’m documenting the journey here with weekly, hands-on blog posts tied to the blueprint.
After working with pyATS and CI/CD in blog post #5, I wanted to dive deeper into infrastructure as code using Terraform, and integrate it with GitLab CI.
This week I explored Terraform to deploy and manage Cisco ACI fabric resources in a stateful and repeatable way, and integrated Vault to manage secrets in my Nautix app.
Terraform allows us to describe infrastructure declaratively. It’s perfect for:
Managing ACI tenants, VRFs, and EPGs as code
Handling dependencies between resources automatically
Tracking state to know exactly what’s deployed
Using loops and variables for repeatable, parameterized deployments
Integrating secrets securely (Vault)
Instead of manually pushing configurations, Terraform lets your code understand and manage the network state.
Vault provides a secure way to manage secrets and credentials in automation pipelines. In this project, it allows us to:
Store ACI usernames and passwords securely
Provide credentials dynamically to Terraform without hardcoding them
Rotate secrets easily without touching code
Control access to sensitive information per environment or service
Instead of storing credentials in .tfvars
or Git, Vault makes sure secrets never leak and automation pipelines can safely access what they need.
I created a Terraform project to deploy ACI resources, integrated into GitLab CI:
Variables (aci.auto.tfvars
) – Centralized definitions for tenants, VRFs, application profiles, and endpoint groups.
GitLab CI (.gitlab-ci.yml
) – Orchestrates Terraform runs in a pipeline.
Vault service – Docker Compose file spins up Vault and other required services locally.
Pipeline Flow
1. The pipeline is triggered by creating a pipeline
2. Terraform Plan Stage
Runs automatically if JOB_METHOD
is set to "terraform"
Initializes Terraform
Generates a plan file (tfplan
) showing what will be created or updated
3. Terraform Deploy Stage
Runs manually after verifying the plan
Applies the plan and provisions the Cisco ACI infrastructure
This staged approach ensures safe deployments and gives you an opportunity to review changes before they are applied.
Here’s the folder structure:
📂 pipelines/jobs/setup_aci/
main.tf
– Terraform resources, loops, and dependencies
aci.auto.tfvars
– Variables and credentials for ACI deployment
Also updated:
.gitlab-ci.yml
– Orchestrates Terraform in CI/CD pipeline
docker-compose.yml
– Spins up Vault and other services for local testing
Let’s break it down step by step.
The .gitlab-ci.yml
ties the workflow together and determines which stages run based on the JOB_METHOD variable.
The first stage runs automatically (terraform plan
) and produces a plan file.
The deploy stage (terraform apply
) runs manually and provisions the ACI resources based on the plan.
The project consists of main.tf
and aci.auto.tfvars
.
VAULT_TOKEN
environment variable (export TF_VAR_VAULT_TOKEN=root-token
) to fetch secrets dynamically.TENANT_NAME
: Name of the ACI tenant ("NAUTIX"
)
APPLICATIONS
: List of applications with names, descriptions, and endpoint groups
VRFS
: List of VRFs to create under the tenant (["RED", "BLUE"]
)
"NAUTIX"
.Creates one application profile per application in the tenant.
Uses the for_each
loop so Terraform dynamically creates profiles for:
bluetree.no
upstacked.com
Creates EPGs for each application.
Loops through all endpoint_groups
from locals.endpoint_groups
.
Uses a key combining app_name and epg_name to ensure unique map keys for for_each
Creates VRFs for the tenant, one for each name in VRFS
.
Converts the list to a set to ensure unique entries.
A new Vault service is added to the Docker Compose file to provide secure credentials to Nautix without exposing them in code.
Instead of manually configuring ACI:
✔ Deployments are repeatable and version-controlled
✔ Loops and variables make scaling easy
✔ Secrets are protected with Vault
✔ Dependencies between tenants, VRFs, and EPGs are automatically handled
✔ Terraform and GitLab CI now manage infrastructure safely
Blueprint item 3.4 Design a model-driven telemetry solution based on given business and technical requirements by using gNMI dial-in, gRPC dial-out, and NETCONF dial-in
Blueprint item 3.5 Create YANG model-driven telemetry subscriptions
3.5.a Identify model elements and cadence
3.5.b On-change or event drive
3.5.c Optimize frequency
3.5.d Dial-out subscription
3.5.e Secure telemetry streams
3.5.f Confirm data transmission
3.5.g Identify network issues and make changes