Tuesday, December 3, 2024

GitLab CI CD Variables and How to Use Them

Working with GitLab CI CD pipelines is a great way to automate your DevOps processes. In building a CI CD pipeline you can use variables effectively in the CI CD pipeline to reference values you have stored in your GitLab CI CD settings. It is a great way to handle secrets and have these referenced without hardcoding things in your code. Below I will show you what they are and also demonstrate a real-world example of how you can use them in GitLab.

Why use GitLab CI CD variables?

Hard coding values in your code for passwords or tokens is a very bad idea. Avoid hard coding values as it can lead to exposing extremely sensitive data or having your secrets fall into the wrong hands.

Secrets information should always be stored in the settings UI for a pipeline in GitLab and never in the .gitlab-ci.yml file.

  • For a project in the project’s settings
  • For all projects in a group in the group’s setting
  • For all projects in a GitLab instance in the instance’s settings

Caveats to using the GitLab CI CD variables

One thing to remember is that forked projects can’t access the CI CD variables that are available in the parent project. However, if you run a merge request pipeline in the parent project for a merge request from a fork, then the variables will be available in the pipeline.

Protected, masked, and expanded

Even though you are using variables for sensitive data, information can still be exposed in a job log or sent to a third part server. GitLab CI CD has a masked variable feature that helps you reduce the likelihood of accidentally exposing variable values.

GitLab allows having several types of attributes:

  • Protected variables: These are only exposed to protected branches or protected tags. For the most part, you may have non sensitive project configuration, but the protected variables are for sensitive projects.
  • Masked variables: These are hidden in job logs
  • Expanded: Expanded variables treat values as the start of a reference to another variable. Otherwise, the value will be treated as the start of a reference to another variable like variable type variables and what you would expect.

Globally defined variables

Normally for each CI CD pipeline, these are environment scoped project variables. You can also use globally defined variables on GitLab groups so projects in the same group can access environment variables set at this level and variables defined globally. The group variables can save work if you have many projects that are using the same variables. Keep the environment scope in mind when creating variables.

Creating GitLab CI CD pipeline variables

To create a GitLab CI CD pipeline variables, navigate to Settings > CI/CD > Variables > Expand > Add variable.

You can see variables that I have created for a pipeline that runs in my home lab that backs up VMware ESXi configuration to my NAS device. I am using the CI/CD variables to store the vCenter Server credentials and the NAS credentials, along with the vCenter Server hostname. Below, you can see the variables defined for my specific pipeline.

You can click the pencil icon next to each to see the environment variable value. These are simple key and value pair variables defined for sensitive variables.

create a gitlab ci cd pipeline variable
create a gitlab ci cd pipeline variable

Create a gitlab ci cd pipeline instance variable or environment variable for use with your Pipeline. Here you can see the Add variable dialog box. This is where you make selections for visibility, flags, description, key and other configuration.

Launching the GitLab CI CD variable add screen
Launching the GitLab CI CD variable add screen

How do you use GitLab CI CD pipeline variables?

So, how do you use the GitLab CI CD pipeline variables created in the GitLab UI settings for CI/CD? This is actually pretty easy to do. In my PowerCLI script in the above screenshot, you see the variables that will be used for my code to pull the vCenter Server, NAS user and pass and vSphere credentials.

Below is the snippet of code at the top that allows you to use the pipeline variables. As you can see, we use the $env:<VARIABLENAME> to reference the GitLab CI CD variable you configured. These are environment variables that are called from the GitLab variables stored for CI CD purposes.

# Define variables
$vcenterhost = $env:VCENTERHOST
$vsphereuser = $env:VSPHEREUSER
$vspherepassword = $env:VSPHEREPASSWORD
$nasuser = $env:NASUSER
$naspass = $env:NASPASS

Full PowerCLI code using the GitLab variables, so you can see this in context:

# Define variables
$vcenterhost = $env:VCENTERHOST
$vsphereuser = $env:VSPHEREUSER
$vspherepassword = $env:VSPHEREPASSWORD
$nasuser = $env:NASUSER
$naspass = $env:NASPASS

# Generate a timestamp for the parent folder
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$parentFolderPath = "./ESXiConfigs/$timestamp"

# Create the parent folder if it does not exist
if (-not (Test-Path -Path $parentFolderPath)) {
    New-Item -ItemType Directory -Path $parentFolderPath -Force
}

