My journey continues
👋 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.
Link to my GitLab Repo
Blog post #6
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.
Why Terraform?
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.
Why Vault?
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.
This Week’s Project
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
- With the required JOB_METHOD and environment variables.

2. Terraform Plan Stage
3. Terraform Deploy Stage
This staged approach ensures safe deployments and gives you an opportunity to review changes before they are applied.
Implementation
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:
How It Works
Let’s break it down step by step.
1. Gitlab CI
The .gitlab-ci.yml ties the workflow together and determines which stages run based on the JOB_METHOD variable.


- Ensure that Terraform is installed in the Gitlab runner.


2. Terraform
The project consists of main.tf and aci.auto.tfvars.

- Providers: Cisco ACI provider for resource creation and Vault provider for secure credentials.
- Vault integration: Use
VAULT_TOKEN environment variable (export TF_VAR_VAULT_TOKEN=root-token) to fetch secrets dynamically.
- Variables:
-
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"])
- Tenant
- Creates an ACI tenant with the name
"NAUTIX".
- Application profiles
- Endpoint groups
-
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
- VRFs
-
Creates VRFs for the tenant, one for each name in VRFS.
-
Converts the list to a set to ensure unique entries.
3. Vault
A new Vault service is added to the Docker Compose file to provide secure credentials to Nautix without exposing them in code.

Why This Matters
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
Nautix architecture

📅 What’s Next
In post #7 I will focus on Model-driven-telemetry:
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
🔗 Useful Links
Blog series