Skip to content

Creating your first Burp.toml

Miu edited this page Jul 1, 2023 · 13 revisions

Knowing the Burp.toml

Burp uses an application-specific configuration file to understand how it will deploy the application, this configuration will include, but is not limited to, the Git repository link of the application, the name of the application, and the build directory of the application. This TOML file will dictate how the application will be deployed and what other dependencies (third-party services) it will also deploy on the remote server.

Your first application

[service]
name = "burp"
build = "/"
repository = { link = "https://github.com/ShindouMihou/burp" }

To have Burp be able to deploy your application, its configuration (burp.toml) must have the following properties:

  • service.name
  • service.build
  • service.repository

To make the service build from a specific repository, simply add branch property to the repository property. For example:

repository = { link = "https://github.com/ShindouMihou/burp", branch = "feat/cool-feature" }

Read more about the different properties you can configure to the application in: Container Properties.

Environment Files

[environment]
baseline = ".env"
override = false
server-side = false

The environment properties in Burp allow applications to have their own configuration using a .env file. This file serves as a template, which can be either a .env.example or a .env file. Burp provides two ways to handle this configuration:

  1. Client-side: In this approach, Burp sends the baseline file from the client to the server. It is recommended when the application requires the deployer to configure the .env file in their development environment.

  2. Server-side: If the .env file is already configured on the server and mapped to Burp's container, you can enable the server-side option. This allows Burp to use the existing file or environment variables on the server for configuration. Alternatively, Burp can also configure the file using its own Burpy functions, which will be discussed later.

The main difference between server-side and client-side is:

  • Server-side: Uses the Git repository's baseline file (usually a .env.example) for configuration.
  • Client-side: Copies the baseline file from the development environment (where the CLI is used) to the remote server.

You should choose the appropriate approach based on your requirements:

  • Use server-side when you prefer an automatically generated configuration file using Burpy functions and do not need the deployer's configuration.
  • Use client-side when you want the deployer to configure the properties of the configuration file in advance.

Functions

[dependencies.environment]
MONGO_INITDB_ROOT_USERNAME="root"
MONGO_INITDB_ROOT_PASSWORD="[burp: Random(256) AS mongo.password]"

[environment.replacements]
MONGO_URI="mongodb://root:[burp: Use(mongo.password)]@172.17.0.1:2732"
SIGNING_KEY="[burp: Random(256)]"

Burp provides a variety of Burpy functions that can generate hashes, randomized strings, perform mathematics, and more. You can utilize these functions using the following syntax:

[burp: Function(arguments)]

Arguments can also include functions, which in turn can have their own arguments. When using a function as an argument, you don't need to include the brackets ([]). Here's an example:

[burp: Function(burp: Function2(arguments2), arguments)]

To store the result of a function for later use, you can add AS key at the end, like this:

[burp: Function(arguments)] AS something

Later on, you can refer to it using the Use function. Here's an example:

[burp: Use(something)]

You can leverage these functions to create configuration properties, as demonstrated in the example above. For a comprehensive list of available functions, you can refer to the Burpy Functions wiki page here.

Includes

Burp allows the transfer of files from the development environment to the remote server through the includes property at the top-level of the configuration (not within service or dependencies). This property requires a source and a target parameter to specify the location of the file inside the Burp container.

All included files are stored in a specific location within the Burp agent container. During Burp deployment, it binds $HOME/.burpy/ to /root/.burpy, which is where files like temporary build files and included files are stored.

Specifically, Burp saves all included files in .burpy/home/$target. For example, if you want to include a configuration file called git.toml and set the target as data/git.toml, it will be saved under .burpy/home/data/git.toml. You can then bind this location to the container using $HOME/.burpy/home/data/git.toml.

Here's an example:

includes = [
    { source = "data/git.toml", target = "data/git.toml" },
    { source = "data/docker.toml", target = "data/docker.toml" },
]

Additionally, you can specify that the included files are required by adding the required property:

includes = [
    { source = "data/git.toml", target = "data/git.toml", required = true },
]

This ensures that the specified files must be included, and if any of them are missing, Burp will raise an error.

Dependencies

[[dependencies]]
name = "primrose-mongo"
image = "mongo"
ports = [["2732","27017"]]
restart_policy = { name = "always" }
networks = ["mongo"]
volumes = [
    { type = "volume", source = "primrose_data", target = "/data/db" }
]

[dependencies.environment]
MONGO_INITDB_ROOT_USERNAME="root"
MONGO_INITDB_ROOT_PASSWORD="[burp: Random(256) AS mongo.password]"

[[dependencies]]
name = "primrose-cache"
image = "redis"
ports = [["2733","6379"]]
restart_policy = { name = "always" }

Burp allows you to spawn third-party services using the dependencies property. Unlike the service property, dependencies does not support building services from a Git repository. It also supports multiple dependencies and does not use a .env file for configuration; instead, the configuration needs to be specified directly in the TOML file.

To define a proper dependency, you must include the following properties:

  1. dependencies.name: This specifies the name of the dependency. It's important to ensure that the name does not conflict with any existing containers. Burp automatically prepends burp. to the name to avoid conflicts with non-Burp deployed containers. By default, Burp forcibly overrides the container with the same name unless you explicitly set dependencies.override to false.

  2. dependencies.image: This property specifies the image to be used for the dependency. It defines the base image of the third-party service.

Here's an example of a proper dependency definition:

[dependencies]
name = "my-dependency"
image = "my-dependency-image"

In this example, my-dependency is the name of the dependency, and my-dependency-image is the image to be used.

Please note that additional properties can be included in the dependencies section to further configure the service as required by the specific third-party service you are using.

Container Properties

Burp supports the following properties for both service and dependencies:

  1. hostname: Sets the hostname of the container.

  2. user: Sets the user within the container. For more information, refer to the Docker documentation.

  3. working_directory: Sets the working directory inside the container.

  4. command: Sets the arguments of the container. Learn more about it here.

  5. entrypoint: Sets the entrypoint of the container. Read more about it here.

  6. ports: Exposes the ports of the container. This is an array of arrays of numbers represented as strings. For example: [["1111","1111"],["2222","2222"]].

  7. volumes: Sets the volumes of the container. Read more about it in the section on Container Volumes.

  8. limits: Sets the resource limits of the container. Read more about it in the section on Resource Limits.

  9. restart-policy: Sets the restart policy of the container. Read more about it in the section on Restart Policy.

  10. networks: Sets the networks that the container will be connected to. If the network does not exist, it will be created. For example: ["mongo"].

  11. dns: Sets the DNS of the container. For example: ["1.1.1.1"].

  12. environment: Sets the environment variables of the container. This is the same as the example mentioned above.

  13. override: Specifies whether to override the container if it already exists.

Container Volumes

You can add volumes to a container by including a volumes property. This property accepts an array of items with the following structure:

type ContainerVolume struct {
	Type     string `toml:"type"`
	Source   string `toml:"source"`
	Target   string `toml:"target"`
	ReadOnly bool   `toml:"readonly"`
}

Here's an example:

volumes = [
    { type = "volume", source = "primrose_data", target = "/data/db" }
]

Burp supports two types of volume binding:

  1. bind: Binds a host location (on the remote server) to a location within the container.

  2. volume: Binds a Docker volume to a specific target location within the container.

You can also set readonly to true to allow the container to read the files but not write to them.

Resource Limits

Burp allows you to set specific resource limits for a container. To do this, you can include a limits property with the following structure:

type ContainerResourceLimits struct {
    CPUs       float32?  `toml:"cpus"`
    Memory     size?     `toml:"memory"`
    SwapMemory size?     `toml:"swap_memory"`
}

The size parameter represents the amount of memory to allocate to the container, specified in bytes or using the format [number] Kb. The CPUs property specifies the amount of available CPU resources the container should use. In Docker, this is referred to as cpus.

Here's an example of using resource limits:

limits = { cpus = 1.5, memory = "1 Gb", swap_memory = "1 Gb" }

Restart Policy

Burp supports a restart policy that defines how a container should behave when it crashes or encounters an error. You can set the restart policy by including a restart_policy property, which has the following structure:

type ContainerRestartPolicy struct {
    Name              string `toml:"name"`
    MaximumRetryCount int    `toml:"maximum_retry_count"`
}

The name property specifies the restart policy to be used, which can have the following values:

  1. no: This is the default value, indicating that the container should not automatically restart. If you want to use this policy, do not specify a restart_policy property.

  2. on-failure: This restarts the container if it exits due to an error. You can also specify a maximum_retry_count, which indicates the maximum number of times the container should be restarted before it stops attempting to restart.

  3. always: This restarts the container whenever it stops, unless it is stopped manually.

  4. unless-stopped: This restarts the container in the same way as the always policy, but it will not be restarted even after the Docker daemon restarts.

You can find more information about restart policies in the Docker documentation on Starting Containers Automatically.