Adding a new project

Adding a Project

There are a few steps that must be followed when adding a project to the mntd.dev workflow. Some work is performed in the mntd-dot-dev repository itself, while other work must be done in your project repository. A mini-guide for adding a project follows - please follow included links to external documentation where given!

Updating the mntd.dev Garden Sources

To add your project to the mntd.dev workflow, you must first add a reference to your project to .variables.template.yaml. Each entry is a YAML mapping with two keys:

  1. name - The name of your project. This will be used in some other parts of configuration.
  2. repositoryUrl - An SSH URI to the project repository. This should be a Gitlab URI and include a fragment that points to the the main branch of your repository. For example: ssh://git@gitlab.com/minted/digital-products/addressbook.git#main

Adding Service Hostname Prefixes

If your project contains any HTTP services, you will want to add configuration so their hostnames can be managed correctly through the mntd.dev workflow. Inside the .variables.template.yaml configuration file in the mntd-dot-dev repository, there is a YAML mapping under the ingress.service-prefixes stanza. The keys of this mapping are the names of garden services, and the values are a DNS prefix that you wish to access the service at. All hostnames in mntd.dev should have this structure:

<service-prefix>.minted.<dev-username>.mntd.dev

The service prefix can contain multiple levels of hostnames (eg: my.example.service), but it must end with a dot (.).

Creating Garden Configuration

Add a garden yaml file to your code repo

The final piece of configuration that must be adding is the garden module configuration for the project itself. This configuration must be added to the project source code repository, and you must follow the naming convention garden expects (the filename must end with garden.yaml - if you just have a simple configuration, you should just use a single garden.yaml file).

The most typical type of module for projects will be the container module, as it enables running one or more containers and services (such as web services) that are served off of them. You should read through the garden documentation first, but there's also several great examples to follow with our existing project ecosystem:

  1. addressbook - Has container modules for a database, cache, and a web service
  2. mender - Has container modules for a database, cache, a web service, a background worker, and a Kubernetes module that deploys a blob storage bucket
  3. hitchedup - Has a container module for a NodeJS application, and a Kubernetes module that deploys a custom wildcard ingress

Choosing your garden app name

Your garden config file will likely have at least one main module for your service like:

1kind: Module
2type: container
3name: my-app
4services:
5  - name: my-app-api

Note that this name is different from the service -> name field that you will define.

Variables

One other key aspect of writing garden configuration is that variables are often used to avoid hard-coding configuration details, preventing duplication, and keeping secrets out of source control. All external configuration is managed through the mntd.dev Vault in a secret at the secrets/dev/garden.env path. This secret is a JSON object where the keys are the names of projects (eg: addressbook), and the values are also JSON objects.

The entire JSON object gets "merged" in to the garden configuration and is available under the secrets variable in garden. Thus, if you add a new JSON object to under a myproject key in the Vault secret value, as so:

1{
2   // ...
3   "myproject": {
4      "my-var-1": "foo",
5      "my-var-2": "bar"
6   },
7   // ...
8}

You will then be able to access these variables as so in garden configuration:

${var.secrets.myproject.my-var-1}

A good use-case for this functionality is populating environment variables for you project, like so:

1kind: Module
2type: container
3name: myproject
4services:
5  - name: myproject-api
6    env:
7      EXTERNAL_SERVICE_API_KEY: ${var.secrets.myproject.external-service-api-key}

Creating Hen Configuration

Garden will be used for the dev version of your app. For staging/production, you can choose to use Hen to build and deploy your application.

Hen uses a hen.yaml file for configuration, which will get processed into gitlab yaml files and other resources.

For more details, see Hen.

Choosing your Hen app name

Your hen config file will likely have fields like:

1name: my-app
2deployments:
3- name: my-app-api
4...
5variables: {}
6platformVersion: v9

The top-level name field is limited to 17 characters max. This is because it gets combined with the following naming scheme:

mntd-{name from hen.yaml}-staging (or similar for other environments)

in GCP, which has a limit of 30 characters total for project ids.

Consider removing -service or -svc if your project name is getting too long.

Wrapping Up

After making the requisite changes in both mntd.dev and the project being added, and ensuring these changes are pushed up to their respective source code repositories, the new project can now be used inside mntd.dev. To get the new project deployed in mntd.dev, individuals should run the self-update workflow inside mntd.dev:

garden run workflow self-update

This will update the remote sources and variables, and ensure any new configuration added is present. At that point, any modules present in the new project can be deployed with:

garden deploy