Generic Component

Customizable component for writing your own integrations

Generic components are deployed just like any other environment component in Bunnyshell.

๐Ÿ“˜

They can be defined and edited only from the bunnyshell.yaml.

For generic components, users can choose to use their own images. Alternatively, Bunnyshell can build the images for them.

What differentiates the generic ones from other types of components are the deployment steps.

Normally, when components are deployed, Bunnyshell will generate or use a Kubernetes manifest that will be applied in the cluster. This is not the case with generic components, as no Kubernetes manifest is created or used.

A Generic Component allows the user to write a series of bash scripts containing the commands Bunnyshell will execute when running each workflow (deploying / starting / stopping / deleting the component).

Generic components have a separate kind in bunnyshell.yaml, named GenericComponent. Their custom attributes in bunnyshell.yaml are the following:

  • runnerImage
  • Commands:
    • deploy
    • destroy
    • start
    • stop
  • exportVariables

Common features between Generic Components and other types of components:

  • They are based on a Git repo

  • They can be automatically updated and redeployed (on condition that the feature is enabled) when a git webhook is received.

  • They can be cloned automatically when ephemerals are created

  • They can have a DockerCompose attribute


Complete Example

Before we move on to the attributes, weโ€™ll provide you with an example bunnyshell.yaml file that has a Generic Component defined. In this case, Bunnyshell builds an image from a Git Repo and deploys it in Google Cloud Run.

