If you’ve spent any time managing Citrix, NetScaler, or DaaS environments, you know the drill. A delivery group setting gets tuned during an incident and never written down. A NetScaler virtual server gets a one-off policy change to solve an urgent problem. The environment keeps working until six months later, when nobody remembers why that one component behaves differently, and a routine patch or rebuild turns into a guessing game.
I call this the invisible runbook. ClickOps isn’t inherently bad. Clicking through a console is often the fastest way to learn, triage, or fix something urgent. The trouble starts when those clicks become the only record of how production was actually built. The environment works, but the reasoning behind it lives in a console, in someone’s memory, or in a sequence of manual steps nobody captured. In EUC and DaaS environments, where identity, networking, brokering, image management, ADC configuration, and security controls all need to work together, that invisible layer is often where drift, fragile change windows, and patch avoidance begin to creep in.
The fix isn’t eliminating manual work overnight. It’s making production intent visible, reviewable, and recoverable. This is where Infrastructure as Code (IaC) and GitOps step in.
The Elephant in the Room
I’ve heard the adage that if you aren’t automating your job, someone else will. At this point, I think that framing has it backward. This isn’t about being replaced; it’s about building an environment that’s consistent, repeatable, and resilient enough that you’re not the single point of failure holding it together from memory.
Someone still must decide what “correct” looks like, write the code that enforces it, and handle the judgment calls automation can’t make. That work requires more platform expertise, not less. The admins who lean into this shift aren’t automating themselves out of relevance — they’re moving from clicking through the same wizard for the fortieth time to owning how the environment behaves.
The Mindset Shift: Object State to Desired State
The real shift isn’t tooling; it’s a change in how you think about production.
With ClickOps, you open a console, find the object, change the setting, and it mutates right now. It’s fast, but the reasoning and the desired end-state usually aren’t captured anywhere durable.
With IaC, you stop starting from the live object. You describe the desired result in a file, the resources, settings, dependencies, and policies, and Terraform (or your tool of choice) compares that against the current state and calculates the delta. That plan is the critical bridge: before anything changes, you can see exactly what will be created, changed, or destroyed. It can be reviewed, stored, compared over time, and used as an audit record.
GitOps adds the collaboration layer on top. Instead of making changes directly in production, changes start as pull requests. This is a place to review the code, inspect the plan, ask questions, and approve the work, with a clean audit trail attached. Infrastructure change becomes the same kind of controlled workflow we already expect for application code.
So, the progression is:
- ClickOps changes the object.
- IaC describes the desired state.
- GitOps makes that desired state reviewable, approved, and repeatable.
A repository then becomes the source of truth for that desired state. Rather than relying on console settings or institutional memory, the environment is described in code that can be reviewed, versioned, and deployed consistently.

