Deploy the Vault server

Project directory structure

The following command creates two additional subdirectories named vault and client within the apm-on-gcp directory, which will contain files for the Docker images:

$ mkdir -p {vault,client}

The resulting directory structure should look like this:

apm-on-gcp
  +- client
  +- vault

Prepare Vault docker image

The Vault docker image will be used to start a Vault server compute instance. Several steps are required for creating this image, which are documented in the following sections. These files should be created in the apm-on-gcp/vault directory.

apm-start.sh

Run the command below from the apm-on-gcp directory to create a file named apm-on-gcp/vault/start.sh, which is the server startup script. The environment variables defined in Set environment variables will be substituted in the file content. You may want to verify the contents of the file before proceeding.

This file defines a few steps:

  1. Fetch TLS cert and key from Google Cloud Secrets Manager

  2. Start the server using config.hcl (to be defined in the next section)

$ cat << EOF >vault/start.sh
#!/bin/bash

# Exit on failure
set -ex

# Access TLS key and cert from Google Cloud Secret Manager and store to files
gcloud secrets versions access latest \
    --secret "${VAULT_SERVER_TLS_KEY_SECRET}" \
    >/vault/tls/tls-key.pem
gcloud secrets versions access latest \
    --secret "${VAULT_SERVER_TLS_CERT_SECRET}" \
    >/vault/tls/tls-cert.pem

vault server \
    -config /vault/config/config.hcl
EOF
In development environments, you may use self-signed certificates for the APM. To skip TLS verification for these self-signed certificates, add the -tls-skip-verify flag to the command on line 15. Note that this is insecure for production environments.

config.hcl

Run the command below from the apm-on-gcp directory to create a file named apm-on-gcp/vault/config.hcl, which is the Vault server configuration file. The environment variables defined in Set environment variables will be substituted in the file content. You may want to verify the contents of the file before proceeding.

This file configures the following behaviors for the Vault server:

  1. Listen on port 8200

  2. Read TLS cert and key from filesystem (which were fetched from Secret Manager by the startup script)

  3. Use Google Cloud Storage as storage backend, with high availability enabled

  4. Auto-unseal using Google Cloud KMS

$ cat << EOF >vault/config.hcl
api_addr = "https://${VAULT_SERVER_HOST}:8200"
plugin_directory = "/vault/plugins"

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_cert_file = "/vault/tls/tls-cert.pem"
  tls_key_file = "/vault/tls/tls-key.pem"
}

storage "gcs" {
  bucket      = "${VAULT_SERVER_STORAGE}"
  ha_enabled  = "true"
}

seal "gcpckms" {
  project     = "${GCP_PROJECT}"
  region      = "${KMS_LOCATION}"
  key_ring    = "${KMS_KEYRING}"
  crypto_key  = "${KMS_KEY}"
}
EOF

Server Dockerfile

Now, to put it all together, you will create a Dockerfile to set up the image and then run the startup script.

This Dockerfile expects that the Anjuna Policy Manager (APM) v3.0+ software archive is present in apm-on-gcp/vault. You can download the APM from the Anjuna Resource Center.

Create a file named apm-on-gcp/vault/Dockerfile with the following content:

# Ubuntu 24.04
FROM ubuntu@sha256:a4453623f2f8319cfff65c43da9be80fe83b1a7ce689579b475867d69495b782

# Install Anjuna Policy Manager
COPY anjuna-policy-manager.*.tar.gz /tmp/apm/anjuna-policy-manager.tar.gz
RUN tar -C /tmp/apm -xf /tmp/apm/anjuna-policy-manager.tar.gz
RUN rm /tmp/apm/anjuna-policy-manager.tar.gz

FROM ubuntu@sha256:a4453623f2f8319cfff65c43da9be80fe83b1a7ce689579b475867d69495b782

ARG VAULT_VERSION=1.21.1

# Install Vault
RUN apt-get update && apt-get install -y wget unzip
RUN wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip && \
    unzip vault_${VAULT_VERSION}_linux_amd64.zip -d /usr/local/bin/ && \
    rm vault_${VAULT_VERSION}_linux_amd64.zip

# Install gcloud-cli
RUN apt -y install gnupg
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
RUN wget -q -O- https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
RUN apt update && apt -y install google-cloud-cli=529.0.0-0

# Copy the APM artifacts from the previous stage
COPY --from=0 /tmp/apm/bin/anjuna-policy-manager-plugin /vault/plugins/anjuna-policy-manager-plugin

# Copy APM config file and start script
COPY config.hcl /vault/config/config.hcl
COPY start.sh /vault/start.sh
RUN chmod +x /vault/start.sh

# Create directory for certs
RUN mkdir -p /vault/tls

CMD /vault/start.sh

Build server Docker image

The Vault server Docker image can now be built with the following command executed in the apm-on-gcp directory:

$ docker build -t apm-on-gcp-vault-server ./vault

Build the Anjuna Confidential Container image

The Anjuna Confidential Container image is created from the Vault server docker image and uploaded to the cloud using the Anjuna CLI (anjuna-gcp-cli).

Build Vault server disk image

To build the Vault server disk image, run the following command from within the top level apm-on-gcp directory:

$ anjuna-gcp-cli disk create \
    --disk-size 4GB \
    --disk server-disk.raw \
    --docker-uri apm-on-gcp-vault-server

Create a custom image

To upload the server disk image to Google Cloud and create a custom image, run the following command from within the top level apm-on-gcp directory:

$ anjuna-gcp-cli disk upload \
    --disk server-disk.raw \
    --bucket "${VAULT_SERVER_BUCKET}" \
    --image "${VAULT_SERVER_IMAGE}" \
    --project "${GCP_PROJECT}"