kind: Environment
version: v1
name: CDM Demo
type: primary
components:
    -
        kind: GenericComponent
        runnerImage: 'google/cloud-sdk:alpine'
        deploy:
            - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
            - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
            - 'gcloud run deploy myservice-{{env.unique}} --image={{components.gcloud_demo.image}} --project $GPROJECT_ID --region us-central1 --allow-unauthenticated --platform managed --timeout 5m'
            - 'SERVICE_URL=$(gcloud run services describe myservice-{{env.unique}} --platform managed --region us-central1 --format ''value(status.url)'' --project $GPROJECT_ID)'
        destroy:
            - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
            - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
            - 'gcloud run services delete myservice-{{env.unique}} --quiet --project $GPROJECT_ID --region us-central1'
        start:
            - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
            - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
            - 'gcloud run deploy myservice-{{env.unique}} --image={{components.gcloud_demo.image}} --project $GPROJECT_ID --region us-central1 --allow-unauthenticated --platform managed --timeout 5m'
            - 'SERVICE_URL=$(gcloud run services describe myservice-{{env.unique}} --platform managed --region us-central1 --format ''value(status.url)'' --project $GPROJECT_ID)'
        stop:
            - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
            - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
            - 'gcloud run services delete myservice-{{env.unique}} --quiet --project $GPROJECT_ID --region us-central1'
        exportVariables:
            - SERVICE_URL
        version: v1
        name: gcloud-demo
        gitRepo: 'https://gitlab.com/account/repo.git'
        gitBranch: master
        environment:
            GCLOUD_KEY: |
                {
                  "type": "service_account",
                  "project_id": "project-123456",
                  "private_key_id": "366ae5ffd57641a726efd576ca9369b88bf31ebb",
                  "private_key": "<key>",
                  "client_email": "[email protected]",
                  "client_id": "109378362412555391093",
                  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
                  "token_uri": "https://oauth2.googleapis.com/token",
                  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
                  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/sa%40project-123456.iam.gserviceaccount.com"}
            GPROJECT_ID: project-123456
        dockerCompose:
            build:
                context: .
                args: {  }

๐Ÿ“˜

Git repositories

Please note you can also have a Git repository cloned in the runner by specifying the 3 git-related attributes as well: gitRepo, gitBranch and gitApplicationPath.


Custom attributes

runnerImage

This is where you specify the image where Bunnyshell runs the commands given by the user. It can be the actual image of the component, or any other image.

If the value provided for runnerImage is '@self', Bunnyshell will reference the image of the component.

gitRepo

Optional. The URL of the Git repository to clone in the workdir of the runner.

gitBranch

Optional. The branch of the Git repository to clone in the workdir of the runner.

gitApplicationPath

Optional. When provided, it will watch for changes only within this folder to trigger Auto-updates (if enabled) or to display that a new version of your application is available.

:warning: The repository will be cloned entirely, not just the specified gitApplicationPath.

Commands

In the deploy, start, stop and delete properties you can include your own commands. As mentioned before, you can deploy anywhere you want. You can even choose not to make any deployment, if that is the case.

๐Ÿ“˜

Please see the Workflow documentation to see how & when these scripts are executed in each of the flows.

Steps for the deploy property are mandatory. The other properties can be left blank.

Below is an example that includes all the four properties mentioned earlier.

๐Ÿ“˜

Deploy and Start in Generic Components always run in the order in which components are defined in bunnyshell.yaml.
Why is this important? Letโ€™s look at the variable SERVICE_URL. By exporting it at the beginning, we can inject it in the componentโ€™s environment variables and use it later in a separate component.

Stop and Destroy run in parallel.

deploy:
    - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
    - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
    - 'gcloud run deploy myservice-{{env.unique}} --image={{components.gcloud_demo.image}} --project $GPROJECT_ID --region us-central1 --allow-unauthenticated --platform managed --timeout 5m'
    - 'SERVICE_URL=$(gcloud run services describe myservice-{{env.unique}} --platform managed --region us-central1 --format ''value(status.url)'' --project $GPROJECT_ID)'
destroy:
    - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
    - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
    - 'gcloud run services delete myservice-{{env.unique}} --quiet --project $GPROJECT_ID --region us-central1'
start:
    - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
    - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
    - 'gcloud run deploy myservice-{{env.unique}} --image={{components.gcloud_demo.image}} --project $GPROJECT_ID --region us-central1 --allow-unauthenticated --platform managed --timeout 5m'
    - 'SERVICE_URL=$(gcloud run services describe myservice-{{env.unique}} --platform managed --region us-central1 --format ''value(status.url)'' --project $GPROJECT_ID)'
stop:
    - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
    - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
    - 'gcloud run services delete myservice-{{env.unique}} --quiet --project $GPROJECT_ID --region us-central1'

exportVariables

Using this property you can export variables from Generic Components to other components inside the environment. First of all, they reach an interpolation context and after that they cam be used.

๐Ÿ“˜

These are not environment variables, but variables exported from your deployment script.

deploy:
    - 'echo "$GCLOUD_KEY" >> /tmp/gcloud_sa.json'
    - 'gcloud auth activate-service-account [email protected] --key-file /tmp/gcloud_sa.json'
    - 'gcloud run deploy myservice-{{env.unique}} --image={{components.gcloud_demo.image}} --project $GPROJECT_ID --region us-central1 --allow-unauthenticated --platform managed --timeout 5m'
    - 'SERVICE_URL=$(gcloud run services describe myservice-{{env.unique}} --platform managed --region us-central1 --format ''value(status.url)'' --project $GPROJECT_ID)'

In the section above, under deploy, we defined the variable SERVICE_URL. A request is sent to Google to retrieve the public URL for the service that has just been deployed. Normally, this variabile would only run here. But in our case, we are going to list it under exportedVariables.

exportVariables:
            - SERVICE_URL

This way, after deployment Bunnyshell will store the variable (encrypted) in a database. The variable will be available for you to use in another component, if need be. You can use the exported variables in interpolation contexts using key with the format below:

{{components.NAME.exported.VAR_NAME}}

Generic Components also have Environment Variables.

Usually, environment variables are injected in Kubernetes, where Bunnyshell starts your pod with the image it built. All Component, Environment and Project variables are inherited.

With Generic Components, Environment Variables are injected in a container running with runnerImage.

Example: in the section below, we defined the variable GCLOUD_KEY, which we used in the deploy steps.

components:
  - name: demo
    kind: GenericComponent
    ...
    environment:
      GCLOUD_KEY: |
        {
          "type": "service_account",
          "project_id": "project-123456",
          "private_key_id": "366ae5ffd57641a726efd576ca9369b88bf31ebb",
          "private_key": "<key>",
          "client_email": "[email protected]",
          "client_id": "109378362412555391093",
          "auth_uri": "https://accounts.google.com/o/oauth2/auth",
          "token_uri": "https://oauth2.googleapis.com/token",
          "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
          "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/sa%40project-123456.iam.gserviceaccount.com"
        }

Resources

Resources created by Generic Components are self-managed by the user. Bunnyshell does not analyze the scripts nor does it keep track of any created resources.

Resource cleanup

The cleanup should be handled manually, by defining destroy scripts.