Plugin creation guide#
So you wanna build a BitOps plugin, eh? Follow along for how to do it locally!
1. Create a plugin repo#
cd /path/to/bitops-plugins mkdir sample-plugin && cd sample-plugin
More information on what goes in a plugin here.
Note: If the plugin needs to install tools, you will need to build and run a local version of BitOps. The first portion of this guide assumes the install.sh script DOES NOT needs to be run. For more information about how to set up BitOps for local development with a plugin that requires an installation, skip to step 5 below.
For this example, we'll keep to a really simple plugin.
To start with, create a file called
bitops.schema.yaml and add the following content.
# /path/to/bitops-plugins/bitops.schema.yaml sample-plugin: options: type: object properties: foo: type: string export_env: SAMPLE_PLUGIN_FOO required: true default: foo_value
Next, create a simple
deploy.sh script. This script does some checks and shows how to use some of the system
BITOPS_ available environment variables then outputs configuration values defined by the
# /path/to/bitops-plugins/deploy.sh #!/bin/bash set -e echo "Running Sample Plugin deployment script..." # vars export BITOPS_SCHEMA_ENV_FILE="$BITOPS_OPSREPO_ENVIRONMENT_DIR/ENV_FILE" if [ ! -d "$BITOPS_OPSREPO_ENVIRONMENT_DIR" ]; then echo "No sample-plugin directory. Skipping." exit 0 fi echo "Deploying sample-plugin..." if [ ! -f "$BITOPS_SCHEMA_ENV_FILE" ]; then echo "No sample-plugin ENV file found" else source "$BITOPS_SCHEMA_ENV_FILE" fi cd $BITOPS_OPSREPO_ENVIRONMENT_DIR echo "Listing contents of sample-plugin Root: $BITOPS_OPSREPO_ENVIRONMENT_DIR" ls -al . echo "Running the plugin CLI: (SKIPPED)" echo "Options:" echo "SAMPLE_PLUGIN_FOO: $SAMPLE_PLUGIN_FOO" # Expected result: "foo_value"
Note: Much of the above is best practice boilerplate and is not strictly necessary.
Finally, create a
plugin.config.yaml to configure how BitOps uses the plugin:
# /path/to/bitops-plugins/plugin.config.yaml plugin: deployment: language: bash deployment_script: deploy.sh
2. Create an ops repo for testing#
Now we'll create an
environment with a directory that matches your tool:
- In this example, we have an
sample-ops-repodir as the root.
test-envis our new environment that we want to test the plugin on.
- Finally we have a directory for the
mkdir -p /path/to/sample-ops-repo/test-env/sample-plugin cd /path/to/sample-ops-repo/test-env/sample-plugin
Populate the tool's
bitops.config.yaml based on the schema defined above:
# /path/to/sample-ops-repo/test-env/sample-plugin/bitops.config.yaml sample-plugin: options: foo: baz
3. Test your plugin#
3.1. BitOps-level BitOps Config#
To test your plugin, you'll need BitOps to run with a
bitops.config.yaml that has your plugin defined in the
bitops.config.yaml at the
test-env level in your
sample-ops-repo, and add a
deployments reference to your plugin:
- Note the
file:///opt/...path in the example. This is the path that will result when the plugin is installed into the BitOps Docker container running it - NOT the path on your local machine.
# /path/to/sample-ops-repo/test-env/sample-plugin/bitops.config.yaml bitops: plugins: sample-plugin: file:///opt/bitops/scripts/installed_plugins/sample-plugin deployments: sample-plugin: plugin: sample-plugin
3.2. Run your test#
To run BitOps against a local plugin, you'll need to mount the plugin to the location BitOps expects plugins to be:
- Create a
_scriptsfolder at the root level of your
- Create a
deploy.local.shfile to script the upcoming
Make sure to
chmod +xthe deploy script.
# in /path/to/sample-ops-repo mkdir _scripts && cd _scripts touch deploy.local.sh chmod +x deploy.local.sh
.gitignoreto keep the deploy file out of the upstream repo:
# in /path/to/sample-ops-repo echo _scripts/deploy.local.sh >> .gitignore
Note: To see the full code so far, see docs/examples/plugin-examples/plugin-no-install/duplicate-environment -->
Copy this content into
#!/bin/bash docker run --rm --name bitops \ -e BITOPS_ENVIRONMENT="test-env" \ -v /path/to/sample-ops-repo:/opt/bitops_deployment \ -v /path/to/bitops-plugins/sample-plugin:/opt/bitops/scripts/installed_plugins/sample-plugin \ bitovi/bitops:latest
Note the docker-context name of the plugin dir
/path/to/bitops-plugins/sample-plugin:/opt/bitops/scripts/installed_plugins/***sample-plugin***must exactly match the name in
# in /path/to/sample-ops-repo/_scripts ./deploy.local.sh
If things go well, the output should look like this:
> ./deploy.local.sh 2023-05-15 18:37:12,675 bitops-logger WARNING Optional file was not found. Consider adding the following file: [/opt/bitops/scripts/installed_plugins/azure/plugin.config.yaml] Running Azure Plugin deployment script... Deploying azure plugin... No azure plugin ENV file found Listing contents of azure plugin Root: /tmp/tmpj5lv41jw/test-env/azure total 12 drwxr-xr-x 2 root root 4096 May 15 16:19 . drwxr-xr-x 3 root root 4096 May 15 18:11 .. -rw-r--r-- 1 root root 31 May 15 18:36 bitops.config.yaml Running the plugin CLI: (SKIPPED) Options: AZURE_FOO: foo_value BitOps has finished!
4. Handling the Plugin Install Script#
If your new plugin needs to run some install scripts (e.g. to install a CLI tool), you'll need to build your own version of BitOps locally.
Note: For more information on how to do this, see plugins.
4.1 Update the Plugin to Add an Install Script#
install configuration to your plugin's
plugin: # this plugin has install instructions install: language: bash install_script: install.sh deployment: language: bash deployment_script: deploy.sh
Create your install script:
# /path/to/bitops-plugins/install.sh #!/bin/bash set -e echo "In the install script for the sample-plugin" apk update && apk upgrade # add your actual installers here
4.2. Build a BitOps image#
Create a new directory to hold your custom BitOps config.
In this case we're putting it in our
bitops-plugins parent dir, but you could put it anywhere.
IMAGE_PATH=/path/to/bitops-plugins/bitops-images/sample-plugin-image mkdir -p $IMAGE_PATH && cd $IMAGE_PATH
4.2.1 Add the BitOps config#
First, add your BitOps level
bitops.config.yaml and include a reference to your local file dependency via the
# /path/to/bitops-plugins/bitops-images/sample-plugin-image/bitops.config.yaml # Note that again these are docker-context paths, not local paths. bitops: plugins: sample-plugin: source: file:///opt/bitops-local-plugins/sample-plugin deployments: sample-plugin: plugin: sample-plugin
Note: This is the same file as above (
/path/to/ops-repo/test-env/sample-plugin/bitops.config.yaml), but we've updated the
plugins.sample-pluginobject to include a
Note: The path of the source is reserved by BitOps for locally developed plugins. When you build a custom BitOps image, if there is a
pluginsdirectory as a sibling to the
Dockerfile, BitOps will copy that file into the container at
4.2.2 Add your Dockerfile#
# /path/to/bitops-plugins/bitops-images/sample-plugin-image/Dockerfile FROM bitovi/bitops:base
4.2.3 Copy plugin code to the BitOps directory#
In order for the build to have access to your local plugin files, they'll need to be in the same directory as the
Dockerfile. One quick way to do this is to set up a simple script to run prior to your docker build to clean and re-copy the plugin files:
# /path/to/bitops-images/copy-plugins.sh #!/bin/bash PLUGIN_NAME=sample-plugin PLUGIN_ROOT_PATH=/path/to/bitops-plugins CUSTOM_IMAGE_PATH="$PLUGIN_ROOT_PATH/bitops-images/$PLUGIN_NAME-plugin-image" PLUGIN_PATH="$PLUGIN_ROOT_PATH/$PLUGIN_NAME" mkdir -p "$CUSTOM_IMAGE_PATH/plugins" # clean and copy to the image build dir rm -rf $CUSTOM_IMAGE_PATH/plugins/$PLUGIN_NAME cp -r $PLUGIN_PATH "$CUSTOM_IMAGE_PATH/plugins/$PLUGIN_NAME"
4.2.4 Build the image#
./copy-plugins.sh docker build --tag bitovi/bitops:local-sample-plugin --no-cache .
4.2.5. Test your plugin#
PATH_ROOT=~/Bitovi/github/bitops-plugins # modify to your path here docker run --rm --name bitops \ -e BITOPS_ENVIRONMENT="test-env" \ -v $PATH_ROOT/sample-ops-repo:/opt/bitops_deployment \ -v $PATH_ROOT/sample-plugin:/opt/bitops/scripts/installed_plugins/sample-plugin \ bitops:local-sample-plugin
5. Fully Remote Development#
An alternative to local plugin development is to host the plugin code remotely and specify the plugin via url instead of
bitops: plugins: sample-plugin: source: https://github.com/your-org/sample-plugin deployments: sample-plugin: plugin: sample-plugin
Then, you can follow the steps in #5 above (without the