Build an Anjuna Confidential Pod image

If you have not already done so, follow the guide Example 1 - Deploy Nginx as an Anjuna Confidential Pod in AKS. It goes into more detail on the process of building Anjuna Confidential Pod images.

In this example, you will build a custom application from scratch that uses some of the features of the Anjuna Enclave Configuration File.

Build a container

Start by building a simple Docker container. First, cd into a new temporary directory.

$ cd $(mktemp -d)

Then, run the following command to create the Dockerfile, which defines an image that prints the environment using the env command:

cat > Dockerfile <<EOF
FROM ubuntu:22.04

CMD bash -c "env && sleep infinity"
EOF

In this example, the container image is hosted in the Azure Container Registry, which was provisioned by the Terraform modules for shared resources. You can use any registry as long as you can push images to it, and the cluster has access to pull images from it.

$ export CONTAINER_IMAGE="${AZURE_REGISTRY_NAME}.azurecr.io/env"
$ docker build . -t "${CONTAINER_IMAGE}"
$ docker push "${CONTAINER_IMAGE}"

Build the Anjuna Confidential Pod image

Building an Anjuna Confidential Pod image builds and measures a VM disk image that contains your target application. Creating and storing VM disks in Azure requires a few extra resources, such as a storage container, an image definition, and an image version. The following sections will guide you step by step in this process.

Before creating the needed resources, generate a random suffix that will be used to ensure that resource names are unique. It also helps to quickly identify related resources (i.e., if they share the same suffix):

$ export SUFFIX="${RANDOM}"

Create a storage container

Before building the Anjuna Confidential Pod image, create a storage container to store the measured disk image.

$ export AZURE_STORAGE_CONTAINER="env-${SUFFIX}"
$ az storage container create \
  --name "${AZURE_STORAGE_CONTAINER}" \
  --account-name "${AZURE_STORAGE_ACC_NAME}" \
  --resource-group "${AZURE_RESOURCE_GROUP}"

Create an image definition

Create a new image definition within a Shared Image Gallery. The commands below create a new image definition for your Anjuna Confidential Pod image.

$ export AZURE_IMAGE_DEFINITION="env-${SUFFIX}"
$ az sig image-definition create \
  --resource-group "${AZURE_RESOURCE_GROUP}" \
  --gallery-name "${AZURE_GALLERY_NAME}" \
  --gallery-image-definition "${AZURE_IMAGE_DEFINITION}" \
  --publisher Anjuna \
  --offer CVMGA \
  --os-type Linux \
  --sku AnjGALinuxEnv \
  --os-state specialized \
  --features SecurityType=ConfidentialVMSupported \
  --hyper-v-generation V2 \
  --architecture x64

Every time you build and upload a measured VM disk for this image definition, a new "version" of the image definition will be created.

Build and upload the Anjuna Confidential Pod image

Before building the Anjuna Confidential Pod image, create an enclave configuration file.

The configuration file enclave-config.yaml below does two things:

  • It sets the value of the environment variable DB_USERNAME to user

  • It allows the environment variable LOG_LEVEL to be set in the Pod specification

Refer to Configuration reference to learn more about the enclave configuration file and all the features that it supports.

$ cd "${WORKSPACE}"
cat > enclave-config.yaml <<EOF
version: 1.8

environment:
- DB_USERNAME=user

untrustedConfig:
  envVars:
    allow:
    - LOG_LEVEL
EOF

To build the Anjuna Confidential Pod image, run the following command:

In the command below, you must always specify the fully-qualified container image reference, i.e., including the registry, the repository, and a tag, as in <registry>/<repository>:<tag>.
$ docker load -i ${WORKSPACE}/anjuna-k8s-sev-services-image.tar
$ ./anjuna-k8s-cli/anjuna-k8s-cli build azure \
  --docker-uri "${CONTAINER_IMAGE}:latest" \
  --disk-size 2G \
  --config enclave-config.yaml

Upload your Confidential VM disk to Azure to create a new image version (0.0.1) for the image definition that you created earlier.

$ anjuna-azure-cli disk upload \
  --disk disk.vhd \
  --image-name env-disk.vhd \
  --storage-account "${AZURE_STORAGE_ACC_NAME}" \
  --storage-container "${AZURE_STORAGE_CONTAINER}" \
  --resource-group "${AZURE_RESOURCE_GROUP}" \
  --image-gallery "${AZURE_GALLERY_NAME}" \
  --image-definition "${AZURE_IMAGE_DEFINITION}" \
  --image-version 0.0.1 \
  --location "${AZURE_LOCATION}" \
  --subscription-id "${AZURE_SUBSCRIPTION}"

Finally, retrieve the image ID, which will be used in your Pod specification when deploying the confidential workload to Kubernetes.

$ export AZURE_IMAGE_ID=$(az sig image-version show \
   -i "${AZURE_IMAGE_DEFINITION}" \
   -e 0.0.1 \
   -r "${AZURE_GALLERY_NAME}" \
   -g "${AZURE_RESOURCE_GROUP}" \
   --subscription "${AZURE_SUBSCRIPTION_ID}" \
   --query id | tr -d '"')

Once you have the image ID exported to your environment, you are ready to deploy your application as an Anjuna Confidential Pod, as shown in the next section of this guide.