## Setting CEIP options
Set-PowerCliConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip $false -Confirm:$false

# Connect to vCenter Server
Connect-VIServer -Server $vcenterhost -User $vsphereuser -Password $vspherepassword

# Create the parent folder on the NAS
smbclient //10.1.149.4/esxiconfigs -U $nasuser --password $naspass -c "mkdir $timestamp"

# Get all ESXi hosts
$allHosts = Get-VMHost

foreach ($esxihost in $allHosts) {
    # Define export paths
    $hostFolderPath = "$parentFolderPath/$($esxihost.Name)"
    $exportPath = "$hostFolderPath/$($esxihost.Name)_config.vSphereConfiguration"
    $infoPath = "$hostFolderPath/$($esxihost.Name)_info.txt"

    # Create the host-specific folder if it does not exist
    if (-not (Test-Path -Path $hostFolderPath)) {
        New-Item -ItemType Directory -Path $hostFolderPath -Force
    }

    # Export ESXi configuration to a file
    # Create a temporary folder to hold the backup file as Get-VMHostFirmware requires a directory path
    $tempFolder = "$hostFolderPath/temp"
    if (-not (Test-Path -Path $tempFolder)) {
        New-Item -ItemType Directory -Path $tempFolder -Force
    }

    Get-VMHostFirmware -VMHost $esxihost -BackupConfiguration -DestinationPath $tempFolder

    # Move the backup file to the desired location
    $backupFile = Get-ChildItem -Path $tempFolder -Filter *.tgz | Select-Object -First 1
    if ($backupFile) {
        Move-Item -Path $backupFile.FullName -Destination $exportPath
    }

    # Remove the temporary folder
    Remove-Item -Path $tempFolder -Recurse

    # Get ESXi version, build, and image profile information
    $hostVersion = $esxihost.Version
    $hostBuild = $esxihost.Build
    $imageProfileName = $esxihost.ExtensionData.Config.ImageProfileName
    $fullVersion = $esxihost.ExtensionData.Config.Product.FullName

    # Create a text file with version, build, and image profile information
    $infoContent = "ESXi Host: $($esxihost.Name)`n"
    $infoContent += "Full Version: $fullVersion`n"
    $infoContent += "Version: $hostVersion`n"
    $infoContent += "Build: $hostBuild`n"
    $infoContent += "Image Profile: $imageProfileName`n"
    
    $infoContent | Out-File -FilePath $infoPath

    # Upload files to the NAS using smbclient
    smbclient //10.1.149.4/esxiconfigs -U $nasuser --password $naspass -c "cd $timestamp; put $exportPath $(basename $exportPath)"
    smbclient //10.1.149.4/esxiconfigs -U $nasuser --password $naspass -c "cd $timestamp; put $infoPath $(basename $infoPath)"
}

# Disconnect from vCenter Server
Disconnect-VIServer -Server $vcenterhost -Confirm:$false

Write-Host "Export completed. Check $parentFolderPath for the configuration and info files."

Masked variables in job logs

What do masked GitLab CI CD pipeline variables look like in the job logs? As you can see below in the job log output, I have the vCenter Server as a masked variable, so we see it shown as [MASKED] in the logs or temporary file creations.

viewing the gitlab ci cd pipeline variables masked in the job logs
viewing the gitlab ci cd pipeline variables masked in the job logs

Troubleshooting

Let’s look at some troubleshooting in case the variables are not working from GitLab. If the variables are not working:

  • Check to see you have referenced exactly the name fo the variable as it is configured in GitLab – It is easy for typos to creep in and cause issues with the GitLab pipelines
  • Make sure the variable contains the right value – Check to make sure your variable contains the right value.
  • If you see a pipeline variables error message, make note of the error and troubleshoot accordingly by looking at the pipeline logs and the CI CD instance variable being referred to.

Takeaways

Do use GitLab CI CD variables as they can help you avoid hard coding values in your code checked into the repo. Understand the scope of the variables defined and use them accordingly as instance variables or global.

Brandon Lee
Brandon Leehttps://tek2cloud.com
Brandon Lee is the Senior Writer, Engineer and owner at tek2Cloud.com and has over two decades of experience in Information Technology. Brandon holds multiple industry certifications and loves IT automation, modern applications, and cloud technologies along with traditional servers and infrastructure.

Leave a Reply

Read more

Other Posts