Skip to content

Infrastructure as Code

You can use the Nullstone UI to configure your applications and infrastructure, but there are times when you want to configure in code. Placing configuration in code allows you to automate configuration, track infrastructure changes in version control, and share configuration with your team.

Pipeline and Workflow

Having configuration in code allows you to correlate infrastructure changes with code changes. As an example, lets say you are adding a new feature that requires the use of new infrastructure. In the same commit or PR, you can add both the configuration to the IaC (infrastructure as code) file and the code for the new feature. As the PR is opened, a preview environment is created and launched. Because the configuration is in the IaC file, the preview environment will be configured with the new infrastructure. You can test the new feature in the preview environment and ensure it works as expected.

INFO

Coming Soon!

Once the PR is merged, all the infrastructure changes will be applied to all of your environments including production.

IaC File

A Nullstone IaC file is a YAML file and must be placed in the .nullstone directory of your repo. There are two types of IaC files:

  • A config.yml file is used to fully control the application's configuration.
  • A previews.yml file is used to override variables and environment variables in preview environments.

The format of the IaC file is similar to a docker-compose file. An example previews.yml is shown below.

yaml
version: "0.1"
apps:
  acme-api:
    vars:
      num_tasks: 1
      cpu: 256
      memory: 512
    environment:
      DATABASE_URL: "{{ POSTGRES_URL }}"
      ANOTHER_VAR: abc123
version: "0.1"
apps:
  acme-api:
    vars:
      num_tasks: 1
      cpu: 256
      memory: 512
    environment:
      DATABASE_URL: "{{ POSTGRES_URL }}"
      ANOTHER_VAR: abc123

At the root of the file, first specify the IaC file version. The current version is 0.1.

Next, specify all the applications you want to configure. Each application should be listed by its unique name. It must match the name of the application in Nullstone.

vars

The vars section is used to provide configuration for your application. Depending on the application module you are using, different variables may be available.

To see the available variables, check out the module's documentation in the Nullstone Registry. For example, if you are using the aws-fargate-service module, you can find the list of available variables here. Fargate Service Variables

Another way to determine the list of available variables is to check the Configuration tab for your application in the UI. Configuration Tab

If you don't include a variable in your IaC file, it is no problem. Nullstone will use the default value. However, if you specify a variable that doesn't exist, an error will occur during launch.

yaml
vars:
  num_tasks: 1
  cpu: 256
  memory: 512
vars:
  num_tasks: 1
  cpu: 256
  memory: 512

From the example above, we are explicitly setting the num_tasks to 1, cpu to 256, and memory to 512. All other variables will use the default values.

environment

The environment section is used to configure environment variables for the application. Specify as many key/value pairs as you like. For a config.yml file, any environment variables not specified will be removed from the application. For a previews.yml file, environment variables specified will either be added or overridden. Missing environment variables will have no affect.

Interpolation is supported when specifying environment variables in the IaC file. You can use interpolation to build new environment variables from other environment variables. Check out the guide on Environment Variables for more information.

yaml
environment:
  DATABASE_URL: "{{ POSTGRES_URL }}"
  ANOTHER_VAR: abc123
environment:
  DATABASE_URL: "{{ POSTGRES_URL }}"
  ANOTHER_VAR: abc123

When configuring environment variables in the UI, you can mark sensitive values as secrets. Secrets are not currently supported in the IaC file.

capabilities

The capabilities section is used to define all the capabilities for your application. It is only supported in a config.yml file. Any capabilities not listed in the config.yml file will be removed from the application for the preview environment.

In the example below, we are specifying that our application will have one capability. The module for the capability is the nullstone/aws-s3-cdn module and the version is latest. The module_version field is optional and will default to latest if not specified.

yaml
capabilities:
  - module: nullstone/aws-s3-cdn
    module_version: 'latest'
    vars:
      default_document: 'index.html'
      enable_www: false
      notfound_behavior:
        document: '404.html'
        enabled: true
        spa_mode: false
    connections:
      subdomain:
        block_name: docs-subdomain
capabilities:
  - module: nullstone/aws-s3-cdn
    module_version: 'latest'
    vars:
      default_document: 'index.html'
      enable_www: false
      notfound_behavior:
        document: '404.html'
        enabled: true
        spa_mode: false
    connections:
      subdomain:
        block_name: docs-subdomain

Just like with the application, each capability may have variables that can be configured. In the example, we are configuring the default_document, enable_www, and notfound_behavior variables. The notfound_behavior variable is a complex type with 3 attributes. It can be represented using yml syntax.

Capabilities can have a single connection and if it has a connection it is required. Looking at the definition for the aws-s3-cdn module, we can see that it has a single connection named subdomain. The capabilities that we define in the IaC file must match the capabilities defined in the module.

To configure a capability connection, we need to specify which block to connect to. The block_name is required and must match the name of a block in Nullstone.

Optionally, you can also specify a stack_id and env_id for the connection. If stack_id and env_id are not specified, the connection will be made to the current stack and environment. These fields are useful when you want to connect to a block in a different stack or environment. For example, you may want to connect to a domain block in the global stack and environment. Most of the time you will not need to specify these fields.