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.
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.
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).
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
-
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"