About Snippets
Overview
The NGINX Controller Application Delivery (AD) module lets you configure NGINX directives that aren’t represented in the NGINX Controller API via “config snippets”, or “Snippets”. You can do so by using either the user interface (UI) or the Application Delivery REST API.
Caution:
When you use Snippets to customize your NGINX configuration, your changes are applied to the
nginx.conf
file as is. NGINX Controller does not verify that your configuration is valid before applying the snippet.We strongly recommend verifying Snippets in a lab environment before making any changes in production.
Types of Snippets
There are five types of Snippets, which you can configure for gateways or components. This lets you add custom directives into the corresponding NGINX configuration blocks generated by the gateways and components for the associated URIs.
Note:
TheuriSnippets
can’t be used for TCP/UDP components.
Snippet | Description | Corresponding API Endpoint |
---|---|---|
httpSnippet |
Adds directives to the http block. |
Gateway |
mainSnippet |
Adds directives to the main block. |
Gateway |
streamSnippet |
Adds directives to the stream block. |
Gateway |
uriSnippets |
Adds directives to the component’s server and location blocks. |
Component |
uriSnippets |
Adds directives to the gateway’s server blocks. |
Gateway |
workloadGroupSnippets |
Adds directives to the upstream blocks. |
Component |
Best Practices
Gateway Partitions
It’s important to avoid adding conflicting snippets to the same context in your NGINX configuration file. We recommend that you create one stand-alone Gateway to hold the main
, http
, and stream
snippets. Doing so lets you share the configuration for these contexts across Gateways that define the URIs (server
blocks) for particular instances while reducing the risk of duplicate or conflicting settings.
NGINX Variables
NGINX configurations commonly use NGINX variables or custom variables. If you prefer to configure NGINX Controller by using the REST API, you may run into problems with variable expansion when sending JSON as part of a curl
request using th -d
flag. The recommended best practice for this is to reference the JSON in a data file instead of sending the string as part of the request. An alternative is to redefine the variable to itself, which allows the variable to pass through to the NGINX configuration. If you’re using the NGINX $host
variable in your JSON data – represented by the <data>
placeholder in the example below – you would define the variable before the curl request as follows:
host='$host' curl -s -k -H "Content-Type: application/json" -X PUT -d "<data>" https://192.168.100.10:80/
Usage Examples
Caution:
The examples provided here are intended for demonstration purposes only. We strongly recommend verifying Snippets in a lab environment before making any changes in production.
Add HTTP Strict Transport Security Headers
If you want to implement a HTTP Strict Transport Security (HSTS) policy, you can add a snippet to your gateway. For example:
{
"metadata": {
"name": "<gateway-name>"
},
"desiredState": {
"configSnippets": {
"uriSnippets": [
{
"applicableUris": [
{
"uri": "http://172.16.0.238:81"
}
],
"directives": [
{
"directive": "add_header",
"args": ["Strict-Transport-Security", "max-age=31536000; includeSubDomains", "always"]
}
]
}
]
},
"ingress": {
"uris": {
"http://example.com:8020": {}
},
"placement": {
"instanceRefs": [
{
"ref": "/infrastructure/locations/unspecified/instances/<instance-name>"
}
]
}
}
}
}
Allow or Deny IP Addresses
You can add IP addresses to your allow- or deny-list by using the allow
or deny
directives in a gateway snippet. For example:
{
"metadata": {
"name": "<gateway-name>"
},
"desiredState": {
"configSnippets": {
"uriSnippets": [
{
"applicableUris": [
{
"uri": "<gateway URI>"
}
],
"directives": [
{
"directive": "deny",
"args": ["192.0.2.2"]
},
{
"directive": "allow",
"args": ["192.0.2.1/24"]
},
{
"directive": "allow",
"args": ["2001:0db8::/32"]
},
{
"directive": "deny",
"args": ["all"]
}
]
}
]
},
"ingress": {
"uris": {
"http://example.com:8020": {}
},
"placement": {
"instanceRefs": [
{
"ref": "/infrastructure/locations/unspecified/instances/<instance-name>"
}
]
}
}
}
}
Load the NGINX Prometheus Module
In order to use the [NGINX Prometheus-njs]https://docs.nginx.com/nginx/admin-guide/dynamic-modules/prometheus-njs/) module with NGINX Controller, you need to use load_module
in the main
context, js_import
in the http
context, and js_content
in the location
. NGINX Controller automatically enables the location api location /api
, which is also required for metrics reporting.
After installing the module, add the following Snippets to your gateway. This will add load_module
and js_import
:
{
"metadata": {
"name": "<gateway-name>"
},
"desiredState": {
"configSnippets": {
"mainSnippet": {
"directives": [
{
"directive": "load_module",
"args": ["modules/ngx_http_js_module.so"]
}
]
},
"httpSnippet":{
"directives": [
{
"directive": "js_import",
"args": ["/usr/share/nginx-plus-module-prometheus/prometheus.js"]
}
]
}
},
"ingress": {
"uris": {
"http://example.com:8020": {}
},
"placement": {
"instanceRefs": [
{
"ref": "/infrastructure/locations/unspecified/instances/<instance-name>"
}
]
}
}
}
}
Then, you’d add a config snippet similar to the example below to your component.
{
"metadata": {
"name": "<gateway-name>"
},
"desiredState": {
"configSnippets": {
"uriSnippets": [
{
"applicableUris": [
{
"uri": "/metrics"
}
],
"directives": [
{
"directive":"js_content",
"args": ["prometheus.metrics"]
}
]
}
]
},
"ingress": {
"uris": {
"http://example.com:8020": {}
},
"placement": {
"instanceRefs": [
{
"ref": "/infrastructure/locations/unspecified/instances/<instance-name>"
}
]
}
}
}
}
NGINX as a WebSocket Proxy
If you want to use NGINX Controller to configure NGINX as a WebSocket Proxy, you can customize your nginx.conf
by using Snippets and header programmability.
In the gateway, provide an http
snippet that defines the map
directive and the server
configuration:
{
"metadata": {
"name": "<gateway-name>"
},
"desiredState": {
"configSnippets": {
"httpSnippet": {
"directives": [
{
"directive": "map",
"args": ["$http_upgrade", "$connection_upgrade"],
"block": [
{
"directive": "default",
"args": ["upgrade"]
},
{
"directive": "''",
"args": ["close"]
}
]
}
]
}
},
"ingress": {
"uris": {
"http://example.com:8020": {}
},
"placement": {
"instanceRefs": [
{
"ref": "/infrastructure/locations/unspecified/instances/<instance-name>"
}
]
}
}
}
}
Then, add the two required headers to the component using requestHeaderModifications
. For example:
{
"metadata": {
"name": "<component-name>",
},
"desiredState": {
"ingress": {
"uris": {
"/": {}
},
"gatewayRefs": [
{"ref": "/services/environments/${env}/gateways/<gateway-name>"}
]
},
"programmability": {
"requestHeaderModifications": [
{
"action": "ADD",
"headerName": "Upgrade",
"headerValue": "$http_upgrade"
},
{
"action": "ADD",
"headerName": "Connection",
"headerValue": "$connection_upgrade"
}
]
},
"backend": {
"workloadGroups": {
"websocket": {
"uris": {
"http://<data-host-name>:8010": {}
}
}
}
}
}
}
Forward Errors Logs to Remote Syslog
If you want to forward HTML error logs to syslog, you can add the error_log
directive snippet to your gateway.
For example:
{
"metadata": {
"name": "<gateway-name>"
},
"desiredState": {
"configSnippets": {
"httpSnippet": {
"directives": [
{
"directive": "error_log",
"args": ["syslog:server=<data-host-name>", "debug"]
}
]
}
},
"ingress": {
"uris": {
"http://example.com:8000": {}
},
"placement": {
"instanceRefs": [
{
"ref": "/infrastructure/locations/unspecified/instances/<instance-name>"
}
]
}
}
}
}
Note:
Theerror_log
andaccesslog
directives can appear at various block levels (main
,http
,stream
,server
,location
, etc.). NGINX Controller adds these directives to control logging to the local file. When using Snippets to add additional logging capabilities, the inner blocks override the outer block definitions. For example, if you enable remote logging for errors at themain
level, and you add anerror_log
directive to aserver
orlocation
block that uses local logging, the local logging configuration overrides the remote logging configured at themain
level.
Extend App Security with Snippets
When adding NGINX Controller App Security to your components, you can use Snippets to add NGINX App Protect directives that aren’t represented in the NGINX Controller API. You can also use Snippets to tune your NGINX App Protect WAF performance.
Refer to Extend App Security with Snippets for more information and examples.
This documentation applies to the following versions of NGINX Controller App Delivery module: 3.22, 3.22.1 and 3.22.2.