Environment definition file (env.yaml)

In order to describe an Environment, we use a single editable record, which contains its entire definition, including Applications / Services / Databases. We call it env.yaml

Overview

version:
  type: string
  required: true
  description: Bunnyshell parser version used for the current Environment definition.
kind:
  type: string
  required: true
  description: Type of entity being described, "Environment".
metadata: 
  type: hash
  required: false
  description: Key-value pairs; currently used to keep links with Bunnyshell entities.
name:
  type: string
  required: true
  description: Name of the Environment.
deploymentRules:
  type: hash
  required: false
  description: Settings serving Environment cloning and updating.
type:
  type: string
  required: true
  description: Specifies whether an Environment is permanent or ephemeral.
components:
  type: array
  required: true
  description: Contains the definitions of the Applications / Services / Databases composing the Environment.
security:
  type: hash
  required: false
  description: Settings related to the security of the environment.
environmentVariables:
  type: hash
  required: false
  description: Environment-level variables. The bns_secret method can be used to mark a secret value (e.g. "- VAR_NAME:'bns_secret(secret value)'")

metadata

Currently, used to keep references to Bunnyshell internal entities, such as the ID of the Environment, or a unique hash to identify the Environment by, upon - the Kubernetes namespace will contain it.

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

metadata Example

metadata:
  com.bunnyshell.k8s.id: 123
  com.bunnyshell.k8s.unique: alphanumeric
  com.bunnyshell.k8s.docker-compose-version: 3.4
  arbitrary: value

security

Allows the user to control various aspects related to the environment's security.

For example you can have a non-public environment, that can be accessed only from certain IP ranges.

You can force certain endpoints to remain public by setting the flag components.N.hosts.N.public to true.

security:
  access:
    allowedIps:
      - '192.168.0.1/24'
      - '192.12.45.123/32'

Components

Applications, Services and Databases are defined under the components key.

components Composition Example:

components:
  - kind: Application
    version: v1
    name: php
    ...
  - kind: Application
    version: v1
    name: java
    ...
  - kind: Service
    version: v1
    name: nginx
    ...
  - kind: Database
    version: v1
    name: mysql
    ...
  - kind: GenericComponent
    version: v1
    name: cloud-run-nginx
    ...

Components Definition

components.N:
  kind:
    type: string
    required: true
    description: Type of the component - Application / Service / Database / StaticApplication / InitContainer / SidecarContainer
  version:
    type: string
    required: true
    description: Version used by the Bunnyshell parser for this component
  metadata:
    type: hash
    required: false
    description: Pretty name for the component, reference to the origin of the imported definition etc.
  name: php
    type: string
    required: true
    description: Component name, used to reference the component internally and name the Kubernetes services
  gitRepo:
    type: string
    required: false
    description: Git repository for the docker-compose.yml file which contained this component
  gitBranch: 
    type: string
    required: false
    description: Git branch for the docker-compose.yml file which contained this component
  gitApplicationPath: 
    type: string
    required: false
    description: Folder path within the Git repository; useful for monorepos
  gitDockerComposePath:
    type: string
    required: false
    description: Path of the docker-compose.yml file within the Git repository; may or may not contain the filename
  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.
  k8s:
    resources: 
      type: hash
      required: true
      description: Specify resource allocation, in a Kubernetes-compatible way.
  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).
  preReleaseCommands: 
      type: array
      required: false
      description: Every new pod for this Application will first run these commands in order and wait until they are succesfull. Only after their success, the pod will start.
  cronJobs:
      type: array
      required: false
      description: A list of commands to be ran. Any command will be ran each time in a fresh container instance, so you cannot rely on running jobs on existing containers (eg. not suitable for log rotation).
  dbSeed:
      type: string
      required: false
      description: Used only for Databases. A string composed of a filename and a version. The files must be uploaded in Bunnyshell beforehand.
  deploy:
      type: array
      required: false
      description: Used only for GenericComponents. A list of commands that will be ran each time this environment is deployed.
  destroy:
      type: array
      required: false
      description: Used only for GenericComponents. A list of commands that will be ran when this environment is deleted.
  start:
      type: array
      required: false
      description: Used only for GenericComponents. A list of commands that will be ran each time this environment is started.
  stop:
      type: array
      required: false
      description: Used only for GenericComponents. A list of commands that will be ran each time this environment is stopped.
  runnerImage:
      type: string
      required: false
      description: Used only for GenericComponents. The Docker image in which the deploy/destroy/start/stop commands will be ran. Use "@self" in case the commands should be ran inside the component image.
  exportVariables:
      type: array
      required: false
      description: Used only for GenericComponents. 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"..

components.N.dockerCompose Definition

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)'")

components.N.dockerCompose Example

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

components.N.k8s.resources Definition

  k8s:
    resources:
      requests:
        cpu: 
          type: string
          required: false
          description: Kubernetes-compatible values
        memory: 
          type: string
          required: false
          description: Kubernetes-compatible values
      limits:
        cpu: 
          type: string
          required: false
          description: Kubernetes-compatible values
        memory: 
          type: string
          required: false
          description: Kubernetes-compatible values

components.N.k8s.resources Example

  k8s:
    resources:
      requests:
        cpu: 500m
        memory: "512Mi"
      limits:
        cpu: "1"
        memory: "1Gi"

components.N.pod Definition

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

components.N.pod Example

Volumes:
  -
    name: node-modules-cache
    type: disk
    size: 1Gi
  -
    name: backend-sessions
    type: disk
    size: 1Gi
 
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

components.N.pod.*.N Definition

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.

components.N.pod.*.N.shared_paths.N Definition

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 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.

components.N.pod.*.N.volumes.N Definition

name:
  type: string
  required: true
  description: A named volume as defined in env.yaml.
mount:
  type: string
  required: true
  description: A path where the volume should be mounted in the current init/sidecar container.

components.N.hosts Definition

hosts:
  - hostname: 
        type: string
        required: true
        description: Hostname prefix, will 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 IPs that do not exist in the allowedIps list.

components.N.hosts Example

hosts:
  - hostname: backend
    path: /
    servicePort: 8080
    public: true

components.N.cronJobs Definition

  cronJobs:
    - name: 
        type: string
        required: true
        description: The pretty name; a Kubernetes CronJob resource with the name "{service_name}.{cronjob_name}" will be created, to ensure uniqness in the namespace
      schedule: 
        type: string
        required: true
        description: Kubernetes Cron schedule syntax (https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax);
      command: 
        type: string
        required: true
        description: The command to be ran

components.N.cronJobs Example

  cronJobs:
    - name: check-git-status
      schedule: "*/1 * * * *"
      command: php bin/console git:check-status 

Complete Configuration Example

version: v1
kind: Environment
metadata:
  com.bunnyshell.k8s.id: 123
  com.bunnyshell.k8s.unique: {alphanumeric}
  com.bunnyshell.k8s.docker-compose-version: 3.4
  arbitrary: value
