components

The components key contains:

📘

Please see the dedicated Components section of the documentation for details on each.

 

Components Composition

You can combine as many Components as you need in a single Environment, regardless of their kind.

Let's take an example:

  • payments_service to deploy a Helm Chart containing all what is needed for this microservice to run
  • checkout_proxy to deploy a Kubernetes manifest containing a simple proxy service
  • frontend_checkout to deploy a static application
  • admin_internal to deploy a monolith app which uses Docker-compose for local development
  • nginx to deploy the gateway of the Environment
  • mysql to deploy a Database
  • cloud-run-workers to deploy a batch processing job in any other place than Kubernetes
...
components:

  - kind: Helm
    name: payments_service
    ...

  - kind: KubernetesMafinest
    name: checkout_proxy
    ...

  - kind: StaticApplication
    name: frontend_checkout
    ...

  - kind: Application
    name: admin_internal
    ...
    
  - kind: Service
    name: nginx
    ...
    
  - kind: Database
    name: mysql
    ...
    
    - kind: GenericComponent
    name: cloud-run-workers
    ...

 

Schema for all Components

Some attributes are common for all Components, regardless of their kind. They are listed below.

📘

More attributes are available, depending on the component kind. They will be detailed below.

components.[*]:

  kind:
    type: string
    required: true
    description: Type of the component

  name:
    type: string
    required: true
        description: Component name, used to reference the component internally; for Docker-compose Components, the name the Kubernetes services as well

  metadata:
    type: hash
    required: false
    description: Pretty name for the component, reference to the origin of the imported definition etc.

  gitRepo:
    type: string
    required: false
    description: Git repository for the Component

  gitBranch: 
    type: string
    required: false
    description: Git branch for the Component

  gitApplicationPath: 
    type: string
    required: false
    description: Folder path within the Git repository; useful for monorepos

  version:
    type: string
    required: false
    description: Version used by the Bunnyshell parser for this component, default is "v1"
    
  ...

kind

Available kinds:

  • Helm
  • KubernetesManifest
  • DockerImage
  • GenericComponent
  • Application
  • Service
  • Database
  • StaticApplication
  • InitContainer
  • SidecarContainer

Please read the specific Components documentation for details on each.

metadata

Currently, it is used to keep references to Bunnyshell internal entities, such as the ID of the Environment, or a unique hash to identify the Environment by.

Also, arbitrary key-value pairs can be inserted here, for future use.

Example

components:
  - name: example
    ...
    metadata:
      com.bunnyshell.k8s.id: 18182
      com.bunnyshell.k8s.unique: qmrxve-0

gitRepo

Depending on component type, the repository will either be:

  • for Helm, KubernetesManifest and GenericComponents - cloned into the runner which is in charge of executing the deploy / destroy / start / stop workflows, so you can leverage files from within the repository in executing the workflows
  • for Docker-compose Components and DockerImage - used to build the image

For all Components, Bunnyshell will install a webhook so the Git Provider will notify Bunnyshell of the activity from within the repo. Currently, Pull Request create & close events are tracked, as well as commit pushes - for creating/destroying ephemerals, respectively updating Environments.

gitBranch

The branch for the Git repository.

gitApplicationPath

The path within the repository. Very important for detecting updates on applications in monorepos, as for a given Component, activity on other paths is ignored.

 

Schema for Docker-compose Components

📘

Also see attributes for all components, as they apply for Docker-compose Components as well.

components.[*]:

  dockerCompose:
    type: hash
    required: true
    description: Contains information needed to build the images

  envVarMapping:
    type: hash
    required: true
    description: Supporting use of dynamic Env vars, such as Application / Service / Database URLs, generated by Bunnyshell; key-value pairs. Will be replaced with actual values before the deployment.

  pod:
      type: hash
      required: false
      description: Co-locate services on same pods and share folders between them (eg. programming language container + web server container, aka PHP-FPM + nginx).

  hosts: 
      type: array
      required: false
      description: Specify the host URL (domain + path + service port).

