0

I'm trying to set up a loadbalancer that would redirect to specific version of an application certein users. So far i was using Blue/Green deployment strategy (so once i made new version of an app i created new environment and redirected traffic there). Now i would like to change this approach. I want to be able to specify users (more experienced or whatever) that would see new site after authentication while the others would still be redirected to old one. If something goes wrong with new version all users will see old version. Currently my loadbalancing is made in apache and authentication is done on application level. So is this even possible? I know i could hardcode it in application but what if there is a bug in new feature and new users are still being redirected there? I would then need to stop application for all users and rollback to old version and that's bad i guess. I was thinking about using external CAS however didnt find any information if it would be possible then. So i would like to ask is it possible and are there any tools (maybe some apache plugin) for that purpose?

peter Schiza
  • 387
  • 7
  • 23
  • Are you looking for a solution working in apache exclusively or an alternative solution i.e using nginx would be fine too? – Oleg Kuralenko Jan 24 '18 at 20:38
  • Anything would be good. I assume apache or nginx wont let me do that because first i need to authenticate user to application or CAS. And then redirect users with specific roles to new version of my application. – peter Schiza Jan 24 '18 at 21:14
  • Which version of the app is a non-authenticated user supposed to see? Is it ok if such a user first sees an old version of the app and once he gets authorized he is redirected to the new version? – Oleg Kuralenko Jan 25 '18 at 05:03
  • I would like non-authenticated users to see old version. Yes its okay that those "special" users first see old version and after login the new one. Basically the point is to let more experienced users test new version before deploying it as main one. – peter Schiza Jan 25 '18 at 16:46

1 Answers1

1

Here's a working solution with nginx

  1. create conf.d/balancer.conf
  2. put the code into it (see below)
  3. docker run -p8080:8080 -v ~/your_path/conf.d:/etc/nginx/conf.d openresty/openresty:alpine
  4. use curl to play with it

balancer.conf:

map $cookie_is_special_user $upstream {
    default http://example.com;
    ~^1$ http://scooterlabs.com/echo;
}

server {
    listen 8080;
    resolver 8.8.8.8;

    location / {
        proxy_pass $upstream;
    }
}

testing

curl --cookie "is_special_user=1" http://localhost:8080

It would return the contents of scooterlabs.com dumping the request it receives

curl http://localhost:8080

Produces the contents of example.com

explanation

  • the idea is that you set a special cookie to the users you treat as special by the backend app after they get authorized as usual
  • of course it would only work if both app versions are served on the same domain so that the cookie is seen by both versions
  • after that you balance them to a desired server depending on the cookie value
  • you can easily disable such routing by tweaking your nginx config file
  • with this approach you can come up with even more complex scenarios like setting random cookie values in the range 1-10 and then gradually switching some of the special users in your config file i.e. start with those having value 1, after that 1-2 etc
Oleg Kuralenko
  • 11,003
  • 1
  • 30
  • 40
  • Thanks for your answer, but have some questions/doubts about it (i might be wrong tho and don;t fully understand this idea). So lets say i have 2 versions of spring boot apps. Successful authentication to app1 will redirect me to app2 but i wont be authenticated there right? (using 2 separate tomcat servers, so session wont be shared). Any idea how to deal with that? I thought about CAS but then would need to add that cookie during CAS authentication and that would require tweaking with CAS code. – peter Schiza Jan 25 '18 at 22:41
  • Yes this solution implies your sessions are shared elsewhere. I'm not sure about j2ee/spring/tomcat world and the way spring.cas handles sessions - such restrictions have not been mentioned in the question. I.e in python apps that's totally fine to have sessions stored somewhere in memcached/redis so that one can safely have multiple backend instances of the app. – Oleg Kuralenko Jan 26 '18 at 05:14