Using GitLab to Build and Deploy Windows Containers on Azure Kubernetes Service
Published Aug 03 2023 03:00 AM 7,887 Views

This blog post has been co-authored by Microsoft and Darwin Sanoy a Principal SA in GitLab Alliances


The GitLab DevSecOps Platform supports the Microsoft development ecosystem with performance, accessibility testing, SAST, DAST and Fuzzing security scanning, dependency scanning, SBOM, license management and more. As an extensible platform, GitLab also allows you to plug-in your own tooling for any stage. GitLab's integration with Azure Kubernetes Services (AKS) enables full DevSecOps workflows for Windows and Linux Container workloads using either Push CD or GitOps Pull CD with flux manifests. Using Cloud Native Buildpacks, GitLab Auto DevOps can build, test and autodeploy .NET projects. GitLab is an extensible and scalable software delivery platform in much the same way as Azure is an extensible and scalable workload operations platform. GitLab covers the full range of DevOps capabilities.


While GitLab fully enables DevOps, it is easily adaptable to any development and operations management methodology that might be in use. Together GitLab and Azure allow the developers at both small and large organizations to stay tightly focused on creating and innovating value for their target customers. No one wants to earn a certification in automotive maintenance before having the benefits of driving a personal vehicle. When developers leverage the extensible platform model, they can avoid recreating the wheels of well-known patterns that those platforms have opinionated for them. Extensible platforms have extensibility at every level, so that any required accommodation that differs from the platform can be accomplished with a small amount of code modifications.


Tutorial with Full Working Example Code

This article focuses on architectural requirements for this pattern. For a full tutorial with working example code for setting up the infrastructure and building and deploying Windows containers to AKS, please check Tutorial: GitLab CI Build and Deploy for Windows Containers on Azure AKS.


GitLab Does All the GitOps Securely

Over time, two distinct ideas of what exactly “GitOps” is have evolved. GitLab is designed to do both with features inherent in GitLab Runner and GitLab Agent for Kubernetes. In the case of traditional push deployment to Kubernetes clusters, the GitLab Agent for Kubernetes enhances the security posture by reaching out to the Kubernetes Agent Service so that Kubernetes Control planes never have to be publicly exposed.



Runners and Infrastructure Required for GitLab Stages

Let’s take a look at GitLab’s normal container development workflow and analyze what type of compute we’ll need to do Windows Container development.


GitLab Container Registry

GitLab container registry is used during development because container write operations can use built-in GitLab security and no secrets need to be stored. External registries can be used, but this pattern is generally limited to the production installation where it is important that the container registry be collocated to the clusters they serve to avoid lag as well as bandwidth egress / ingress charges in complex cloud environments.


Build Stage

Any container pipeline requires that we first build the container so that it can be scanned and tested in various ways.


Windows containers cannot run Docker In Docker. This means that building Windows containers with native Windows shell commands (PowerShell and cmd) will require a GitLab shell runner on Windows with Docker installed.


Due to the size of the containers, the first run will take a while. Since we’ve used the GitLab Runner Pull Policy “if-not-present”, subsequent builds will use any layers still on the runner and in the GitLab Container registry for the project.

CI Infrastructure Requirement: Windows VM Running GitLab Runner and Docker with tags to be used only for Windows docker builds.


Test Stage

GitLab has many test jobs including many security scanners. These all run in Linux containers. This means our AKS cluster must have a Linux Node Group and that we install a GitLab runner in that node group and have it default to running containers on the Linux node group. Since AKS Clusters use Linux for their control plane, it is not unusual to have Linux nodes in a cluster even if its primary purpose is to run a Windows Container workload. Since GitLab’s Linux runner is packaged as a helm chart (and the Windows Runner is not), this also allows us to leverage the GitLab maintained Helm chart.

GitLab has many Linux based source code scanners that can easily run against Windows source code without having to run specifically in Windows Containers.


If you create test jobs that must run on Windows Containers, you can ensure that job runs on a Windows node pool using either runner tags or CI Job override variables. These two options are discussed in the section in this document titled Pod Scheduling on OS Based node groups.

CI Infrastructure Requirements: Linux Node Pool for GitLab Runner. Windows Node Pool configured with NoSchedule taint for performing Windows Container steps and review environments. GitLab Runner Deployed.


Deploy Stage

The deployment stage can either be handled by Runner Push CD - which is what you’d use if your Kubernetes deployments consist of kubectl and helm CLI commands.  The GitLab Agent can also pull process Kubernetes or Flux manifests. The GitLab Agent comes with the additional benefit of regular configuration reinforcement on a polling interval.

CI Infrastructure Requirements: Linux Node Pool for GitLab Agent and/or Runner. Windows Node Pool configured with NoSchedule taint for installing the review environment or production environment. Gitlab Agent for Kubernetes Deployed.


Summary of Infrastructure Configuration

The following diagram displays a sample minimalist configuration (least config). The GitLab instance is just for reference and not deployed as part of the working Infrastructure as Code.


GitLab and AKS Better Together

GitLab supports the complete lifecycle of development and deployment of Windows containers to Azure Kubernetes Service (AKS). Customers on AKS using Gitlab can:

  • Have full flexibility to use GitLab SaaS, Dedicated or Self-Managed because the key integration technologies are GitLab Agent and GitLab Runner.
  • Leverage AKS easy support for Linux Node pools to auto scale the Linux version of GitLab Runner for doing Windows CI build and scan jobs and for doing Windows CD push Application deployments (helm commands) to Windows node pools (except Docker in Docker).
  • Leverage AKS easy support for Linux node pools to run the Linux version of GitLab Agent for Kubernetes to manage GitOps CD Pull style deployments to Windows Node Pools (and Linux Node Pools if applicable). GitLab Agent supports standard Kubernetes manifests and flux manifests.
  • Leverage the flexibility of using a VM based Windows shell runner for Windows container builds using sidecar docker runtimes or, alternatively Azure build services for Windows container builds.
  • Leverage GitLab’s Semgrep SAST scanning for Microsoft computing languages and NuGet dependency scanning for SBOM, License compliance and dependency vulnerabilities.
  • Take advantage of GitLab’s DAST Scanning can also be used by standing up a running copy of the application in the CI pipeline (not part of the tutorial).
  • Utilize GitLab’s Single Source of Truth (SSOT) Merge Request view of all softare defects, including all vulnerabilities.

We invite you to contact your Microsoft or GitLab account team if you need more assistance or have questions.


Fully Working Example Code and Tutorial Maintenance

All the code and snippets needed to stand up a working example as the diagram above are available and will be updated with needed changes and fixes at our Guided Explorations repository.


This repository guides you through an end-to-end scenario, including setting up the environment, deploying GitLab agent to AKS cluster, deploying Kubernetes app to cluster, building a Windows container using GitLab CI, GitLab security scanning, Gitlab pull deployment using the GitLab agent, and more.


For more information on GitLab, pay us a visit and check our documentation page.

Version history
Last update:
‎Aug 04 2023 10:44 AM
Updated by: