Bind Services to OpenWhisk Packages

When working with serverless actions, often we'll still need to access some sort of service, whether it's object storage, a database, or whatever. Here's a quick overview of how this works for IBM Cloud Functions (plus some gotchas ....)

For this example, I'll be connecting my NodeJS example code to a PostgreSQL database on IBM Cloud, but other combinations of languages and services work along very similar lines. To make everything super clear, we'll create all the elements from scratch: first the database and some access credentials for it:

bx service create compose-for-postgresql Standard my-database
bx service key-create my-database key1

At this point I have:
* one compose-for-postgres service
* named my-database
* with a key called key1

To make this available to my serverless actions, I want to give the IBM Cloud Functions package access to this database. I'll create the package my-pkg and bind the service we created above to the package:

bx wsk package create my-pkg
bx wsk service bind compose-for-postgresql my-pkg

With this in place, there will be an additional parameter available to the actions in this package called __bx_creds that holds the details of the bound service credentials.

For example, in my NodeJS action:

const pgp = require('pg-promise')();
var db;

function main(params) {
    var postgres_url = params['__bx_creds']['compose-for-postgresql']['uri'];
    return new Promise(function(resolve, reject) {
        db = pgp(postgres_url, []);
        ...

If you have multiple databases of the same type in your space, then I recommend specifying which of the particular service type to use. For me the command would look like this:

bx wsk service bind compose-for-postgresql --instance my-database my-pkg

There's also a switch for which key to use if you have multiple keys: this is the --keyname argument.

With these features available, I can simply create services and bind them to the packages that my actions will be in. My code can access these actions and there is no need for the credentials to be available anywhere else - which is ideal. In the past I was setting package parameters with these values in: now the services are bound and I can be confident about the source of the data in the __bx_creds parameter.

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.