Automating STIG Deployments with Ansible and Gitlab
- 5.15 Technologies
- Apr 29, 2022
- 5 min read
Updated: 5 days ago
Maintaining STIG compliance across systems can be time-consuming, difficult to scale, and prone to configuration drift when performed manually.
Security Technical Implementation Guides (STIGs) are standardized security baselines used to enforce configuration requirements across systems in regulated environments, including DoD and government programs. A STIG defines security controls for specific technologies, ranging from operating systems to network devices.
While STIGs are often implemented manually, this approach does not scale effectively across modern environments. In this guide, we will walk through how to automate STIG deployments on Linux systems using an Ansible playbook provided by DISA (STIGs Document Library – DoD Cyber Exchange) and integrate the process with GitLab.
To accomplish this, we will walk through how to use Ansible and GitLab to build a repeatable, automated STIG deployment workflow:
This workflow includes:
Environment setup
Ansible playbook configuration
GitLab pipeline integration
Deployment execution
Validation and compliance checks
What is GitLab?
GitLab is a DevOps and DevSecOps platform that enables teams to automate workflows through Continuous Integration and Continuous Delivery (CI/CD). It provides a centralized toolset for source code management, pipeline automation, and integrating security and operational processes.
In the context of STIG deployments, GitLab allows teams to integrate secure configuration management directly into the delivery pipeline, ensuring deployments are consistent, repeatable, and aligned with compliance requirements.
GitLab offers both paid and free versions, allowing organizations to scale based on their needs. There are also a number of features included in the free version. Organizations can choose to host GitLab within their own environment or use GitLab cloud. We typically recommend GitLab Ultimate, as it provides expanded capabilities for enterprise-scale workflows and security integration.
What is Ansible®?
Ansible is an infrastructure-as-code tool used for configuration management, software provisioning, and application deployment. For the purposes of this guide, we will use Ansible as a configuration management tool to automate STIG deployments across systems.
In this implementation, Ansible will be used on Linux systems, though it also supports Windows environments. Communication with target systems is handled over SSH, which supports multiple authentication methods. For simplicity, this guide will use password-based authentication.
Why Automate STIG Deployments with GitLab?
The process for deploying STIGs can be cumbersome when it all needs to be done manually; especially if you have hundreds, or even thousands, of machines that you need to keep compliant. Most environments are likely Windows based, so deploying STIGs may not be so bad because DISA provides Group Policies Objects, which can be applied to entire Organizational Units (OU's), to keep systems compliant.
But what if you have Linux systems? That is where Ansible comes in. DISA provides a few Ansible playbooks for different Linux flavors, network devices, or even Docker. Now that you know what GitLab and Ansible are as well as why you would use them, let’s start talking about how this can all be implemented.
What You Will Need
Since the STIGs are provided as an Ansible playbook, all you must do is set up your GitLab repository file structure to make use of any, and all, playbooks you may need. There isn’t a lot that is needed to build this setup. The systems and software needed for each are listed below:
Hardware:
1 Linux system
Software:
Linux (Ubuntu or RHEL):
- Ansible
- Sshpass (only needed if using password authentication)
- OpenSSH
- GitLab Runner
As you can see, the setup is rather simple. The GitLab runner is used to run the pipeline on an internally hosted system instead of using GitLab’s provided shared runners. The reason this is needed is because the shared runners would not have access to the systems that need to be scanned in your environment.
Put it All Together
Now that we have some background on all the hardware and systems needed, let’s look at how it all works. To start, this is the structure of the GitLab repository.
NOTE: If you want to deploy STIGs using Ansible, you will likely need to add “become: true” to the site.yml files that are in the root of each downloaded DISA Ansible zip file.

As you can see, the naming conventions for most of the files and folders correlate to the operating system, or version, that is going to be scanned. This repository uses manually created host files, but these could also be created automatically depending on the tools used in the environment. There are host files for each version and flavor of Linux that needs a STIG deployed; In this instance, we are doing Ubuntu 18 and RHEL 8. The names of the files are used in the GitLab pipeline to determine which Ansible playbook needs to be run.
Before we look at the GitLab YAML, let’s look at the Project variables needed in GitLab. This part is only needed if you are doing username/password authentication with Ansible. This is not the most secure way, but we are using it here for simplicity. The variables needed for this setup would be RHEL_ROOT_PASS, RHEL_USERNAME, UBUNTU_ROOT_PASS, UBUNTU_USERNAME. These variables are used to login to the RHEL/Ubuntu machine(s) for remote command execution over SSH.
Now, it’s time to move on to the gitlab-ci.yml file. Starting from the top, we have the stages and the deployment template, identified by the period (‘.’) at the start of the name, that is used for all Linux systems. This template can be used on several Linux flavors so long as the correct variables are used. This template will first identify all files with the OS flavor in the name of the file; rhel_8.txt, for instance, in our repository. It will then iterate through each file and run the Ansible playbook against each host defined in the file.
stages:
- stig-deployment
.linux-stig-deployment:
script:
- >
FILES=$(find $FOLDER -maxdepth 1 -name "*$OS*" -type f)
if [[ $FILES ]]; then
for FILE in $FILES; do
VERSION=$(echo $FILE | cut -d'_' -f2 | cut -d'.' -f1)
if [ -s $FILE ]; then
ansible-playbook ./ansible/$OS/$VERSION/site.yml -i $FILE -u $USERNAME \
--extra-vars "ansible_sudo_pass=$ROOT_PASS ansible_ssh_pass=$ROOT_PASS" \
--ssh-common-args "-o StrictHostKeyChecking=no"
fi
done
fi
tags:
- ansibleThe last part of the gitlab-ci.yml file are the two jobs in the pipeline that execute the scans, as seen below. These jobs are very similar, with the only real change being the variables used for the username and password, that was discussed previously, and then the Linux flavor for the “OS” variable.
ubuntu-stig-deployment:
stage: stig-deployment
extends: .linux-stig-deployment
variables:
OS: ubuntu
USERNAME: $UBUNTU_USERNAME
ROOT_PASS: $UBUNTU_ROOT_PASS
FOLDER: deployments
rules:
- if: $CI_PIPELINE_SOURCE == "push"
when: never
- if: $CI_PIPELINE_SOURCE == "schedule"
rhel-stig-deployment:
stage: stig-deployment
extends: .linux-stig-deployment
variables:
OS: rhel
USERNAME: $RHEL_USERNAME
ROOT_PASS: $RHEL_ROOT_PASS
FOLDER: deployments
rules:
- if: $CI_PIPELINE_SOURCE == "push"
when: never
- if: $CI_PIPELINE_SOURCE == "schedule"If we focused on the RHEL STIG deployment job, when it starts, it runs the script block identified in the “linux-stig-deployment” template job; due to the extends property. This job would search in the deployments’ folder, defined by the “FOLDER” variable, for any files that match the value of the “OS” variable. It would iterate through each file, get the version that needs to be deployed by looking at the name of the file, and then run the appropriate Ansible playbook accordingly.
Final Thoughts
Automating STIG deployments for Linux systems enables organizations to move beyond manual configuration efforts and toward repeatable, scalable compliance operations.
By leveraging Ansible and integrating deployment workflows into GitLab pipelines, teams can reduce configuration drift, improve consistency, and eliminate common issues like “fat fingering” configurations or missing critical steps during deployment.
While these playbooks may not cover every edge case, they significantly reduce the operational burden and help standardize secure configurations across environments.
If you are looking to automate secure configuration management, integrate compliance into your delivery pipelines, or scale infrastructure automation, 5.15 Technologies can design and implement a solution tailored to your environment.
Explore how automation can standardize compliance and improve operational consistency across your environment.




Comments