Serverless framework with Azure Functions

Recently an update to Azure Functions has been published containing proxies and integration with Serverless framework. In a nutshell it's a tool for building serverless architectures. Don't get the name fool you - in fact there's a server behind the whole functionality and still all principals regarding web development are true. What in reality it gives you is focusing only on the very functionality of your application. There're no pipelines, layers or areas - you're going to ensure that each component follows the single responsibility pattern and can be deployed separately. 

We're going to build a very simple application using Azure Functions and Serverless to present the current capabilities of the integration.

Provisioning you environment

I decided, that the easiest solution here is to obtain a pre-configured Ubuntu VM with installed NodeJS - you can easiliy get it from the marketplace in the portal. Once you have it, connect to it(as usual in my case, from Windows PuTTY seems like the best idea) and we can start. Type in following commands:

sudo npm install -g serverless
serverless install --url --name ServerlessExample

Those two will:

  • install Serverless globally
  • install a new service locally using name ServerlessExample

Once it's finished, you can go to the ServerlessExample directory - you'll see some files which are the core of our application. In fact, this boilerplate gives us all we need to get started as the example is fully functional.

Deploying a function

Before you're able to deploy your function to Azure you have to provide a credentials for deployment. The whole process is pretty well described here, however I attaching it here with my comments because in my case it didn't go as flawlessly as I thought:

bitnami@nodejsblog:~$ sudo npm i -g azure-cli
bitnami@nodejsblog:~$ azure login
bitnami@nodejsblog:~$ azure account show
bitnami@nodejsblog:~$ azure login
bitnami@nodejsblog:~$ azure ad app create -n service_name --home-page --identifier-uris -p pass
bitnami@nodejsblog:~$ azure ad sp create -a application_id
bitnami@nodejsblog:~$ azure role assignment create --objectId object_id  -o Contributor
bitnami@nodejsblog:~$ export azureSubId='<subscriptionId>'
bitnami@nodejsblog:~$ export azureServicePrincipalTenantId='<tenantId>'
bitnami@nodejsblog:~$ export azureServicePrincipalClientId='<servicePrincipalName>'
bitnami@nodejsblog:~$ export azureServicePrincipalPassword='<password>'

Note that I used azure ad app create command additionally - in my case it was not possible to simply create a service principal using only a name and a password.

You can ensure that you've added environment variables using printenv command. Once you configured your credentials, go to the directory of your service and just run:

serverless deploy

You should see following output:

Serverless: Packaging service...
Serverless: Logging in to Azure
Serverless: Creating resource group: ServerlessExampleKamz-rg
Serverless: Creating function app: ServerlessExampleKamz
Serverless: Waiting for Kudu endpoint...
Serverless: Parsing Azure Functions Bindings.json...
Serverless: Building binding for function: httpjs event: httpTrigger
Serverless: Packaging function: httpjs
Serverless: Building binding for function: queuejs event: queueTrigger
Serverless: Building binding for function: queuejs event: blob
Serverless: Packaging function: queuejs
Serverless: Syncing Triggers....Response statuscode: 200
Serverless: Running Kudu command del package.json...
Serverless: Running Kudu command npm install --production...
Serverless: Successfully created Function App

Now when you go to the portal, you'll see a new resource group created and function deployed.

In the next post we'll try to do more advanced configuration and consider involving VSTS and incorporating the framework into our build/release pipeline.

EventStore on Azure and Ubuntu - it's a piece of cake! #3

In the last but one post of this series we'll try to run a simple cluster of 3 nodes running EventStore instances. What is worth noting here is the fact, that there're three ways to organize and configure instances, so they work with each other:

  • running them on the same machine
  • running them on separate machines using IPs
  • running them on separate machines using DNS

Because the first one is almost self-describing(you have to start three instances on different ports), we'll omit it here and focus on the more complicated examples.

Running on separate machines

We'll start with creating 2 additional machines for our purposes. Just create two additional VM instances in the resource group you're using just like in the very first post of this series and we're good to go. Make sure that you're creating them in the same virtual network, which was created for the first virtual machine.

Once VMs are created, log in to each one and install EventStore instances as described in the previous posts.

Now we have to configure our instances so they're aware of other nodes. Basically what you have to do here is to change configuration on each node so it knows cluster size and other communication partners. Your eventstore.conf file could look like this:

RunProjections: None
ClusterSize: 3
DiscoverViaDns: False

The important thing here is the GossipSeed property, which points to other cluster nodes. I'm using here private IPs so my instances are still secured inside the network. The important thing here is that ES uses internal HTTP port for gossiping so make sure you're using the right value - if anything's wrong, election service won't be able to other machines and you'll see DEAD as other nodes status.

Configure all three nodes with proper gossip seeds and IPs by modifying each one's configuration file. Once you're done, go to the web panel of ES and sign in as admin.

Checking cluster status

If you sign in to the web panel, you'll see Cluster status menu item:

It will show all nodes attached, current state(which one is a master) and many, many more. I strongly recommend you to play a bit with it.

We've managed to create a cluster of 3 different machines running EventStore using VMs from Azure. In the last part of this series we'll try to use DNS instead to ease configuration a bit if anything changes.