# GitOps

Bindplane's API allows developers to manage configuration state with GitOps.

This guide will showcase how to use Github actions for automating the deployment of resources to Bindplane.

### Prerequisites

The following prerequisites must be satisfied before Bindplane can be automated.

#### Bindplane Authentication

You must have access to your Bindplane Server using an API key (when multi-project is enabled) or username and password (when single-project is enabled).

#### Bindplane CLI

You must have the ability to run CLI commands against your Bindplane server from your workstation.

You can create a quick CLI profile with the following commands (where `gitflow` is the name of the profile):

```bash
bindplane profile set "gitflow" --remote-url http://<host>:3001 --api-key <api key>
bindplane profile list
bindplane profile use "gitflow"
bindplane get agents
```

If you are using a username and password, replace the `--api-key` flag with the `--username` and`--password` flags.

See the [CLI](https://docs.bindplane.com/how-to-guides/broken-reference) documentation for more information.

#### Network Access

Bindplane must be reachable by the CI/CD "runner". If your Bindplane server is hidden behind a corporate firewall, you can look into using [Self-hosted Runners](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners).

Most installations of Bindplane will be listening on port `3001` unless configured otherwise or placed\
behind a load balancer.

#### Repository

You must have a new or existing repository that you can use while following this guide. This repository will be used to store Bindplane resource files as well as rendered OpenTelemetry "raw" configuration files.

### Github Actions

#### Repository Secrets

The following [repository secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) must be defined in your repository.

* `BINDPLANE_REMOTE_URL`: The remote URL of your Bindplane server, usually in the form of `http://<hostname>:3001`.
* `BINDPLANE_API_KEY`: API key if you do not want to use a username and password

Bindplane supports username and password, however, an API key is required when multi-project\
is enabled. If Bindplane is not configured for multi-project, you must have the following\
secrets for your basic authentication username and password.

* `BINDPLANE_USERNAME`
* `BINDPLANE_PASSWORD`

#### Export Existing Resources

Existing resources should be exported to your repository before enabling the Github Action.

```bash
bindplane get destination -o yaml --export > destinations.yaml
bindplane get configuration -o yaml --export > configurations.yaml
```

This will output all existing destinations to `destinations.yaml` and configurations\
to `configurations.yaml`. You can move these files to any directory within your repository.\
Make a note of where they live, as their paths will be required when configuring the GitHub Action.

**Sensitive Values**

Destinations and configurations that have sensitive values (passwords, tokens, API keys) will not\
export the actual value. Instead, the value will be a placeholder "(sensitive)". Bindplane\
will never allow you to retrieve a sensitive value.

Bindplane destination resource example:

```yaml
apiVersion: bindplane.observiq.com/v1
kind: Destination
metadata:
  id: google
  name: google
spec:
  type: googlecloud
  parameters:
    - name: project
      value: my-project
    - name: auth_type
      value: json
    - name: credentials
      value: (sensitive)
      sensitive: true
```

Raw OTEL configuration example:

```yaml
exporters:
  googlecloud/google:
    credentials: (sensitive)
```

When the configuration is pushed to the collector, the correct value will be included in the configuration.

#### Github Action Workflow

Create a new workflow at `.github/workflows/bindplane.yml`. Open the [observIQ/bindplane-op-action](https://github.com/observIQ/bindplane-op-action) repository to view the full list of configurable parameters.

```yaml
name: bindplane

on:
  push:
    branches:
      - main

# Required for writing back otel configs to the repo.
permissions:
  contents: write

# Prevents concurrent and potentially out of order
# resource updates.
concurrency:
  group: ${{ github.head_ref || github.ref_name }}
  cancel-in-progress: false

jobs:
  bindplane:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: observIQ/bindplane-op-action@v1.0.0
        with:
          bindplane_remote_url: ${{ secrets.BINDPLANE_REMOTE_URL }}
          bindplane_api_key: ${{ secrets.BINDPLANE_API_KEY }}
          target_branch: main
          destination_path: destinations.yaml
          configuration_path: configurations.yaml
          enable_otel_config_write_back: true
          configuration_output_dir: otel/
          token: ${{ secrets.GITHUB_TOKEN }}
```

If using username and password, replace the `bindplane_api_key` option with:

```yaml
bindplane_username: ${{ secrets.BINDPLANE_USERNAME }}
bindplane_password: ${{ secrets.BINDPLANE_PASSWORD }}
```

Update `target_branch: main` to point to the branch you wish to use as your source of truth. When\
the action is running against this branch, it will apply resources to Bindplane.

Make sure `destination_path` and `configuration_path` point to the relative path of the\
previously exported destination and configuration resource files.

If you do not wish to write back the raw OpenTelemetry configuration files to the repo, set`enable_otel_config_write_back` to `false`.

#### Commit and Test

Commit the destination resource, configuration resource, and actions workflow YAML files to the repository. If committing to a branch other than the `target_branch`, make sure to open a pull request to merge these changes to the target branch.

Once the target branch has the Bindplane resources and the actions workflow,\
you should see the action running under the repository's "Actions" tab.

Because the existing resources are up to date with the repository's resources, the results will\
be uneventful. The actions will pass without taking action. If `enable_otel_config_write_back` is\
set to `true`, the action will have committed the raw OpenTelemetry configuration back to the repo.

You can test changes by editing one of the resources in the repository (`destinations.yaml` or `configurations.yaml`). Save and commit the change to the target branch either directly or by using your pull request workflow.

Once the change is merged into the target branch, the following will happen:

1. The action will apply the resources to Bindplane
2. All affected Bindplane configurations will have a pending rollout
3. The updated raw OpenTelemetry configurations will be committed back to the repo if `enable_otel_config_write_back` is `true`

Configurations that have a pending rollout can be triggered by Bindplane Web Interface users.

### Automatic Rollout

The action can be configured to trigger rollouts automatically after updating a configuration.

{% hint style="danger" %}
**WARNING**

When automatic rollouts are enabled, configuration changes made by the action will immediately apply to collectors that are attached to that configuration.
{% endhint %}

Set `enable_auto_rollout` to `true`.

```yaml
- uses: observIQ/bindplane-op-action@v1.0.0
  with:
    bindplane_remote_url: ${{ secrets.BINDPLANE_REMOTE_URL }}
    bindplane_api_key: ${{ secrets.BINDPLANE_API_KEY }}
    target_branch: main
    destination_path: destinations.yaml
    configuration_path: configurations.yaml
    enable_otel_config_write_back: true
    configuration_output_dir: otel/
    token: ${{ secrets.GITHUB_TOKEN }}
    enable_auto_rollout: true
```

### Updating Resources

Resources can be updated using two methods. You can edit the resources (destination and configuration YAML files) files directly or you can edit resources in the Bindplane UI and export them using the CLI, similar to the original export covered at the beginning of this guide.

#### Direct Edit

Direct edits can be done by editing the configuration files that the action is pointing to.

```yaml
destination_path: destinations.yaml
configuration_path: configurations.yaml
```

In this example, the `otlp_grpc` destination's `grpc_port` is updated from `4317` to `44317`.

```yaml
---
apiVersion: bindplane.observiq.com/v1
kind: Destination
metadata:
  id: bindplane-gateway-agent
  name: bindplane-gateway-agent
spec:
  type: otlp_grpc
  parameters:
    - name: grpc_port
      value: 44317
```

You can use `git diff` to view your changes.

```
--- destinations.yaml
+++ destinations.yaml
@@ -10,7 +10,7 @@ spec:
         - name: grpc_port
-          value: 4317
+          value: 44317
```

With the changes in place, commit the change directly to the target branch (branch the action is deploying changes from) or go through your normal pull request and review workflow with your team.

Once the change is merged or committed to the target branch, the action will deploy the change to Bindplane.

If [Auto Rollout](#automatic-rollout) is not enabled, you will need to log into Bindplane's web interface and trigger the rollout manually.

#### UI Export

As an alternative to editing the resource files directly, you can modify configurations in the web interface and re-export them to your repository.

1. Edit the configuration within the Bindplane web interface.
2. Do **NOT** roll the configuration out.
3. Re-run the CLI export commands in the [Export Existing Resources](#export-existing-resources) section.
4. Verify the changes with `git diff`
5. Commit the changes to the target branch, or follow a pull request workflow to merge the changes to the target branch.

Once the change is merged or committed to the target branch, the action will deploy the change\
to Bindplane.

If [Auto Rollout](#automatic-rollout) is not enabled, you will need to log into Bindplane's web interface and trigger the rollout manually.

#### Updating Sensitive Values

At this time, sensitive values must be updated by following the [UI Export](#ui-export) workflow. It is important to avoid storing sensitive values in the Git repository.

### Role Based Access Control

When using the action with [Auto Rollout](#automatic-rollout) enabled, it is recommended to restrict your Web Interface user's access by using RBAC.

You can allow users to make configuration changes and prevent them from rolling the configuration\
out by setting their permission level to `user`. See the [Rollout Permissions](https://docs.bindplane.com/how-to-guides/broken-reference) guide for more information.

{% hint style="info" %}
**NOTE**

The action's username or API key should be associated with an admin user to allow it to trigger rollouts.
{% endhint %}
