Contents
Deploy on Google Cloud, AWS or Azure Enterprise
On Google Cloud, AWS and Azure you run the team server as a unikernel, a tiny VM that boots straight into gitta. There is no shell, no SSH and nothing else installed, which minimizes the attack surface.
Why a unikernel
A normal VM runs an operating system with many services, users and tools. Each one needs updates and is a way in. The gitta unikernel image holds the Nanos kernel and the gitta server, nothing else. Nobody can log in to it.
To change a server, build a new image and replace the VM. The deploy script does both.
Before you start
- The gitta Enterprise package, with the
gittaserver program for Linux x86_64 anddeploy.sh. - ops, the NanoVMs tool that builds and starts unikernel images. Run the deploy from Linux, or from a Mac with the x86_64 Nanos kernel installed.
- The cloud's own command line tool, logged in, with rights to create images, VMs and firewall rules.
- A DNS name for each server and a TLS certificate for those names.
Google Cloud
- Make a storage bucket for images, in the region you will use.
$ gcloud storage buckets create gs://example-gitta-images --location=europe-north1 - Make a service account with the roles Compute Admin, Storage Admin and Service Account User. Save its key file.
- Deploy two servers in two zones.
$ export GOOGLE_APPLICATION_CREDENTIALS=~/gitta-deploy-key.json $ export GCP_PROJECT=example-project GCP_ZONE=europe-north1-a GCP_BUCKET=example-gitta-images $ export GCP_ZONES=europe-north1-a,europe-north1-b COUNT=2 $ export GITTA_TLS_CERT=fullchain.pem GITTA_TLS_KEY=privkey.pem $ export GITTA_LICENSE_FILE=example.license $ ./deploy.sh gcp ./gitta gitta token written to ./gitta-server.token signing key written to ./gitta-server.signing-key Image creation succeeded gitta. Instance creation succeeded gitta-1. Instance creation succeeded gitta-2. started 2 server(s). Find the addresses with: ops instance list -t gcp -c <config> - Reserve the VMs' addresses as static addresses and point your DNS names at them.
$ gcloud compute addresses create gitta-1 --addresses=<address of gitta-1> --region=europe-north1
AWS
- Make an S3 bucket for images.
$ aws s3 mb s3://example-gitta-images --region eu-north-1 - Create the
vmimportrole that AWS uses to import VM images. Follow the AWS guide "Required service role for VM Import". Give it read access to the bucket. - The user that deploys needs EC2 and S3 rights, and the EBS rights
ebs:StartSnapshot,ebs:PutSnapshotBlock,ebs:CompleteSnapshot. - Deploy.
$ export AWS_PROFILE=gitta AWS_REGION=eu-north-1 AWS_BUCKET=example-gitta-images COUNT=2 $ export GITTA_TLS_CERT=fullchain.pem GITTA_TLS_KEY=privkey.pem GITTA_LICENSE_FILE=example.license $ ./deploy.sh aws ./gitta gitta - Allocate an Elastic IP for each server, associate it, and point your DNS names at them.
Azure
- Make a resource group and a storage account.
$ az group create -n gitta -l swedencentral $ az storage account create -n examplegittaimages -g gitta -l swedencentral --sku Standard_LRS - Make a service principal with the Contributor role on the resource group.
- Deploy.
$ export AZURE_SUBSCRIPTION_ID=… AZURE_TENANT_ID=… AZURE_CLIENT_ID=… AZURE_CLIENT_SECRET=… $ export AZURE_LOCATION=swedencentral AZURE_RESOURCE_GROUP=gitta AZURE_BASE_GROUP_NAME=gitta $ export AZURE_STORAGE_ACCOUNT=examplegittaimages AZURE_STORAGE_ACCESS_KEY=… $ export GITTA_TLS_CERT=fullchain.pem GITTA_TLS_KEY=privkey.pem GITTA_LICENSE_FILE=example.license COUNT=2 $ ./deploy.sh azure ./gitta gitta - Attach a static public IP to each VM's network interface, and point your DNS names at them.
Settings for deploy.sh
| Variable | Use |
|---|---|
COUNT | Number of servers. Default 1. Use 2 or 3 for several servers. |
GCP_ZONES | Zones on Google Cloud to spread the servers over, comma separated. |
FLAVOR | VM size. The defaults are e2-small, t3.small and Standard_B2ts_v2. |
GITTA_TOKENS | Admin tokens. If empty, one is made and written to ./gitta-server.token. |
GITTA_SIGNING_KEY | If empty, ./gitta-server.signing-key is used or made. Keep it for the next deploy. |
GITTA_TLS_CERT, GITTA_TLS_KEY | With these, the server serves HTTPS on port 8443. Without them, HTTP on port 8080, for use behind a TLS load balancer. |
GITTA_LICENSE_FILE | Your licence. |
ARCH | amd64 (default) or arm64, to match the server program. |
Treat the image like the secrets in it:
- Limit who can read images in the project or account where you deploy, ideally a project used only for gitta.
- When you rotate tokens, the signing key or the certificate, deploy new images and then delete every old image, snapshot and image version. Until they are deleted, the old secrets can be read from them.
- Rotating the signing key invalidates every personal token. Issue new ones after the rotation.
Kubernetes keeps these secrets in a Kubernetes Secret instead, provided at start, not stored in an image. Use the Helm chart where that difference matters.
Try it on your own machine
deploy.sh local boots the same image under QEMU, on port 8080 or 8443.
$ ./deploy.sh local ./gittaCost
One small VM per server. Delete the VMs and images when you stop using them.