Integration of External Services

Integration of External Services

The interaction of a cluster with a database instance hosted by a third-party service provider is a classic illustration of external service integration. Carbonio Mesh is used to deploy in circumstances like this one with Carbonio.

Situation & Conditions

In our example scenario, a Carbonio Multi-Server installation with the following components is used:

    • one or more Nodes for Carbonio Files
    • One cluster node, maybe distinct from the Carbonio Files Nodes, was chosen as the terminating gateway
    • Unrelated to the Carbonio infrastructure is a server

    • Remotely hosted by an outside service


We will refer to this node as database node in the remainder of this guide.


 The sample scenario used, with two Carbonio Files nodes and a database hosted remotely.

Terminating Gateway

In consul terminology, a terminating gateway is a cluster node that takes the responsibility to communicate with an external resource. All services running on the cluster that need to access this resource will contact the terminating gateway, which will forward the request and send back the output received by the resource. The services do not need to know anything about the resource: they just contact the terminating gateway and wait for the response.

Each terminating gateway is responsible for one service only, in case of multiple services need to access external resources, you need to spawn multiple instances of a terminating gateway.

Although certain instructions near the conclusion of the setup require access to the database node, for the most part, the configuration requires access to the command line on the terminating gateway because the process includes manual file editing and running commands.


It is highly suggest to use the Carbonio Mesh Administration Interface to better keep track of the configuration and changes. Please check Carbonio Mesh Administration Interface for directions on how to configure it and reach it.

Finally, remember your cluster credential password since token creation requires it.

Let’s begin the process by installing Carbonio Files after setting up Carbonio Mesh.

Setup and security

A few actions must be taken to finish the initial setup.


All commands must be executed on the node elected as terminating gateway, unless stated differently.

 1. Make a special user

# groupadd -r 'carbonio-gateway'
# useradd -r -M -g 'carbonio-gateway' -s /sbin/nologin 'carbonio-gateway'

 2. Establish policies. The Carbonio Files database, carbonio-files-db, is the service that has to  be routed in our case, hence Carbonio Mesh must be informed of this. Create a directory to house all of the configuration first.

# mkdir -p /etc/carbonio/gateway/service-discover/

