User Provided Service Instances: Use Them!
Join the DZone community and get the full member experience.
Join For FreeThere's a feature in Cloud Foundry v2 and Stackato 3 that a lot of people seem to miss. User-Provided Service Instances let you store service connection information and credentials using the same JSON-formatted environment variables that system-provided services create when you bind a service to an application.
In short, it's the simplest possible way to connect applications running on Stackato to *existing* data services. Enter the connection strings via the 'stackato' client, then bind the resulting service instance to your app.
A feature's a feature, no matter how small.
A lot of PaaS systems use environment variables to set configuration and attach applications to services. Storing config in the environment is the third factor in the Twelve-Factor App approach.
The database binding system has been in Cloud Foundry from the start, and thankfully, someone at Pivotal noticed some low-hanging fruit when planning and implementing Cloud Foundry v2.
With the service instance binding model already in place, it was relatively trivial to give users the ability to specify arbitrary key-value pairs from the CLI client and enable them to connect their applications. Stackato inherited this in version 3.0 with the move to the v2 code base.
How services are bound to apps
When you push an application to Stackato, you can request a data service for it. Here's an example in stackato.yml format:
name: cirrus mem: 256M instances: 2 services: cirrusdb: mysql - See more at:
Our application, called 'cirrus', requests 256M of application memory for each of two instances (Docker containers). It also requests a MySQL database, which Stackato will create. Stackato's user-facing name for this service instance is 'cirrusdb' but that's not the *actual* database name in MySQL. Depending on how the system service is implemented, the database name may need to be globally unique, so generally the connection information for a service instance like 'cirrusdb' might look something like this:
host: 192.168.68.18 name: dd8b072e1950844aa8af62911132898a5 password: pQaVO9oAd6dJR port: 3306 user: uIcTojXrnLWyE
$ echo $VCAP_SERVICES | json { "mysql": [ { "name": "cirrusdb", "label": "mysql-5.5", "tags": [], "plan": "free", "credentials": { "name": "dd8b072e1950844aa8af62911132898a5", "hostname": "192.168.68.18", "host": "192.168.68.18", "port": 3306, "user": "uZ3e0I7b3w578", "username": "uZ3e0I7b3w578", "password": "p0IOGF5wYA337", "uri": "mysql://uZ3e0I7b3w578:p0IOGF5wYA337@192.168.68.18:3306/dd8b072e1950844aa8af62911132898a5", "jdbcUrl": "jdbc:mysql://uZ3e0I7b3w578:p0IOGF5wYA337@192.168.68.18:3306/dd8b072e1950844aa8af62911132898a5" } } ] }
$ echo $STACKATO_SERVICES | json { "cirrusdb": { "name": "dd8b072e1950844aa8af62911132898a5", "hostname": "192.168.68.18", "host": "192.168.68.18", "port": 3306, "user": "uZ3e0I7b3w578", "username": "uZ3e0I7b3w578", "password": "p0IOGF5wYA337", "uri": "mysql://uZ3e0I7b3w578:p0IOGF5wYA337@192.168.68.18:3306/dd8b072e1950844aa8af62911132898a5", "jdbcUrl": "jdbc:mysql://uZ3e0I7b3w578:p0IOGF5wYA337@192.168.68.18:3306/dd8b072e1950844aa8af62911132898a5" } }
The application can parse one of these variables (or the even more succinct _URL variables) to connect itself to the database. Simple.
But how do I connect to the production DB?
All of the above works great if you're using Stackato to provision all databases all the time, but a lot of people already have data in existing production databases. Connecting applications hosted on Stackato to these systems used to (back in 2.x days) require manually specifying additional environment variables in the application containers and adding extra tests/parsing in the application code.
It worked, but it wasn't very elegant. It wasn't that much better than hard-coding connection strings, which we've been exhorting people to avoid.
Now there's a better way to store those connection strings.
Say we have a big, high-availability MySQL cluster on our network. Our production data is already there, and I've been given credentials to connect the appropriate database with a certain username and password. The Stackato admin has made sure the DEA nodes in our Stackato cluster can route to the host that is load-balancing the DB cluster.
I take the connection details I've been given and enter them as a user-provided service instance using the stackato client:
$ stackato create-service user-provided cirrusdb-prod-live Which credentials to use for connections [hostname, port, password]: hostname, port, name, user, password hostname: bigdb.int.example.com port: 3306 name: cirrusdb-prod user: cirrus-web-ro password: n63uYdetMH8qAkysoL Creating new service ... OK
$ stackato unbind-service cirrusdb cirrus Unbinding cirrusdb from cirrus ... ...
$ stackato bind-service cirrusdb-prod-live cirrus Binding cirrusdb-prod-live to cirrus ...
My application will pick up the connection details from VCAP_SERVICES or STACKATO_SERVICES and start using the live data.
Not just for databases.
Since you control the keys and the values saved in the service instance, you can use it to connect your application to *any* type of service that requires a connection string or credentials (e.g. an SMTP server, a REST interface, a message queue).
As long as your application has the libraries needed to connect to the service, and Stackato can route to the service endpoint (the host), you're good to go.
If you'd like to try Stackato for yourself, you can download the micro cloud for free or request access to the Stackato sandbox for a trial period.
Published at DZone with permission of Troy Topnik, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Top Six React Development Tools
-
Managing Data Residency, the Demo
-
Decoding eBPF Observability: How eBPF Transforms Observability as We Know It
-
Building the World's Most Resilient To-Do List Application With Node.js, K8s, and Distributed SQL
Comments