How to Create and Update Gitlab CI/CD Variables Using PowerShell

Bernice ChoyBernice Choy
3 min read

Context

I needed to create multiple CI/CD variables in Gitlab on my Windows machine. I chose to be lazy and skip the Clickops, so I automated everything instead using PowerShell 🤪️️️️️️

Prerequisite

  1. Create a personal access token with api scope to invoke the Gitlab REST API.

  2. Retrieve your project id in Settings > General

  3. Store them into your PowerShell terminal as an environment variables.

$env:gitlab_token='REPLACE_VALUE_WITH_API_TOKEN'
$env:project_id='REPLACE_VALUE_WITH_PROJECT_ID'

TLDR;

  • You can refer to the complete script in this project repository if you want to jump right into action

Step-by-Step Walkthrough

  1. First up, defining the Gitlab token and project ID as variables in the PowerShell script
# User token and project id
$GITLAB_API_TOKEN="$env:gitlab_token"
$PROJECT_ID="$env:project_id"

# To toggle between create / update
$ACTION="create" 
#$ACTION="update"
  1. Then we define the Gitlab endpoints required. In this case, we are using the Project-level CI/CD variables API, along with the headers that will be used in the API calls.
# Gitlab endpoints
$GITLAB_BASE_URI = 'https://gitlab.com'
$GITLAB_BASE_API = "$GITLAB_BASE_URI/api/v4"

# Target API for Project-level CI/CD variables
$GITLAB_URI="$GITLAB_BASE_API/projects/$PROJECT_ID/variables"

# Headers
$Headers = @{
    "Authorization" = "Bearer $GITLAB_API_TOKEN"
}
  1. Next, we will define an array of hashtable that will contain the key-value pair for the CI/CD variables.

    • Each hashtable contains the form data for 1 CI/CD variable

    • You can define multiple hashtable inside the array

    • The protected, masked and raw keys are to determine whether the variable needs to be protected, masked and treated as a literal string respectively.

# Key-value pairs should be customized here to your needs
$VariableForm = @(
    @{
        "variable_type" = "env_var"
        "key" = "sample_key1"
        "value" = "dummy"
        "protected" = $false
        "masked" = $false
        "raw" = $true
        "environment_scope" = "*"
        "description" = "Sample key 1 created"
    },
    @{
        "variable_type" = "env_var"
        "key" = "sample_key2"
        "value" = "dummydummy"
        "protected" = $false
        "masked" = $false
        "raw" = $true
        "environment_scope" = "*"
        "description" = "Sample key 2 created"
    }
)
  1. To invoke the REST API, we will be using Invoke-WebRequest command.

  2. I have written the CreateVariablesForProject function to call the create variable API.

function CreateVariablesForProject([string] $gitlab_url, [hashtable] $headers, [object[]] $form) {

    $form | ForEach-Object {
        $current_form = $_
        $Result = Invoke-WebRequest -Uri $gitlab_url -Method Post -Headers $headers -Form $current_form
        Write-Output $Result
    }

}
  1. I have also written the UpdateVariablesForProject function to call the update variable API.

    The only difference is PUT method and the API URL needs to append the value of variable_key.

function UpdateVariablesForProject([string] $gitlab_url, [hashtable] $headers, [object[]] $form) {
    $form | ForEach-Object {
        $current_form = $_
        $variable_key = $current_form.key
        $gitlab_update_url = "$gitlab_url/$variable_key"
        $Result = Invoke-WebRequest -Uri $gitlab_update_url -Method Put -Headers $headers -Form $current_form
        Write-Output $Result
    } 
}
  1. Finally, we will invoke the function to trigger the actual creation of the CI/CD variables in the target project repository.
Write-Output "[info] Create CI/CD variables for Target Project"
CreateVariablesForProject $GITLAB_URI $Headers $VariableForm

if ( "$ACTION" -eq "create") {

    Write-Output "[info] Create CI/CD variables for Target Project"
    CreateVariablesForProject $GITLAB_URI $Headers $VariableForm

} elseif ("$ACTION" -eq "update") {
    Write-Output "[info] Update CI/CD variables for Target Project"
    UpdateVariablesForProject $GITLAB_URI $Headers $VariableForm

}

Conclusion

I decided to embrace my inner laziness and avoid the dreaded Clickops by automating everything with PowerShell instead of the usual shell-script. It's a bit unconventional, but hey, it should save us all some time when creating and updating CI/CD variables on GitLab from a Windows machine. Cheers! 🤪️️️️️️

0
Subscribe to my newsletter

Read articles from Bernice Choy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Bernice Choy
Bernice Choy

A fledgling engineer dabbling into areas of DevOps, AWS and automation. I enjoy tinkering with technology frameworks and tools to understand and gain visibility in the underlying mechanisms of the "magic" in them. In the progress of accumulating nuggets of wisdom in the different software engineering disciplines!