After that, paste this text into the file  /etc/carbonio/gateway/service-discover/policies.json.

  "key_prefix": [
      "carbonio-gateway/": {
        "policy": "read"
  "node_prefix": [
      "": {
        "policy": "read"
  "service": [
      "carbonio-gateway": {
        "policy": "write"
      "carbonio-files-db": {
        "policy": "write"

Let the consul finally pick up the new policy.

# consul acl policy create -name "carbonio-gateway-policy" -description "Policy for carbonio-gateway" -rules  @/etc/carbonio/gateway/service-discover/policies.json

3. Export a fresh bootstrap token, which enables access to consul’s APIs and the ability to run commands. Run the following command and then provide the cluster credential password to retrieve the bootstrap token.

# export CONSUL_HTTP_TOKEN=$(service-discover bootstrap-token --setup)

4. Create a new token that will be the only one required to interface with the external database and is linked to the policy.

# consul acl token create -format json -policy-name carbonio-gateway-policy -description "Token for carbonio-gateway" | jq -r '.SecretID' > /etc/carbonio/gateway/service-discover/token

# chown carbonio-gateway:carbonio-gateway -R /etc/carbonio/gateway
What the External Service Means

We describe both the external service and how the terminating gateway may access it and grant Carbonio Files nodes access to it since the terminating gateway has to be aware of the precise location of the remote service in order to function properly.

Although there is currently no CLI command for this, we can use the APIs instead. Make a file called  /etc/carbonio/gateway/service-discover/carbonio-files-db-external.json.

  "Address": "",
  "Node": "external-files-db-node",
  "NodeMeta": {
    "external-node": "true",
    "external-probe": "true"
  "Service": {
    "ID": "carbonio-gateway",
    "Port": 5432,
    "Service": "carbonio-files-db"

the external service should then be registered by sending a curl request.

Services Scheduling

It is time to inform Carbonio Mesh of the list of services that can utilise the terminating gateway now that the terminating gateway and the service have been defined and registered.

Put the following code, which designates a carbonio-gateway as a terminating gateway for the carbonio-files-db service, in the file /etc/carbonio/gateway/service-discover/gateway-config.hcl to do this.

The file mentioned above has two items that are commented; these entries are optional and need not be supplied at all in the setup.


an SSL certificate that is particular to the service. In most cases, unless a highly specific and complicated situation is set up, this is not essential. Consul is responsible for encrypting all communication between nodes and with external resources; since services and clients communicate with it through localhost, it is secure for them to do so. Before leaving the node, all data received from consul on localhost are instantly SSL-encrypted.


In order to avoid name mismatch, the Server Name Indication is an extra security measure on top of TLS. When a client request is received, the web server might not yet know which specific domain the client is trying to access because the HTTPS TSL/SSL handshake takes place before the client sends the actual HTTP request for the domain in the typical scenario where a single web server hosts multiple domains, each with its own SSL certificate. The client can end up receiving the incorrect certificate as a result, breaking the secure connection. This issue may be avoided by using an SNI since it enables the domain name to be sent during the SSL/TSL handshake.

Make sure to write the configuration, by issuing the following command.

# consul config write /etc/carbonio/gateway/service-discover/gateway-config.hcl

At this point, we are almost done: configuration of Carbonio Mesh has now been completed. Let’s now go through the last few tasks.
Systemd Service

Now, create a systemd unit to control whether the carbonio gateway is enabled or not and therefore whether access to the external DB is allowed. Create file /lib/systemd/system/carbonio-gateway.service and configure it with these content.

Description=Carbonio gateway for external services

ExecStart=/usr/bin/consul connect envoy \
    -token-file /etc/carbonio/gateway/service-discover/token \
    -admin-bind localhost:0 \
    -gateway=terminating \
    -register -service carbonio-gateway



You can modify the ExecStart option by adding -- -l debug at the end to produce more verbose logs. The option should then look like:

ExecStart=/usr/bin/consul connect envoy \
  -token-file /etc/carbonio/gateway/service-discover/token \
  -admin-bind localhost:0 \
  -gateway=terminating \
  -register -service carbonio-gateway -- -l debug

Once the file has been saved, restart systemd to inform it of the updated unit file before enabling the new carbonio-gateway service.
Setting up the carbonio-files-db


This step only applies when the external resource is a database, like in our scenario.

The  carbonio-files-db-bootstrap  script typically handles the configuration of the database, which involves sending the DB credentials to Carbonio Mesh and creating the DBs. However, this action must be carried out manually using these commands on the terminating gateway because the carbonio-files-db package is not installed.
  • configure database name

    # consul kv put carbonio-files/db-name <database-name>

  • configure username

    # consul kv put carbonio-files/db-username <username>

  • configure password

    # consul kv put carbonio-files/db-password <password>
Let’s now log in to the database node, where a postgres superuser has to be created. In this illustration, we give the user the password ScrtPsw9872. Use a strong password of your choosing, and be sure to.
To access the database directly, first log in as the postgres user and launch the CLI client.
# sudo -u postgres psql
Then run the scripts below to create the user.
# CREATE ROLE "carbonio-files-adm" WITH LOGIN SUPERUSER encrypted password 'ScrtPsw987^2'; CREATE DATABASE "carbonio-files-adm" owner "carbonio-files-adm";
Exit the client after finishing.
# \q
Installing Carbonio Files Nodes
In a Multi-Server, the installation of Carbonio Files is slightly different from the typical one. Make sure in particular that no nodes have the package carbonio-files-db installed after installation. In fact, in our circumstance, the external service instead of that package provides the database functions. Therefore, you must remove it in order to prevent conflicts.
  • On each Proxy Node, install the carbonio-files-ui package.

The final message of the installation will be:

Carbonio Files installed successfully!
You must run pending-setups to configure it correctly.

hence, carry out  pending-setups

# pending-setups -a
Take Services Out of the Catalogue
It is simple to delete the configuration of the services when the external resource is no longer required, such as when the database is moved within the company’s data centre.
  • Delete the configuration file and stop the systemd unit service
    # systemd stop carbonio-gateway
    # systemd disable carbonio-gateway
    # rm /lib/systemd/system/carbonio-gateway.service
  • Remove the gateway settings.
    # consul config delete -kind terminating-gateway -name carbonio-gateway
    # curl --request PUT --header "X-Consul-Token: ${CONSUL_HTTP_TOKEN}" http://localhost:8500/v1/agent/service/deregister/carbonio-gateway
    # curl --request PUT --header "X-Consul-Token: ${CONSUL_HTTP_TOKEN}" http://localhost:8500/v1/agent/service/deregister/carbonio-files-db
The carbonio-files-db package may now be installed on any node, and the Carbonio Files nodes will have immediate access to it.