In an openresty nginx.conf I would like be able to add locations conditionally based on a feature flag value, like as it follows
env ENABLE_UPSTREAMS;
env UPSTREAM_HOST;
http {
upstream upstream1 {
server ${UPSTREAM_HOST1};
}
upstream upstream2 {
server ${UPSTREAM_HOST2};
}
map $ENABLE_UPSTREAMS $enable_upstreams {
"on" 1;
default 0;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
if ($enable_upstreams = 1) {
location /some-path {
proxy_pass http://upstream1;
}
location /some-path-2 {
proxy_pass http://upstream2;
}
}
}
}
but this does not work. I get as error "location" directive is not allowed here in /usr/local/
.
I tried to include as a separate *.conf file but still the same error.
than I tried
location /some-path {
if ($enable_aws_upstreams = 1) {
proxy_set_header Host $UPSTREAM_HOST;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://upstream2;
}
}
but this end in another error "proxy_set_header" directive is not allowed here in
and on other side I do not want to expose any path if is disabled by feature flag
What is the right way in this case?
Only handful of directives are allowed inside if
block (mosty ngx_http_rewrite_module
directives since if
itself is a part of this module); neither location
nor proxy_*
is allowed, hence the error.
Assuming (from the tag) that you use OpenResty, we can use the power of ngx_http_lua_module
.
Here is a rough example:
env ENABLE_UPSTREAMS;
http {
upstream disabled {
server 127.0.0.1:8001;
}
upstream upstream1 {
# upstream1 mock address for demo purposes
server 127.0.0.1:9001;
}
upstream upstream2 {
# upstream2 mock address for demo purposes
server 127.0.0.1:9002;
}
server {
listen 8000;
location /path-1 {
# we have to predefine the variable
set $upstream '';
# set the actual value depending of the environment variable value
set_by_lua_block $upstream {
if os.getenv('ENABLE_UPSTREAMS') == 'on' then
return 'upstream1'
else
return 'disabled'
end
}
proxy_pass http://$upstream;
}
location /path-2 {
set $upstream '';
set_by_lua_block $upstream {
if os.getenv('ENABLE_UPSTREAMS') == 'on' then
return 'upstream2'
else
return 'disabled'
end
}
proxy_pass http://$upstream;
}
}
# dummy "disabled" upstream, just returns 404
server {
listen 127.0.0.1:8001;
return 404;
}
# upstream1 mock for demo purposes
server {
listen 127.0.0.1:9001;
return 200 'response from upstream1';
}
# upstream2 mock for demo purposes
server {
listen 127.0.0.1:9002;
return 200 'response from upstream2';
}
}
Without the env variable:
$ openresty -p . -c nginx_if.conf
$ curl http://localhost:8000/path-1/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>openresty</center>
</body>
</html>
$ curl http://localhost:8000/path-2/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>openresty</center>
</body>
</html>
With the env variable:
$ env ENABLE_UPSTREAMS=on openresty -p . -c nginx_if.conf
$ curl http://localhost:8000/path-1/
response from upstream1
$ curl http://localhost:8000/path-2/
response from upstream2