Deployment Automation with GitLab CI and Nitric

This guide will demonstrate how Nitric can be used, along with GitLab CI, to create a continuous deployment pipeline. The actions in the example below target AWS, but can be modified to target Google Cloud or Microsoft Azure.

Workflow setup

To begin you'll need a Nitric project ready to be deployed. If you haven't created a project yet, take a look at the quickstart guide.

Next, we'll add a GitLab CI workflow file to the project. This is where you'll configure the deployment automation steps. Create a yaml file .gitlab-ci.yml at the root of your project. The file can be named how you like, however .gitlab-ci.yml is most common.

Here is example content you can copy into your workflow file. In the next sections we'll breakdown what's happening in this file, so you can modify it as you see fit.

deploy:
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  variables:
    PULUMI_CONFIG_PASSPHRASE: $PULUMI_ACCESS_TOKEN
    PULUMI_ACCESS_TOKEN: $PULUMI_ACCESS_TOKEN
    AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
    AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
    HOST_DOCKER_INTERNAL_IFACE: 'eth0'
  before_script:
    - apk update
    - apk add --no-cache curl bash
    - curl https://nitric.io/install | bash
    - export PATH=$PATH:$HOME/.nitric/bin
    - curl -fsSL https://get.pulumi.com/ | bash
    - export PATH=$PATH:$HOME/.pulumi/bin
  script:
    - nitric up --ci

Breaking it down

Edit the config file and start by defining a new job which uses a docker image as the base, and docker-in-docker (dind) as the underlying service.

deploy:
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind

Setup the workflow rules

Rules tell Gitlab when to run this job. In this case we want it to run when there is a merge request on the main branch.

$CI_PIPELINE_SOURCE == 'merge_request_event': run on a merge request.

$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH: run when the target is the default branch (main).

rules:
  - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Workflow variables

Configure the environment variables required by Nitric and Nitric's dependency Pulumi. In this example we store the required values in Gitlab CI variables. Variables can be found by navigating to https://gitlab.com/{user}/{project}/-/settings/ci_cd.

Pulumi

  • PULUMI_ACCESS_TOKEN

    • You can get a pulumi access token by logging into Pulumi on the browser and going to your profile settings. Under the 'Access Tokens' tab click 'Create token'.
  • PULUMI_CONFIG_PASSPHRASE

    • For interaction free experiences, Pulumi also requires a passphrase to be configured. Your passphrase is used to generate a unique key which encrypts configuration and state values.

AWS Login

  • AWS_ACCESS_KEY_ID

    • You can obtain a key, including its ID and value, from the amazon console.
  • AWS_SECRET_ACCESS_KEY

    • You can obtain a key, including its ID and value, from the amazon console.

Nitric

  • HOST_DOCKER_INTERNAL_IFACE

    • The network interface that the Nitric CLI will temporarily run the containers on. Without this, the containers can't communicate with the Nitric server whilst gathering the resource definitions.
variables:
  PULUMI_CONFIG_PASSPHRASE: $PULUMI_CONFIG_PASSPHRASE
  PULUMI_ACCESS_TOKEN: $PULUMI_ACCESS_TOKEN
  AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
  AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
  HOST_DOCKER_INTERNAL_IFACE: 'eth0'

Adding base dependencies

Within the before script, all the dependencies are added. Start by adding curl and bash, which are used when installing pulumi and nitric in the next steps.

before_script:
  - apk update
  - apk add --no-cache curl bash

Install Nitric and dependencies

These steps install the Nitric CLI and Pulumi, allowing the use of commands such as nitric up.

before_script:
  - apk update
  - apk add --no-cache curl bash
  - curl https://nitric.io/install | bash
  - export PATH=$PATH:$HOME/.nitric/bin
  - curl -fsSL https://get.pulumi.com/ | bash
  - export PATH=$PATH:$HOME/.pulumi/bin

Deploy the stack

Finally, in the script: section of the job, the up command can be used to deploy your project. The first argument --ci tells the CLI that we are running in a ci pipeline and should have raw output.

script:
  - nitric up --ci