Publish NGINX configs with version control

Overview

With F5 NGINX Instance Manager, you can easily edit and publish NGINX configurations to your NGINX Open Source and NGINX Plus instances. This guide explains how to set up your version control system as the source of truth for maintaining NGINX configurations and how to publish modified configurations to any instance or instance group managed by NGINX Instance Manager.

The documentation includes examples of how to publish configurations from GitLab or GitHub as the version control system to manage your configurations.


Before you begin

To complete the instructions in this guide, ensure:

  • NGINX Instance Manager is installed, licensed, and running.
  • You have one or more NGINX data plane instances or instance groups.
  • A version control system maintains your configuration files for at least one instance or instance group.
  • A Docker base image is available to run in the pipeline.

Publishing configurations from version control system

Set up the pipeline

To set up the pipeline to push configuration changes upstream to an instance or instance group, you will define variables for sending API requests to NGINX Instance Manager, prepare the payload for the requests, and define rules to trigger the action using CI/CD Pipelines.

Add a .gitlab-ci.yaml file at the root directory of your repository to manage the configuration files. You can define variables to reference in the pipeline for various purposes, such as sending curl requests to NGINX Instance Manager.

Here are some example variables you might define:

  • CTRL_IP: System IP of NGINX Instance Manager. Example: 198.51.100.1.
  • AUTH_TOKEN: Authorization token for connecting to NGINX Instance Manager. Example: YWRtaW46VGVzdGVudjEyIw==.
  • SYSTEM_UID: System UID of the instance to push configuration changes. Example: fbf7a63f-a394-34b7-8775-93d7d6aceb82.
  • NGINX_UID: NGINX UID of the instance to push configuration changes. Example: 98961494-c999-515c-ae1b-1dd949f78b6e.
  • GROUP_UID: Instance Group UID of the instance group to push configuration changes. Example: 0ba1d2c3-ce36-44da-a786-94fb65425a30.

You can introduce rules in the .gitlab-ci.yaml file to trigger the pipelines when changes are detected in the configuration files. Here’s an example repository structure:

git-automation:
	-> instances
		-> nginx.conf
		-> mime.types
	-> instance-group
		-> nginx.conf
		-> mime.types
	.gitlab-ci.yaml

To run the pipeline only when changes are detected in the instance directory, you could use the following rule:

._run_only_when_change_in_instance_directory:  &_run_only_when_change_in_instance_directory
 changes:
 -  instance/nginx.conf
 -  instance/*

Define pipeline stages

We need to add different pipeline stages, define when the actions will be triggered using rules, and what to run in the pipeline:

stages:
  - publish

publish-config-to-instance:
  image: ${BUILD_IMAGE}
  stage: publish
  script:
    # Run the script that prepares the payload with config changes and required variables
    # ./prepare-payload.sh ${CTRL_IP} ${AUTH_TOKEN} ${SYSTEM_UID} ${NGINX_UID}
  only:
    <<: *_run_only_when_change_in_instance_directory
  needs: []

Prepare the payload

We use a bash script to create a valid payload and send it via POST to NGINX Instance Manager for the instance or instance group. To prepare the payload, encode the file contents of nginx.conf, get the current time in the format Year-Month-DayTHour:Minute:SecondZ, and assign the commit SHA to externalId.

You can find sample scripts for preparing payloads for instances and instance groups.

Example bash script

#!/bin/bash
set  -o  pipefail

DEFAULT_INSTANCE_CONFIG_FILE_PATH="./instance/nginx.conf"
DEFAULT_MIME_TYPES_FILE_PATH="./instance/mime.types"

publish_config_to_instance() {
	local ctrl_ip=$1
	local auth_token=$2
	local system_uid=$3
	local nginx_uid=$4

	if [ -z "${ctrl_ip}" ] || [ -z "${auth_token}" ] || [ -z "${system_uid}" ] || [ -z "${nginx_uid}" ]; then
		echo "Missing required variable"
		exit 1
	fi

	ic_base64=$(base64 < "${DEFAULT_INSTANCE_CONFIG_FILE_PATH}" | tr -d '\n')
	mime_base64=$(base64 < "${DEFAULT_MIME_TYPES_FILE_PATH}" | tr -d '\n')
	update_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
	version_hash="${CI_COMMIT_SHA}"

	payload=$(jq -n --arg versionHash "${version_hash}" --arg updateTime "${update_time}" --arg config "${ic_base64}" --arg mime "${mime_base64}" '{
		"auxFiles": { "files": [], "rootDir": "/" },
		"configFiles": {
			"rootDir": "/etc/nginx",
			"files": [
				{ "contents": $config, "name": "/etc/nginx/nginx.conf" },
				{ "contents": $mime, "name": "/etc/nginx/mime.types" }
			]
		},
		"updateTime": $updateTime,
		"externalId": $versionHash,
		"externalIdType": "git"
	}')

	echo "${payload}" | curl -k -H 'Content-Type: application/json' -H "Authorization: Bearer <access token>" --data-binary @- -X POST "https://$ctrl_ip/api/platform/v1/systems/$system_uid/instances/$nginx_uid/config"
}

publish_config_to_instance "$@"

Publish config changes from version control system

To publish configuration changes, modify the configuration files (nginx.conf) and push your changes upstream to trigger the pipeline. The process is the same whether you are pushing changes to individual instances or to instance groups. You can modify the script and pipeline rules based on whether you’re targeting instances or instance groups.

Note:
You can find a sample template to modify as required in our public repository.

Last modified November 8, 2024