📘

All schemas presented below are for the components.[*] path.

 

dockerCompose

All properties under this attribute are compatible with the compose specification.

Ultimately, they will be interpreted by the kompose.io converter when generating the Kubernetes manifests. Please consult the conversion support.

dockerCompose:
  build:
    context: 
      type: string
      required: true
      description: Path where the docker build will be ran
    dockerfile:
      type: string
      required: true
      description: Filename of the dockerfile, within the specified path (context)
    args:
      type: hash
      required: false
      description: Build arguments, expressed as key-value pairs
  environment:
    type: hash
    required: false
    description: Component-level variables. The bns_secret method can be used to mark a secret value (e.g. "- VAR_NAME:'bns_secret(secret value)'")

Example

dockerCompose:
  build:
    context: .docker/php
    dockerfile: Dockerfile
    args:
      buildno: 1
  environment:
    ENV: production
    password: 'bns_secret(mypassword)'

pod

Allows to enhance the Pod specification with Kubernetes-native concepts: Init & Sidecar containers.

You would use Init Containers when handling initialization tasks, such as changing permissions on folders within a volume.
You would use Sidecar containers to group containers to run in a single Pod, in order to share files or use the same localhost.

pod:
  init_containers:
    type: array
    required: false
    description: The components of kind InitContainer that will run as an initContainer in this pod along with the main component
  sidecar_containers:
    type: array
    required: false
    description: The components of kind SidecarContainer that will run as an containers in this pod along with the main component

Example

Let's take an example which would use some volumes and mount them in the init and sidecar containers, respectively. shared_paths and volumes attributes on the pod.[*].init_container and pod.[*].sidecar_container will be explained separately.

The container init-fronted-custom-name will run before the actual container example is started.

The container sidecar-backend-custom-name will run alongside example, in the same Pod.

volumes:
  -
    name: node-modules-cache
    type: disk
    size: 1Gi
  -
    name: backend-sessions
    type: disk
    size: 1Gi
    
components:
  - name: example
    kind: Application
    ...
    pod:
      init_containers:
        -
          from: init-frontend
          name: init-fronted-custom-name
          environment:
              NODE_ENV: production
         shared_paths:
           -
             path: /opt/frontend/public
             target:
               path: /opt/nginx/public/static
               container: '@parent'
             initial_contents: '@self'
         volumes:
           -
             name: node-modules-cache
             mount: /opt/frontend/node_modules
      sidecar_containers:
        -
          from: sidecar-backend
          name: sidecar-backend-custom-name
          environment:
            COMPOSER_HOME: /opt/.composer
          shared_paths:
            -
              path: /opt/backend/.etc/nginx/config
              target:
                path: /etc/nginx/config
                container: '@parent'
              initial_contents: '@self'
          volumes:
            -
              name: backend-sessions
              mount: /opt/backend/sessions

pod.init_containers.[*]

name:
  type: string
  required: true
  description: The name of the container. Must be unique to be able to add several containers for the same Init/Sidecar type component.
from:
  type: string
  required: true
  description: The name of a component of kind InitContainer for init_containers or kind SidecarContainer for sidecar_containers.
environment:
  type: hash
  required: false
  description: A key-value map of environment variables to inject into this init container or sidecar container.
shared_paths:
  type: array
  required: false
  description: ReadWrite paths that should be shared between current init or sidecar container and a target container in the pod.
volumes:
  type: array
  required: false
  description: Volume mounts to be added to this init or sidecar container.

pod.init_containers.[*].shared_paths.[*]

shared_paths are Kubernetes emptyDir volumes, mounted between the init or sidecar container and another container within the Pod.

path:
  type: string
  required: true
  description: A path from the current init/sidecar container
target:
  type: hash
  required: true
  description: A target for path sharing
  keys:
    container:
      type: string
      required: true
      description: A container name in the same pod. Refer to the component where the pod is defined with '@parent'.
    path:
      type: string
      required: true
      description: A path in the defined target.container.
