Capabilities

Capabilities are third-party dependencies of your applications. By defining capabilities, you explicitly define what services in your application can depend on in each release channel, allowing services to be created without knowledge of which third-party dependency to connect to.

Defining Capabilities

Capabilities are defined as a collection of env variables, as part of the application itself via pvnctl applications create or pvnctl applications edit.

# in text editor started from `pvnctl applications create/edit`
capabilities:
- name: user-db
  perReleaseChannel:
  - releaseChannel: staging
    inlined:
      env:
        MY_DB_URL:
          value: <my-user-db-staging>
        MY_DB_PASS:
          raw_secret: <my-db-staging-pass>  # this will be stored securely in an encrypted state

There must be a definition for each release channel of your application, and the env variable names need to be consistent across all release channels.

Using Capabilities

Once defined, capabilities can be used when configuring services. Adding a capability to your service will automatically inject the env variables for the capability to the corresponding release channels, and your application code can use these variables to connect to the actual third-party systems.

31883188

Coordinating Pushes

Sometimes, service pushes need to be coordinated with capabilities the service depends on. For example, you may have a convention that database migrations must be run before services can be pushed with any revision. Capabilities allow you to codify this relationship by automatically injecting steps before a push to each release channel.

capabilities:
- name: user-db
  perReleaseChannel:
  - releaseChannel: staging
    inlined:
      env: ...
      prePushTasks:
      - customTask:
          description: 'Check for unapplied migrations on staging user-db'
          program:
            image: <docker image>
            cmd: <command to run to check if migrations have run>
          retryConfig:
            firstFailureNotification:
              message: Blocked on unapplied migrations
            retryForever: true

The config above will add a step before pushes to staging for any services that rely on user-db, running the specified image and command and retrying until it succeeds. The custom task will run in the same release channel as the capability definition (staging in this case) and will automatically have env variables for that capability injected. The task schema for prePushTasks are the same as what is used for custom pipelines and custom tasks.

31843184

Reusing definitions

Sometimes, different release channels share the same capability definition. For example, your application may consist of staging, beta, and prod release channels where beta and prod connect to the same database. You can avoid duplicating capability definitions via a reference.

capabilities:
- name: user-db
  perReleaseChannel:
  - releaseChannel: staging
    inlined:
      env: ...
  - releaseChannel: beta
    ref:
      name: user-db-prod
  - releaseChannel: prod
    ref:
      name: user-db-prod
capabilityInstances:
- name: user-db-prod
  env: ...