Deploying on GRIS Energia Systems

Quick and dirty overview of the process of deploying software onto our systems.

Overview

Software hosted on GRIS Energia Systems is handled in source form as git repositories, packaged as Linux container images and orchestrated as Kubernetes deployments.

Production environment

Software reachable from the outside is hosted here.

Developer access is restricted, but software updates are automatically handled via CI.

Requirements

Any projects aiming for deployment in our infrastructure should respect best practices, which include but are not limited to:

  • Must be maintainable

  • No hardcoded credentials

  • Network paths should be configurable, preferably via envvar

  • No binaries, bytecode or database dumps in the repository

  • App should initialize its own databases and storage

  • App should be self contained, no source code injected via filesystem mount at runtime

Workflow

The process is as follows.

1. Planning

Assert:

  • Compliance with requirements

Enumerate:

  • Endpoints which should be reachable by other app components (ex. databases)

  • Endpoints which should be reachable from outside

  • Filesystem paths requiring persistence between restarts

  • Configuration files or variables that need to be passed at runtime

2. Packaging

Package the app into a container image via a Dockerfile.

Avoid including unnecessary files and dependencies in the container image.

EXAMPLE

3. Deployment

Create a Kubernetes deployment project on GRIS Energia: Code, under <project>/stack-<app>

This deployment should contain the app, its dependencies, the way they interact with each other and with the outside.

Sensitive data should not be included.

EXAMPLE

4. CI integration

Only available for projects hosted on GRIS Energia: Code

The systems administration team creates a token for deployment-roller and installs it on your Gitlab group's variables as DEPLOYMENT_ROLLER_TOKEN.

A pipeline file is created as .gitlab-ci.yml, which should take care of packaging and redeploying a specific branch (ex. production).

EXAMPLE

Outside access

HTTP

If the project listens on a HTTP or WS endpoint, it can leverage our systems-wide ingress controller for both proxying and TLS termination.

For names under grisenergia.pt hostname format is as follows:

<component>.<app>.<project>.grisenergia.pt

example:

backend.zremoteqc.zdmp.grisenergia.pt

Generic TCP/UDP

Endpoints which are not HTTP or WS based can also be reachable from the outside, although they should be kept to a bare minimum.

Storage and persistence

Each project/namespace has read, write and execute privileges for directories under

/cluster/<project>

Projects should adhere to the following convention

/cluster/<project>/<app>/<component>

example:

/cluster/zdmp/zremoteqc/db

Development environment

This is a mirror of the production environment.

Teams although encouraged to develop and test on their own workstations, can be granted access to the development infrastructure.

Workflow

  • Request access from the systems administration team

  • Install kubectl

  • Add the following line to your hosts file

10.172.67.71    devcluster.grisenergia.pt
  • Export the following variables, as provided by your systems administrator
export DEVCLUSTER_ADDRESS=<address>
export DEVCLUSTER_USER=<user>
export DEVCLUSTER_TOKEN=<token>
export DEVCLUSTER_CACERT=<cert>
  • Configure kubectl by running
kubectl config set-cluster devcluster --server="$DEVCLUSTER_ADDRESS"
kubectl config set-credentials "$DEVCLUSTER_USER" --token="$DEVCLUSTER_TOKEN"
kubectl config set-context devcluster --user="$DEVCLUSTER_USER" --cluster=devcluster
kubectl config set-cluster devcluster --embed-certs --certificate-authority <(echo $DEVCLUSTER_CACERT)
kubectl config use-context devcluster
kubectl config set-context --current --namespace="$DEVCLUSTER_USER"

Resources