<commit_before>---
title: Links
---

<p class="note">Note: This feature is available with bosh-release v255.5+.</p>

Previously, if network communication was required between jobs, release authors had to add job properties to accept other job's network addresses (e.g. a "db_ips" property). Operators then had to explicitly assign static IPs or DNS names for each instance group and fill out network address properties. Such configuration typically relied on some helper tool like spiff or careful manual configuration. It also led to inconsistent network configuration as different jobs named their properties differently. All of that did not make it easy to automate and operate multiple environments.

Links provide a solution to the above problem by making the Director responsible for the IP management. Release authors get a consistent way of retrieving networking (and topology) configuration, and operators have a way to consistently connect components.

---
## <a id="definition"></a> Release Definitions

Instead of defining properties for every instance group, a job can declare links. (The job either 'consumes' a link provided by another job, or it can 'provide' itself so that any jobs, [including itself](#self) can 'consume' it).

In the below yaml snippet the `name` field is used to differentiate between two links of the same `type` (`db`). Both the `name` and `type` that are provided can be arbitrarily defined by release authors. Other releases which consume these links must match the `type` specified.

For example, here is how a "web" job which receives HTTP traffic and talks to at least one database server may be defined. To connect to a database, it consumes `primary_db` and `secondary_db` links of type `db`. It also exposes an "incoming" link of type `http` so that other services can connect to it.

Note that when the `web` job is 'consuming' db links, the name of the link does not have to match the name of the provided db link (i.e. postgres has a link called `conn` while the web job consumes `primary_db` and/or `secondary_db`). The mapping between the provided link named `conn` and the consumed link named `primary_db` is done in the [deployment manifest file](#deployment).

```yaml
name: web

templates: {...}

consumes:<commit_msg>Add an overview section on BOSH links.<commit_after>---
title: Links
---

<p class="note">Note: This feature is available with bosh-release v255.5+.</p>

Previously, if network communication was required between jobs, release authors had to add job properties to accept other job's network addresses (e.g. a "db_ips" property). Operators then had to explicitly assign static IPs or DNS names for each instance group and fill out network address properties. Such configuration typically relied on some helper tool like spiff or careful manual configuration. It also led to inconsistent network configuration as different jobs named their properties differently. All of that did not make it easy to automate and operate multiple environments.

Links provide a solution to the above problem by making the Director responsible for the IP management. Release authors get a consistent way of retrieving networking (and topology) configuration, and operators have a way to consistently connect components.

---
## <a id="overview"></a> Overview
First, we provide an overview of the capabilities and logistics of links through a simple example. Here, we have two jobs: an application job and a database job. The database provides its connection information through a link, which the application consumes.

In the database job's spec file, it declares that it provides the connection information:

```yaml
# Database job spec file.
name: database_job
# ...
provides:
- name: database_conn
  type: conn
  # Links always carry certain information, like its address and AZ.
  # Optionally, the provider can specify other properties in the link.
  properties:
  - port
  - adapter
  - username
  - password
  - name
properties:
- name: port
# ...
```

Likewise, the application job's spec file declares that it consumes connection information:

```yaml
# Application job spec file.
name: application_job
# ...
consumes:
- name: database_conn
  type: conn
```

Then, in the application job's templates, it can use the connection information from the link:

```sh
#!/bin/bash
# Application's templated control script.
# ...
export DATABASE_HOST="<%= link('db_conn').address %>"
export DATABASE_PORT="<%= link('db_conn').p('port') %>"
# ...
```

If the application uses two database connections, each provided by a separate database_job instance, the link becomes ambiguous and we must resolve the ambiguity in the deployment manifest. In this case, the application job's spec file could look like:

```yaml
# Application job spec file.
name: application_job_two_db
# ...
consumes:
- name: frontend_database
  type: conn
- name: backend_database
  type: conn
```

And then in the deployment manifest, we disambuate the links with `provides` and `consumes` declarations on the jobs. The database jobs name their `database_conn` links. The application job uses these names to specify which database it will use for each of its links.

```yaml
# ...
instance_groups:
- name: database_1
  jobs:
  - name: database_job_1
    templates:
    - name: database_job
      release: ...
    provides:
      database_conn: {as: db1}
- name: database_2
    templates:
    - name: database_job
      release: ...
  jobs:
  - name: database_job_2
    provides:
      database_conn: {as: db2}
- name: application_ig
  jobs:
  - name: application_job_two_db
    consumes:
      frontend_database: {from: db1}
      backend_database: {from: db2}
# ...

---
## <a id="definition"></a> Release Definitions

Instead of defining properties for every instance group, a job can declare links. (The job either 'consumes' a link provided by another job, or it can 'provide' itself so that any jobs, [including itself](#self) can 'consume' it).

In the below yaml snippet the `name` field is used to differentiate between two links of the same `type` (`db`). Both the `name` and `type` that are provided can be arbitrarily defined by release authors. Other releases which consume these links must match the `type` specified.

For example, here is how a "web" job which receives HTTP traffic and talks to at least one database server may be defined. To connect to a database, it consumes `primary_db` and `secondary_db` links of type `db`. It also exposes an "incoming" link of type `http` so that other services can connect to it.

Note that when the `web` job is 'consuming' db links, the name of the link does not have to match the name of the provided db link (i.e. postgres has a link called `conn` while the web job consumes `primary_db` and/or `secondary_db`). The mapping between the provided link named `conn` and the consumed link named `primary_db` is done in the [deployment manifest file](#deployment).

```yaml
name: web

templates: {...}

consumes:
{'fraction_non_alphanumeric': 0.0745030745030745, 'fraction_numerical': 0.002288002288002288, 'mean_word_length': 4.2745098039215685, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7345408', 'n_tokens_mistral': 1821, 'n_tokens_neox': 1749, 'n_words': 987}