Sunday, May 14, 2017

Hosting an Angular 2 app with deep linking support in OpsWork (Chef 11 Stack)


The Problem

We recently developed an Angular 2 web application and after deploying it to a staging we encountered an issue with link sharing not working. The application was hosted on an AWS OpsWorks stack using the static web server layer.The static web server layer uses NGINX to serve the web application. The link sharing did not work as the links did not correspond to actual resources available on the server.


How do we support deep links ?

The knowledge of the link resource is available to the application router and thus NGINX needs to be instructed to route all traffic to the application root when a resource is not found. This can be achieved using the try_files directive [6] as follows:

try_files $uri$args $uri$args/ /index.html;

To test this we SSHed into the instance and accessed enabled sites configuration for the application. This is usually accessible at /etc/nginx/sites-enabled. The try_files  directive was added to the following block:


After making the change we restarted the NGINX service using the following command:

sudo service nginx restart

Working with OpsWorks

It worked! we were able to share links. However, we were now faced with the problem of adding this configuration to the OpsWork Stack configuration. The above configuration cannot be added using an attribute and instead must override a configuration template. The steps for doing this are listed here [3]:
  1. Identify the cookbook that contain the configuration template. In this case it was the nginx cookbook which is located here [7].
  2. Replicate the cookbook structure making sure only to keep the template that needs to be modified. 
  3. Create a zip archive and upload it to a location which OpsWorks can access. In our case we used S3.
A cookbook with this updated template is available here [1].

Deploying to OpsWorks

  1. Enable custom cookbooks for your OpsWork Stack
  2. Provide the location of zip archive as the location of the custom cookbook
  3. Execute a Run Command for the Update Cookbook action
  4. Deploy the application

References
[1] https://github.com/splinter/angular2-deeplinks-opsworks-cookbook
[2] http://stackoverflow.com/questions/38991541/nginx-and-angular-2
[3] http://docs.aws.amazon.com/opsworks/latest/userguide/workingcookbook-template-override.html
[4] http://docs.aws.amazon.com/opsworks/latest/userguide/cookbooks-101-opsworks-templates.html
[5] https://serverfault.com/questions/378581/nginx-config-reload-without-downtime
[6] http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
[7] https://github.com/aws/opsworks-cookbooks/tree/release-chef-11.10/nginx
[8] https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.10/nginx/templates/default/site.erb