name: my-env
type: primary | ephemeral
components:
  - kind: SidecarContainer
    version: v1
    metadata:
      com.bunnyshell.k8s.display-name: PHP App
      com.bunnyshell.k8s.source-file: git.repo.com/.docker/docker-compose.yaml
      com.bunnyshell.k8s.source-file-hash: {alphanumeric}
      com.bunnyshell.k8s.source-block-hash: {alphanumeric}
      com.bunnyshell.k8s.source-name: php
    name: php
    gitRepo: git@...
    gitBranch: master
    gitApplicationPath: / # optional; for monorepo apps
    gitDockerComposePath: / # the path of the docker-compose.yaml inside the git_repo
    dockerCompose:
      # image: ... # if present, `image` will be removed, we will build the image and after that we will add the image: with the value from our Amazon ECR
      build:
        context: .docker/php
        dockerfile: Dockerfile
        args:
          buildno: 1
    envVarMapping:
      API_PATH: BNS_INGRESS_URL_NGINX # BNS_ are auto-generated
    k8s:
      resources: # k8s resources for this service; k8s syntax
        requests:
          cpu: "0.5"
          memory: "100Mi"
        limits:
          cpu: "900m"
          memory: "0.5Gi"
    hosts: # you can add more
      - hostname: app # will be suffixed with -${env_unique}.bunnyenv.com
        path: / # optional
        servicePort: 8080
    preReleaseCommands: # every new pod for this Application will first run these commands in order and wait until they are succesfull; only after their success, the pod will start
      - php bin/console doctrine:migrations -y
    cronJobs:
      - name: check-git-status
        schedule: "*/1 * * * *" # k8s Cron schedule syntax (https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax);
        command: php bin/console git:check-status # this will be passed as an argument to `/bin/sh -c`

  - kind: InitContainer
    version: v1
    name: frontend
    gitRepo: git@...
    gitBranch: master
    gitApplicationPath: / # optional; for monorepo apps
    dockerCompose:
      build:
        context: frontend

  - kind: Service
    version: v1
    metadata:
      com.bunnyshell.k8s.id: 123 # Bunnyshell ID, optional
      com.bunnyshell.k8s.display-name: Web Server
      com.bunnyshell.k8s.source-file: git.repo.com/.docker/docker-compose.yaml
      com.bunnyshell.k8s.source-file-hash: {alphanumeric}
      com.bunnyshell.k8s.source-block-hash: {alphanumeric}
      com.bunnyshell.k8s.source-name: nginx
    name: nginx
    gitRepo: git@...
    gitBranch: master
    gitApplicationPath: / # optional; for monorepo apps
    gitDockerComposePath: / # the path of the docker-compose.yaml inside the git_repo
    dockerCompose:
      build:
        context: .docker/nginx
        dockerfile: Dockerfile
        args:
          buildno: 1
    envVarMapping:
    k8s:
      resources: # k8s resources for this service; k8s syntax
        requests:
          cpu: "0.5"
          memory: "100Mi"
        limits:
          cpu: "900m"
          memory: "0.5Gi"
    pod:
      init_containers:
        -
          from: frontend
          name: # the name of the container
          shared_paths:
            -
              path: /var/www/public # path on this service container (e.g. frontend)
              target:
                container: '@parent'
                path: /var/www/html/public # path on the pod-colocated service container (e.g. nginx)
              initial_contents: '@self'
      sidecar_containers:
        -
          from: php
          name: # the name of the container
    hosts: # you can add more
      - hostname: app # will be suffixed with -${env_unique}.bunnyenv.com
        path: / # optional
        servicePort: 8080
        public: true # will be publicly available, even if the user IP does not exist in security.allowedIps
    preReleaseCommands:
    cronJobs:

  - kind: Database
    metadata:
      com.bunnyshell.k8s.id: 456 # Bunnyshell ID, optional
      com.bunnyshell.k8s.display-name: Database
      com.bunnyshell.k8s.source-file: git.repo.com/.docker/docker-compose.yaml
      com.bunnyshell.k8s.source-file-hash: {alphanumeric}
      com.bunnyshell.k8s.source-block-hash: {alphanumeric}
      com.bunnyshell.k8s.source-name: mysql
    name: mysql
    gitRepo: git@...
    gitBranch: master
    gitApplicationPath: / # optional; for monorepo apps
    gitDockerComposePath: / # the path of the docker-compose.yaml inside the git_repo
    dockerCompose:
      build:
        context: .docker/mysql
        dockerfile: Dockerfile
        args:
          buildno: 1
    envVarMapping:
    k8s:
      resources: # k8s resources for this service; k8s syntax
        requests:
          cpu: "0.5"
          memory: "100Mi"
        limits:
          cpu: "900m"
          memory: "0.5Gi"
    podSharing:
    hosts:
    preReleaseCommands:
    cronJobs:
    dbSeed: anonymized-dumps/stage-complex-scenarios.sql:v3
security:
  access:
    allowedIps: # only IPs in these ranges will be able to access the non-public hosts
      - '192.168.0.1/24'
      - '192.12.45.123/32'

Last updated

Was this helpful?