Example of a GitOps repository for Citrix DaaS infrastructure. Terraform configurations, reusable modules, environment definitions, and GitHub Actions pipelines are organized into a repeatable, version-controlled operating model.
What This Actually Buys You
You can ask “is production still what we think it is?” on demand. Now you can avoid finding out about drift during an outage. Run a plan at any point in the day, and you’ll see whether the live environment still matches the declared state.
Rebuilds stop being a once-a-year fire drill. I use a monthly rebuild cadence with Citrix and NetScaler environments: static, stable components stay in place while rotating layers, like machine catalog generations, get rebuilt from code on a regular schedule. Side-by-side generations, validation, cutover, and retirement become routine motions instead of a scramble. That routine is your disaster recovery rehearsal.
Review happens before impact, not after. A Terraform plan showing exactly what will be created, changed, or destroyed is a fundamentally better review artifact than a screenshot of a console setting or a change-ticket description. A good plan review asks: what resources are actually affected, is the blast radius acceptable, and are secrets excluded from the output? That conversation happens in a pull request, before production is touched.
Terraform and Ansible each do the job they’re actually good at. Terraform owns desired infrastructure state — resource groups, networks, hosting connections, machine catalogs, delivery groups, ADC resources — with a plan/apply lifecycle and remote state. Ansible owns the procedural side — domain join, software installation, guest configuration, smoke tests. Terraform answers “what should exist?” Ansible answers “what should happen inside or after it exists?” GitOps orchestrates both through the same pull request (PR) and pipeline path.
Patching stops requiring heroics. NetScaler’s CVE history is a good example of why this matters: an internet-facing appliance with an aggressive patch cadence requirement is exactly the kind of asset where “I’ll get to it next quarter” becomes a headline. When a firmware version is a variable in code, patching a fleet of NetScaler HA pairs is a pipeline run, not a manual walk through every NetScaler appliance hoping nothing gets missed.
It’s Not Automatically Safe — Say So
If you’re presenting this to a room, don’t oversell it. GitOps can automate mistakes just as fast as it automates good practices, and the biggest anti-pattern I see is partial adoption: production changed sometimes through Terraform and sometimes through the console, with nobody reconciling the difference. That’s still the same ClickOps risk, just with better branding.
There are a few key disciplines that keep it honest:
- Keep secrets and real credentials out of code entirely — use repository secrets and OIDC/federated identity instead of long-lived cloud credentials.
- Review plans like you would review a production change request, not like paperwork.
- Gate high-risk applies rather than auto-applying everything.
- Treat drift as work to resolve, not background noise.
This is also where a shift-left security mindset pays off, and it doesn’t require a big program to start.
A quick bit of context: in a GitOps workflow, a proposed infrastructure change is submitted as a “pull request” — a package of code changes waiting for review before it’s merged into the main codebase that actually gets deployed. “Before merge” means before that change is approved and combined with the production-bound code; nothing in the pull request touches real infrastructure until it’s merged and applied. That review window is valuable real estate, because it’s the one point where a human, or an automated check, can catch a problem before it ever reaches a live NetScaler or DaaS environment.
A few deterministic, high-signal checks running automatically in that window catch the cheap, obvious problems before a change is ever merged: formatting, linting, a security scanner such as tfsec (which scans Terraform code for common misconfigurations like open security groups or missing encryption), and terraform validate run with the backend disabled (a syntax and internal-consistency check that doesn’t require live cloud credentials). Catching these automatically means human review time goes toward design intent and blast radius.
Start these checks as advisory (they report issues without blocking anything), build trust in the signal, then promote the ones that prove reliable to hard gates that block a merge until they pass. Trying to enforce everything on day one just teaches people to route around the gate.
Where to Start: 30/60/90
You don’t need to convert your entire estate at once. A realistic path would be as follows:
Days 0–30 — Codify: Pick one workflow. Build the repository structure, define variables and state, and get a local Terraform plan running successfully.
Days 31–60 — Gate: Add PR validation. Handle secrets and identity correctly (OIDC, not embedded credentials). Require plan review before merge and add lint/scan checks gradually as advisory first.
Days 61–90 — Operate: Move the best-trusted checks to blocking gates, add smoke tests, run drift checks regularly, and perform your first real rebuild exercise.
A reasonable starting point in most EUC shops is a single NetScaler plan workflow or a low-risk DaaS variable change, something with a contained blast radius where a mistake is cheap and a win is visible.
What Success Actually Looks Like
Success isn’t that your team suddenly loves Terraform. It’s that every durable change has:
- A diff (a line-by-line record of exactly what was added, removed, or changed) and an approver — reviewable
- A clean rebuild that uses files instead of human memory — repeatable
- Plan and apply output that produces real evidence — observable
- Known-good state that can be recreated on demand — recoverable
- A visible record of who changed what and why — auditable
The repository is not the end product — the repeatable operating model is.
Closing Thoughts
The pattern running through all of this is simple: production intent that lives only in a console or in someone’s memory is a liability, no matter how well the environment currently runs. Moving that intent into code, and moving changes through a reviewed, pipeline-driven path, doesn’t just make automation possible. It makes drift visible, rebuilds routine, makes patching sustainable, and makes recovery something you’ve already rehearsed rather than something you’re hoping works.
You don’t have to overhaul everything at once. Start with one workflow, put it into code, add a review process, and build from there. If you’re still validating changes before enforcing them or deciding what should be gated, that’s a normal part of the process. In fact, that’s where most teams begin.
The point isn’t to automate for the sake of automation. It’s to build an environment your team understands, can review with confidence, and can reliably rebuild when needed. That’s the real value of moving from ClickOps to GitOps.
If your team is considering this shift but isn’t sure where to start, that’s exactly the kind of problem Ferroque Systems works through with clients every day. Whether it’s structuring a first Terraform root for a NetScaler or DaaS environment, building out a PR-gated pipeline, or planning a realistic 30/60/90-day adoption path, we help EUC teams move from ClickOps to GitOps without disrupting the environment they’re already running. If you’d prefer to have an experienced hand build the first workflow with you rather than try to figure it out solo, that’s a conversation worth having with us.
For More On This Topic, See These Helpful Links
The Presentation at the EUCTech Denmark Conference