initial_contents:
  type: enum
  values: ['@self', '@target']
  required: true
  description: Shared path initial contents from either current init/sidecar container or target container.

pod.init_containers.[*].volumes.[*]

volumes are Kubernetes classic volume mounts.

name:
  type: string
  required: true
  description: The name of a volume, as defined in bunnyshell.yaml key "volumes".
mount:
  type: string
  required: true
  description: A path where the volume should be mounted in the current init/sidecar container.

pod.sidecar_containers.[*]

See pod.init_containers.[*], the definition is identical for sidecar and init containers.

pod.sidecar_containers.[*].shared_paths

See pod.init_containers.[*].shared_paths, the definition is identical for sidecar and init containers.

pod.sidecar_containers.[*].volumes.[*]

See pod.init_containers.[*].volumes.[*], the definition is identical for sidecar and init containers.

hosts

hosts:
  - hostname: 
        type: string
        required: true
        description: Hostname prefix, must be suffixed with "-${env.unique}.bunnyenv.com"
    path: 
        type: string
        required: false
        description: URL path, if any
    servicePort:  
        type: string
        required: true
        description: "Public" port (not the container port), aka the one exposed through the Service definition
    public:
        type: boolean
        required: false
        description: Comes into effect when "security.allowedIps" is set. When set to "true" it allows traffic from all IPs, including those which do not exist in the allowedIps list.

Example

hosts:
  - hostname: backend-qmrxve.bunnyenv.com
    path: /
    servicePort: 8080
    public: true

 

Schema for Helm and KubernetesManifest

📘

Also see attributes for all components, as they apply for Helm, KubernetesManifest, GenericComponent Components as well.

components.[*]:

  deploy:
      type: array
      required: false
      description: A list of commands that will be ran each time this environment is deployed.

  destroy:
      type: array
      required: false
      description: A list of commands that will be ran when this environment is deleted.

  start:
      type: array
      required: false
      description: A list of commands that will be ran each time this environment is started.

  stop:
      type: array
      required: false
      description: A list of commands that will be ran each time this environment is stopped.

  runnerImage:
      type: string
      required: false
      description: The Docker image in which the deploy/destroy/start/stop commands will be ran. 

  exportVariables:
      type: array
      required: false
      description: A list of variables that will be exported from the runner and will be made available to be used in interpolations as "components.NAME.exported.VAR_NAME".

runnerImage

The image which will be to run the specified scripts in. git* attributes, if specified, will also clone the repository and mount it in the running container.

deploy / destroy / start / stop

Sequence of scripts to be ran in each of the workflows. Please see the workflows documentation.

exportVariables

Environment Variables from the runner container which can be captured and stored in Bunnyshell, to be used by interpolating the value in later-ran Components.

 

Schema for DockerImage Components

📘

Also see attributes for all components, as they apply for Docker-compose Components as well.

components.[*]:

  context:
    type: string
    required: false
    description: Available path for build. Default value is "/".
    
  dockerfile:
    type: string
    required: false
    description: Path to Dockerfile, within the context. Default value is "Dockerfile".
    
  target:
    type: string
    required: false
    description: Specifies stage to be built.
    
  args
    type: map
    required: false
    description: Key-value pairs for build arguments.

context

Same meaning as Docker context. Will make only the specified context available during the build.

Must be included in gitApplicationPath, otherwise the cloned part of the repo will not contain the context.

dockerfile

Same meaning as Docker dockerfile. Path to Dockerfile, within the context.

target

Same meaning as Docker `target`. Specifies the stage to be built.

args

Same meaning as Docker args. These are build arguments.

 

Schema for GenericComponent Components

Please see the Schema for Helm and KubernetesManifest, as the Generic Component inherits it all, with one difference.

runnerImage

The only difference is that, for GenericComponents you can use @self in case the commands should be ran inside the component built image.