The files in this repo have the following dependencies:
- Docker Engine or Docker Desktop (required by kl-deploy-images.sh)
- Git (required if you wish to use kl-deploy-images.sh to fetch Keylime source from a remote repository)
- Packer (required to use kl-gce-image.pkr.hcl)
- Terraform (required to use kl-gce-vm.tf)
Additionally, the files and scripts in this repo all require the appropriate credentials to authenticate to GCP.
There are a few different ways to authenticate to GCP but it usually easiest to use the gcloud CLI. As alternative, when employing the files in this repo in a GitHub Actions workflow, the auth action can be used instead.
To authenticate using the gcloud CLI, make sure the CLI is installed and then run gcloud auth login
. Because Packer and Terraform use Application Default Credentials (ADC), you will also need to run gcloud auth application-default login
.
If you wish to use the kl-deploy-images.sh script to push images to GCR, you also need to configure Docker to use a GCP authentication provider. gcloud can do this automatically if you run gcloud auth configure-docker
(you can accept the default options).
To provision a new deployment of Keylime in GCP:
-
Clone this repo to your machine:
git clone git@github.com:hse-aurora/keylime-ci.git cd keylime-ci
-
Choose an identifier to attach to the resources that will be provisioned in GCP. This should describe the environment (e.g., "dev" or "stage"). If you are using these files to set up a development environment for yourself, it is suggested that you include your name to disambiguate your VMs from those of your team members.
Set your chosen identifier as an environment variable:
export GCP_ID="dev-jean-$(date +%s)"
-
Build Docker images for the verifier, registrar and tenant using the source location of your choice and push these to GCR.
To base your images on the official repo:
./kl-deploy-images.sh -r git@github.com:keylime/keylime.git -c vrt -p gcr.io/project-keylime -t "$GCP_ID"
To base your images on a local clone or fork:
./kl-deploy-images.sh -d <path_to_kl_dir> -c vrt -p gcr.io/project-keylime -t "$GCP_ID"
where
<path_to_kl_dir>
is the path, relative to your current working directory, to the directory containing the Python source code for the server-side components of Keylime. -
Build a Docker image for the agent using the source location of your choice and, again, pushing this to GCR.
To base your image on the official repo:
./kl-deploy-images.sh -r git@github.com:keylime/rust-keylime.git -c a -p gcr.io/project-keylime -t "$GCP_ID"
To base your image on a local clone or fork:
./kl-deploy-images.sh -d <path_to_rust_kl_dir> -c a -p gcr.io/project-keylime -t "$GCP_ID"
where
<path_to_rust_kl_dir>
is the path, relative to your current working directory, to the directory containing the Rust source code for the Keylime agent. -
Copy the default Packer input variables file and make edits as appropriate:
cp defaults/kl-gce-image.pkrvars.hcl . nano kl-gce-image.pkrvars.hcl # Or editor of your choice
-
Fetch the required plugins for Packer and Terraform:
packer init kl-gce-image.pkr.hcl && terraform init
-
Use Packer to build a VM image in GCP with pre-installed containers for the verifier, registrar, tenant and agent:
packer build -var-file="kl-gce-image.pkrvars.hcl" kl-gce-image.pkr.hcl
If an image with that ID already exists, you can overwrite it by adding the
-force
option. -
Create a new Terraform workspace and instantiate a new VM instance based on the image generated by Packer:
terraform workspace new <workspace_name> terraform apply -var image_name="packer-keylime-$GCP_ID" -var ovmid="$GCP_ID"
where
<workspace_name>
is a name of your choice, only visible to you, to represent the environment you are deploying (e.g., "development" or "staging").
If you have performed the above steps in order, you will now see the following resources in the GCP console:
-
In the GCP Container Registry:
- A Docker image in the
keylime_base
repository with the tag<GCP_ID>
. - A Docker image in the
keylime_verifier
repository with the tag<GCP_ID>
. - A Docker image in the
keylime_registrar
repository with the tag<GCP_ID>
. - A Docker image in the
keylime_tenant
repository with the tag<GCP_ID>
. - A Docker image in the
keylime_agent
repository with the tag<GCP_ID>
.
- A Docker image in the
-
In GCP Compute Engine, under Images:
- A VM image called
packer-keylime-<GCP_ID>
.
- A VM image called
-
In GCP Compute Engine, under VM Instances:
- A VM instance called
terraform-keylime-<GCP_ID>
which will be assigned the IP address output by Terraform in step 7. Note that this IP is dynamic so it will change upon VM reboot.
- A VM instance called
You can access the VM by copying the gcloud_ssh_cmd
value output by Terraform in step 7 and pasting it in your terminal:
gcloud compute ssh --zone europe-west2-c terraform-keylime-<GCP_ID> --project project-keylime
Now if you run docker ps
in the remote shell, you will see running containers for each Keylime component (named keylime_verifier
, keylime_registrar
, keylime_tenant
and keylime_agent
). Keylime data and configuration files are stored in Docker volumes named kl-data-vol
and kl-config-vol
respectively. You can use docker volume inspect <vol_name>
to find the mount point of these volumes.
To access a shell inside a container, use Docker's exec
command. For example, to use the Keylime tenant to check the status of the deployment:
[kluser@terraform-keylime]$ docker exec -it keylime_tenant /bin/bash
[root@7fbd2d3c6f52 /]# keylime_tenant status
Finally, if you wish to see the log output of one of the Keylime components, run docker logs <container_name>
.