{"id":34,"date":"2022-08-10T22:35:21","date_gmt":"2022-08-10T12:35:21","guid":{"rendered":"https:\/\/kevinyipeio.com\/blog\/?p=34"},"modified":"2022-08-11T12:17:20","modified_gmt":"2022-08-11T02:17:20","slug":"nginx-for-proxying-to-aws-load-balancer-dynamic-ip-resolver-url-parameters","status":"publish","type":"post","link":"https:\/\/kevinyipeio.com\/blog\/2022\/08\/10\/nginx-for-proxying-to-aws-load-balancer-dynamic-ip-resolver-url-parameters\/","title":{"rendered":"Nginx for proxying to AWS Load Balancer Dynamic IP Resolver + URL Parameters"},"content":{"rendered":"\n<p>The story goes that we have a web-app running on AWS Elastic Container Service in a Docker container and is served with nginx. It is exposed to the internet via a public-facing load balancer. <\/p>\n\n\n\n<p>We also have an API service in another container that the web-app will have to access to perform some tasks. It is resolved in an internal\/private load balancer. Now if we were to call the API directly with the internal load balancer API URI, we will get a CORS issue as it&#8217;s trying to access something on a different domain.<\/p>\n\n\n\n<h4>Creating a proxy_pass<\/h4>\n\n\n\n<p>To fix this, we create a rule in the <code>nginx.conf<\/code> of the web-app to proxy a path of the nginx server of the web-app to point to the internal load balancer API URI which will be used by the app to access the API.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location \/some-service-api\/ {\n  proxy_pass http:\/\/internal-load-balancer-url\/some-service-api\/;\n}<\/code><\/pre>\n\n\n\n<h4>Stale IP<\/h4>\n\n\n\n<p>This looks fine and dandy, however an issue will arise when the container has been running for a certain period of time. The IP address that is resolved when we pass the URI to proxy_pass will become stale as the IP address of the load balancer is dynamic in AWS. Therefore the location will be pointing to a stale IP that is no longer in use.<\/p>\n\n\n\n<h4>Resolving dynamic IP address of load balancer URI<\/h4>\n\n\n\n<p>To fix the above issue, we add a resolver IP address which will be the IP in your internal network VPC. Then we create a variable and set it to the URI and pass that variable into <code>proxy_pass<\/code>. This will make the IP address be dynamically resolved so that the location will always be pointing to the correct IP address of your internal load balancer.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location \/some-service-api\/ {\n  resolver 10.1.0.2;\n  \n  set $some_service_uri_var http:\/\/internal-load-balancer-url\/some-service-api\/;\n\n  proxy_pass $some_service_uri_var;\n}<\/code><\/pre>\n\n\n\n<p>Great, that works, but now if your API has endpoint paths, you may start getting 404s.<\/p>\n\n\n\n<h4>The final fix (I promise) &#8211; getting path parameters<\/h4>\n\n\n\n<p>To fix, we need to grab the path parameters by first using a nginx global variable: <code>$request_uri<\/code> which contains the path of the request (e.g. \/some-service-api\/users?id=2). We then grab everything after the first trailing slash and put it in a <code>$path_remainder<\/code> variable. Then when we set the internal load balancer API URI variable, we append the <code>$path_remainder<\/code> then pass the final variable into <code>proxy_pass<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    location \/some-service-api\/ {\n      resolver 10.1.0.2;\n\n      if ($request_uri ~* \"\/some-service-api\/(.*$)\") {\n          set  $path_remainder  $1;\n      }\n\n      set $some_service_uri_var http:\/\/internal-load-balancer-url\/some-service-api\/$path_remainder;\n\n      proxy_pass $some_service_uri_var;\n    }<\/code><\/pre>\n\n\n\n<p>Okay, we&#8217;re done. Hope you find this useful and that Google will point more people like you here who are having this issue as I had to look deep and hard and go through many sources to combine the knowledge to put this solution together. Also, forgive my lack of in-depth knowledge in nginx as I&#8217;m still a bit of a n00b ;). Cheers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The story goes that we have a web-app running on AWS Elastic Container Service in a Docker container and is<a class=\"more-link\" href=\"https:\/\/kevinyipeio.com\/blog\/2022\/08\/10\/nginx-for-proxying-to-aws-load-balancer-dynamic-ip-resolver-url-parameters\/\"><span data-hover=\"Read More\">Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":42,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/posts\/34"}],"collection":[{"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":11,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"predecessor-version":[{"id":48,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions\/48"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/media\/42"}],"wp:attachment":[{"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kevinyipeio.com\/blog\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}