February 10, 2019

Learning BOSH: Links

Welcome to my Learning BOSH diary:

In this post we will link the two releases we use in our deployment so that we can configure Nginx to load balance requests to the web application instances instead of replying with hardcoded response.

Follow the steps here in order to recreate what we have done (in case you took down your environment).

Links are a way to provide an information from a release to other releases in the same (or even other) deployment. A good explanation can be found in this gist by Amit Gupta (discussion bellow it is also worth reading).

OK, so we need to update akoranga-go-boshrelease to provide a link exposing the IP addresses of its instances and make akoranga-nginx-boshrelease consume this link when generating the nginx.conf configuration file.

In order to provide links from akoranga-go-boshrelease for other releases to use we need to update its spec file like this:

diff --git a/jobs/app/spec b/jobs/app/spec
index 7a8db95..b1b2817 100644
--- a/jobs/app/spec
+++ b/jobs/app/spec
@@ -7,4 +7,7 @@ templates:
 - akoranga-go
+- name: ingress
+  type: http
 properties: {}

What we have done here is to declare that the app job from this release provides a link named ingress of type http. You can find the commit here.

Now lets update the spec file for akoranga-nginx-boshrelease and declare the link it needs to consume:

diff --git a/jobs/nginx/spec b/jobs/nginx/spec
index 671f4cb..f5b9a10 100644
--- a/jobs/nginx/spec
+++ b/jobs/nginx/spec
@@ -8,4 +8,9 @@ templates:
 - nginx-1.14
+- name: backend_servers
+  type: http
 properties: {}

As you may notice names does not have to match and that could be a bit confusing, especially if there are multiple releases involved that all provide and consume links. Amit Gupta tries to de-mistify this here and there are also the docs on how to avoid link conflicts.

Now when we have the link defined we need to make some use of it. First lets update that nginx.conf template and convert it to erb template by renaming it to nginx.conf.erb and updating its declaration in teh spec file:

   ctl.erb: bin/ctl
-  nginx.conf: conf/nginx.conf
+  nginx.conf.erb: conf/nginx.conf

and the use the provided link to configure the load balancing:

upstream backend {
<%- link("backend_servers").instances.each do |instance| -%>
  server <%= instance.address -%>:8080;
<%- end -%>

server {
  listen 80;
  access_log /var/vcap/sys/log/nginx/access.log;
  location / {
    proxy_pass http://backend;

Besides the address the link and instance objects provide few other properties, more on this you can read here. The relevant commit is this one.

Update the deployment

Lets create and deploy a new updated version for each of our two releases (bosh create-release --force and bosh upload-release) and update the deployment by running

$ bosh -d akoranga deploy akoranga-deployment.yml

Now we should have a set of three instances looking like this:

$ bosh instances
Using environment '' as user 'admin' (openid, bosh.admin)

Task 15. Done

Deployment 'akoranga'

Instance                                             Process State  AZ  IPs  
akoranga-app/0b68d9c4-ab21-4ea2-98cd-636774289e59    running        z2  
akoranga-app/36730ac0-a52e-4b8f-9280-ae986b3544b6    running        z1  
akoranga-nginx/7f15ccfc-9659-435e-8898-e36f703837bb  running        z1  

3 instances

Let send a request to the instance running Nginx.

$ curl -i
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Sun, 10 Feb 2019 02:17:41 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 48
Connection: keep-alive

[73a6ff0b-b7b6-42e4-b441-248b2f1fdf51] Kia ora!

Nice! We can see that the response is comming from one of our akoranga-app instances and if we keep sending requests we should see that the hostname in the response will change depending on which instance received that request from Nginx.

That’s all for now, let me know if you have any comments or questions @qrasio.

Powered by Hugo & Kiss.