Skip to content
Open
Show file tree
Hide file tree
Changes from 88 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
1a5744e
Update user to paveliak
paveliak Sep 3, 2025
6331e29
Let paveliak in
paveliak Sep 3, 2025
281a443
Update VM image in build script
paveliak Sep 3, 2025
5264ac2
Do not delete VM
paveliak Sep 3, 2025
c59f3e4
Trying to fix scripts
paveliak Sep 3, 2025
ac1bdfd
Adding retries
paveliak Sep 3, 2025
d09bb94
Add retry mechanism for VM connection check
paveliak Sep 3, 2025
e6e0d74
Fix script path for building VM image
paveliak Sep 3, 2025
b41526b
List files in build-azure directory
paveliak Sep 3, 2025
838f6b6
Uncomment VM deletion and cleanup commands
paveliak Sep 3, 2025
3691570
Update build-linux-vm.sh
paveliak Sep 3, 2025
b32af82
Create temporary directory for kernel files
paveliak Sep 3, 2025
15e747d
Update SCP command to fetch image from scripts directory
paveliak Sep 3, 2025
573fc88
Update image.yml to add attestations permission
paveliak Sep 3, 2025
a033a90
Refactor TMP_DRIVE_PATH handling in build script
paveliak Sep 4, 2025
ccd871a
Cleanup
paveliak Sep 4, 2025
bfae8d2
Cleanup
paveliak Sep 4, 2025
841c105
Update test-buildenv-l1-container.yml
paveliak Sep 4, 2025
9fbb5a1
Add workflow_dispatch trigger to buildenv workflow
paveliak Sep 5, 2025
f692166
Update upload-artifact action to v4.6.2
paveliak Sep 5, 2025
41e45e8
Change action reference for image attestation
paveliak Sep 5, 2025
d8cbae5
Add ls command to list /tmp directory contents
paveliak Sep 5, 2025
2015bd7
Create Azure Shared Image Gallery and image definition
paveliak Sep 9, 2025
ee369b1
Update build.sh
paveliak Sep 9, 2025
8b0e1e4
Fix variable assignments in build script
paveliak Sep 9, 2025
5687058
Fix syntax errors in build script for Azure VM
paveliak Sep 9, 2025
f21a657
Add IMAGE_VERSION to Azure workflow
paveliak Sep 9, 2025
c2ef7b4
Add Azure gallery and image definition to workflow
paveliak Sep 9, 2025
69d2ce8
Update Azure gallery and image definition variables
paveliak Sep 9, 2025
09c38d9
Update image.yml
paveliak Sep 9, 2025
0421723
Comment out VM deletion in cleanup function
paveliak Sep 9, 2025
d8e6329
Update build-linux-vm.sh
paveliak Sep 9, 2025
b58e472
Update initramfs after creating tarball
paveliak Sep 9, 2025
9c85d2b
Add patch-mode option to build script
paveliak Sep 10, 2025
a3d919c
Change patch mode from Manual to ImageDefault
paveliak Sep 11, 2025
700b9f6
Modify VM creation to detach OS disk and add builder VM
paveliak Sep 12, 2025
d14c26d
Add create-vm.sh with TODO comment
paveliak Sep 12, 2025
33a9ec7
Update create-vm.sh
paveliak Sep 12, 2025
91aedbb
Store verity hashes in the partition
paveliak Sep 15, 2025
91eca6a
troubleshoot scripts
paveliak Sep 15, 2025
5ba6e0b
troubleshoot scripts
paveliak Sep 15, 2025
f0f62ed
troubleshoot scripts
paveliak Sep 15, 2025
835bcb6
troubleshoot scripts
paveliak Sep 15, 2025
7382339
troubleshoot scripts
paveliak Sep 15, 2025
9451c5a
troubleshoot scripts
paveliak Sep 15, 2025
7e537e3
troubleshoot scripts
paveliak Sep 15, 2025
29f4226
Cleanup
paveliak Sep 15, 2025
9833491
Cleanup
paveliak Sep 16, 2025
2ae8eb9
RootFS is measured by a different VM
paveliak Sep 16, 2025
e6e6920
Create image version
paveliak Sep 16, 2025
6cfff52
Adding placeholder files for attesting
paveliak Sep 16, 2025
a689ddb
Setup SSH
paveliak Sep 16, 2025
0258fe1
Fixed specialized VM creation
paveliak Sep 16, 2025
be7cc68
Troublshooting hash preservation
paveliak Sep 20, 2025
3071a14
Store verity config on the proper disk
paveliak Sep 20, 2025
2dd2981
Removed redundant code
paveliak Sep 20, 2025
114113c
Do not specify AZURE_VM_USER in CI
paveliak Sep 20, 2025
a6d60f6
Do not specify AZURE_VM_USER in CI
paveliak Sep 20, 2025
f08f7bf
Reading verity config from files
paveliak Sep 21, 2025
a660086
Enable initramfs
paveliak Sep 21, 2025
a22c982
Premount EFI partition
paveliak Sep 21, 2025
9ec30de
Removing ls that fails the script
paveliak Sep 21, 2025
02c5356
Enable boot diagnostics for the VM
paveliak Sep 21, 2025
24a8f52
Temporarily disable creation of verity device
paveliak Sep 21, 2025
0874e93
Debugging verity, adding verification step
paveliak Sep 21, 2025
cea8cee
Do not mount temporary drive (will be used for overlay)
paveliak Sep 22, 2025
21a0919
Configure overlay device on /dev/sdb1
paveliak Sep 22, 2025
7ba15d8
Remove temporary code
paveliak Sep 22, 2025
44dc4ae
Actually do not remove temporary code yet
paveliak Sep 22, 2025
ae15c25
Halt if verity verification failed
paveliak Sep 22, 2025
51838a2
Swap OS disk
paveliak Sep 22, 2025
4849b2f
Troubleshooting scripts
paveliak Sep 22, 2025
b3a8e5f
Troubleshooting scripts
paveliak Sep 22, 2025
71eaa26
Troubleshooting scripts
paveliak Sep 22, 2025
d44ec4f
Side by side verification
paveliak Sep 22, 2025
902d98e
Side by side verification
paveliak Sep 22, 2025
2dd473a
Disable grubenv
paveliak Sep 23, 2025
55d77a9
Set GRUB_RECORDFAIL_TIMEOUT=0
paveliak Sep 23, 2025
42ac094
Delete grubenv
paveliak Sep 23, 2025
45af771
Double check that it works now
paveliak Sep 23, 2025
5d293cc
Disabling temporary debugging code
paveliak Sep 23, 2025
96685c6
Updated readme
paveliak Sep 23, 2025
376b103
Adding debug scripts for the overlay
paveliak Sep 23, 2025
17c5e9c
More debugging
paveliak Sep 23, 2025
c444515
Debug overlay
paveliak Sep 23, 2025
c476dda
Trying one more time
paveliak Sep 24, 2025
b3d08bd
Code cleanup
paveliak Sep 24, 2025
7a3389b
Updated readme with the Image Configuration details
paveliak Sep 30, 2025
8941a45
Apply suggestion from @marcelamelara
paveliak Oct 13, 2025
e2a611a
Remove ls command from action.yml
paveliak Oct 13, 2025
b383aee
Added text about trusting Image and Hasher VMs
paveliak Oct 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/actions/attest-ref-values/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ runs:
run: |
scripts/gen-ref-values.sh ${{ inputs.reference-path }}

- run: ls -al /tmp

- name: Save the signed Sigstore bundles
id: upload
if: ${{ inputs.save == 'true' }}
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: '/tmp/${{ inputs.reference-path }}/*.scai.sigstore.json'
retention-days: 15
52 changes: 49 additions & 3 deletions .github/workflows/image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ on:
permissions:
id-token: write
contents: write
attestations: write
packages: write
jobs:
image:
if: github.actor == 'chkimes'
prep:
runs-on: ubuntu-latest

steps:
Expand All @@ -26,6 +27,26 @@ jobs:
go get ./...
go build -o ../build-azure ./...

- name: Upload image attestation tool
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: image-attestation
path: build-azure/image-attestation

image:
needs: prep
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4

- name: Download image attestation tool
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: image-attestation
path: build-azure

- name: Login to Azure
uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2
with:
Expand All @@ -39,6 +60,7 @@ jobs:
AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
AZURE_LOCATION: ${{ secrets.AZURE_LOCATION }}
AZURE_VM_NAME: ${{ secrets.AZURE_VM_NAME }}
SSH_KEYS_URL: https://github.com/${{ github.actor }}.keys
run: |
set -e

Expand All @@ -54,7 +76,31 @@ jobs:
path: img/*

- name: Generate provenance
uses: github-early-access/generate-build-provenance@5fb744556d7e95958990349de0ddb84909c219bb #main
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a #v3
with:
subject-path: img/*

attest:
needs: [prep, image]
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4

- name: Login to Azure
uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Attesting Azure VM
env:
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
AZURE_VM_NAME: ${{ secrets.AZURE_VM_NAME }}
run: |
set -e

build-azure/attest.sh
1 change: 1 addition & 0 deletions .github/workflows/test-buildenv-l1-container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name: Test for BuildEnv L1 container build

on:
workflow_dispatch:
push:
branches:
- main
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/test-buildenv-l2-container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name: Test for BuildEnv L2 container build

on:
workflow_dispatch:
push:
branches:
- main
Expand Down Expand Up @@ -34,7 +35,7 @@ jobs:
# kernel, build platform client, build executor, and root filesystem.
- name: Attest container reference values
id: ref-values
uses: chkimes/image-attestation/.github/actions/attest-ref-values@main
uses: ./.github/actions/attest-ref-values
with:
reference-path: 'build-container/*'

Expand Down
48 changes: 36 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,50 @@ This is a proof-of-concept for the OpenSSF SLSA draft
[Attested Build Environments (BuildEnv) track](https://github.com/slsa-framework/slsa/issues/975).

The CLI in this repo implements vTPM-based attestation and
integrity checking of a Linux VM image. This repo also provides
integrity checking of a Linux VM image running in Azure. This repo also provides
demo GHA workflows showcasing how to meet SLSA BuildEnv L1 and L2 (WIP).

This Demo uses 2 VMs - `ImageVM` and `HasherVM`.
- `ImageVM` is used to build the target image, it could be populated with all the tools and data needed
- `HasherVM` is a "worker" VM whose sole purpose is to compute Verity tree over the ImageVM root FS.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me think that the HasherVM is "more trusted" than the ImageVM. We may want to note a basic trust model for these VMs here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they are about the same from the trust perspective. HasherVM does not validate the data it hashes. But it has abilities to modify the data produced by the ImageVM. A de-risking approach here could be to put verity hashes on a separate disk and then we could attach data disk as a read-only divice to the HasherVM.

But that seems to unnecessarily complicate things from the distribution perspective because now image provider would have to distribute two images.

I will mention trust relationships in the doc

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added text about trusting VMs.

@marcelamelara the challenging part is L3. If BuildProvider has BuildEnv L3 level then it should be running ImageVM and HasherVM as confidential VMs encrypting the disk. However, the image itself should not be encrypted. And then the question is how do we generate Verity hashes for the encrypted disk like if it was not encrypted?

One solution that comes into my mind is that HasherVM:

  1. creates a non-encrypted block file on the encrypted disk
  2. does block copy of all the ImageVM data into the block file
  3. computes verity hashes for the block file
  4. creates azure disk (or whatever cloud object) from the image

In other words we need to operate with a logical disk on the encrypted physical disk.


```mermaid
graph LR;
ImageVM-- root FS disk -->ImageDisk;
HasherVM-- computes hashes -->ImageDisk;
```

Once `HasherVM` completes setting up `ImageDisk` it could be snapshotted to create clones of the `ImageVM`.

## Image configuration

Image has 3 notable partitions - `boot`, `root file system` and `verity tree`. Verity tree contains hashes for the root file system. Verity configuration data (e.g., root hash) is passed in a well-known configuration file within the boot partition. This file is processed by `initrd` to properly initialize (i.e. open) Verity device. Root hash is measured into TPM and hence is present in the remote attestation quote.

Initrd sets up OverlayFS for the root file system using local ephemeral disk as a storage device. Build environments are ephemeral at `Build L3` and intermediate data is not expected to be preserved upon the termination of the environment. To achieve `BuildEnv L3` temporary storage must be encrypted, which could be done with an ephemeral key generated in Initrd upon booting the environment. `BuildEnv L2` does not require encryption.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to enforce in the demo that the storage must be encrypted at L3? I thought we took that out of the specification.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has to be encrypted at L3. Because otherwise host-based malware may tamper with the temporary data (and all build artifacts will be there). I do not think it's a big deal to encrypt temporary drive because it's ephemeral and so there is no need in managing keys. And confidential VM will make sure that keys in memory are protected from the malicious host.


GRUB environment block is disabled to prevent unintended modificaton of the root file system upon booting.

## How To Use

### Generate the initramfs
### Configure Azure account

From a fresh Ubuntu 20+ VM, install the initramfs scripts:
```
sudo initramfs/install.sh
```
_You need to have Azure account to run this demo_

Generate the initramfs:
```
sudo mkinitramfs -o image-attestation.img
```
Few configuration settings need to be defined in [Actions secrets](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets). None of these are secrets per se but they are treated as secrets to reduce visibility of private resources in public Actions workflow logs:
- `AZURE_SUBSCRIPTION_ID` - Azure subscription id that you have `Owner` access to
- `AZURE_RESOURCE_GROUP` - resource group name where VM and all associated resources are provisioned
- `AZURE_TENANT_ID` - Azure Entra tenant id where App is located
- `AZURE_CLIENT_ID` - Azure app id for accessing subscription from the Actions workflow (**MUST** have `Contributor` access to the subscription)
- `AZURE_LOCATION` - location where VM is provisioned (e.g. `eastus`)
- `AZURE_VM_NAME` - Name to be used for the VM

You need to configure OIDC credentials for the app to let Actions workflow acquire access token for this app ([doc link](https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-azure)).

### Dispath the workflow

### Update GRUB
Dispatch `Image Build` workflow to run this demo. Workflow will build a VM and give you access to this VM by adding GitHub actor public keys into the authorized keys for the `azureuser`. Keys are downloaded from `https://github.com/<your alias>.keys`

TODO
After the VM is built you will be able to SSH to the VM with `ssh azureuser@<ip address>` and poke around.

### CLI

Expand Down
6 changes: 6 additions & 0 deletions build-azure/attest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

set -e

echo "Attesting VM..."
#TODO
82 changes: 50 additions & 32 deletions build-azure/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,61 @@
set -e

SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P )"
VM_USER="${AZURE_VM_USER:-azureuser}"

if ! [ -f ~/.ssh/id_rsa ]; then
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""
fi

echo "Creating resource group..."
az account set --subscription $AZURE_SUBSCRIPTION_ID
az group create --resource-group $AZURE_RESOURCE_GROUP --location $AZURE_LOCATION

echo "Creating VM..."
az vm create --resource-group $AZURE_RESOURCE_GROUP \
--name $AZURE_VM_NAME \
--image Canonical:0001-com-ubuntu-minimal-mantic:minimal-23_10-gen2:23.10.202402260 \
--size Standard_D4ds_v5 \
--admin-username azureuser \
--ssh-key-value ~/.ssh/id_rsa.pub \
--security-type TrustedLaunch \
--nic-delete-option delete \
--os-disk-delete-option delete \
| tee create.log

cleanup() {
echo "Cleaning up..."
az vm delete --resource-group $AZURE_RESOURCE_GROUP --name $AZURE_VM_NAME --yes
rm -f create.log
}

trap 'cleanup' EXIT

IP_ADDR=$(cat create.log | jq -r .publicIpAddress | tail -n 1)
echo "VM created with IP address: $IP_ADDR"
echo "Creating image VM..."
IMAGE_VM_NAME="${AZURE_VM_NAME}"
$SCRIPTPATH/create-vm $IMAGE_VM_NAME
IMAGE_VM_ID=$(az vm show --resource-group $AZURE_RESOURCE_GROUP --name $IMAGE_VM_NAME | jq -r ".id")
IP_ADDR=$($SCRIPTPATH/get-ip $IMAGE_VM_ID)
$SCRIPTPATH/test-connectivity $IP_ADDR

echo "Copying files to VM..."
scp -r -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/../initramfs" azureuser@$IP_ADDR:
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/build-vm.sh" azureuser@$IP_ADDR:
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/client" azureuser@$IP_ADDR:
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/server" azureuser@$IP_ADDR:
scp -r -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/../initramfs" "${VM_USER}@${IP_ADDR}":
scp -r -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/../scripts" "${VM_USER}@${IP_ADDR}":
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/image-attestation" "${VM_USER}@${IP_ADDR}":

echo "Building VM image..."
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa azureuser@$IP_ADDR "sudo ../scripts/build-linux-vm.sh"
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa azureuser@$IP_ADDR:~/image.tar.gz .
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "${VM_USER}@${IP_ADDR}" "sudo SSH_KEYS_URL=$SSH_KEYS_URL scripts/build-linux-vm.sh"
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "${VM_USER}@${IP_ADDR}":~/scripts/image.tar.gz .

echo "Deallocating image VM..."
az vm deallocate --id $IMAGE_VM_ID

echo "Detachinging OS disk..."
DISK_ID=$(az vm show --id $IMAGE_VM_ID | jq -r ".storageProfile.osDisk.managedDisk.id")
IMAGE_ID=$(az disk show --id $DISK_ID | jq -r ".creationData.imageReference.id")
SWAP_DISK_NAME="${AZURE_VM_NAME}-$(openssl rand -base64 12 | tr -dc 'A-Za-z0-9' | head -c 16 ; echo)"
az disk create --image-reference $IMAGE_ID --resource-group $AZURE_RESOURCE_GROUP --name $SWAP_DISK_NAME --security-type TrustedLaunch
SWAP_DISK_ID=$(az disk show --resource-group $AZURE_RESOURCE_GROUP --name $SWAP_DISK_NAME | jq -r ".id")
az vm update --name $IMAGE_VM_NAME --resource-group $AZURE_RESOURCE_GROUP --os-disk $SWAP_DISK_ID

echo "Creating hasher VM..."
HASHER_VM_NAME="${AZURE_VM_NAME}hash"
$SCRIPTPATH/create-vm $HASHER_VM_NAME
HASHER_VM_ID=$(az vm show --resource-group $AZURE_RESOURCE_GROUP --name $HASHER_VM_NAME | jq -r ".id")
IP_ADDR=$($SCRIPTPATH/get-ip $HASHER_VM_ID)
$SCRIPTPATH/test-connectivity $IP_ADDR

echo "Attaching image disk (with 10% added space for verity hashes)..."
DISK_SIZE=$(az disk show --id $DISK_ID --query "diskSizeGB")
NEW_DISK_SIZE=$(echo "$DISK_SIZE * 1.1" | bc)
NEW_DISK_SIZE=$(printf "%.0f" "$NEW_DISK_SIZE")
az disk update --id $DISK_ID --disk-size-gb $NEW_DISK_SIZE
az vm disk attach --resource-group $AZURE_RESOURCE_GROUP --vm-name $HASHER_VM_NAME --disk-id $DISK_ID --lun 0

echo "Setting up Verity..."
scp -r -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "$SCRIPTPATH/../scripts" "${VM_USER}@${IP_ADDR}":
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "${VM_USER}@${IP_ADDR}" "sudo scripts/rootfs-prepare-verity.sh"
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "${VM_USER}@${IP_ADDR}" "sudo scripts/rootfs-measure-verity.sh"

echo "Deleting hasher VM..."
az vm delete --id $HASHER_VM_ID --yes

echo "Attaching OS disk back..."
az vm update --name $IMAGE_VM_NAME --resource-group $AZURE_RESOURCE_GROUP --os-disk $DISK_ID
az disk delete --id $SWAP_DISK_ID --yes
24 changes: 24 additions & 0 deletions build-azure/create-vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

set -e

VM_NAME=$1
VM_USER=${AZURE_VM_USER:-azureuser}

if ! [ -f ~/.ssh/id_rsa ]; then
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""
fi

az vm create --resource-group $AZURE_RESOURCE_GROUP \
--name $VM_NAME \
--image "Canonical:0001-com-ubuntu-server-jammy:22_04-lts-gen2:latest" \
--admin-username $VM_USER \
--ssh-key-value ~/.ssh/id_rsa.pub \
--size Standard_D4ds_v5 \
--security-type TrustedLaunch \
--nic-delete-option delete \
--os-disk-delete-option delete \
--patch-mode ImageDefault

az vm boot-diagnostics enable --resource-group $AZURE_RESOURCE_GROUP \
--name $VM_NAME
11 changes: 11 additions & 0 deletions build-azure/get-ip
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

set -e

VM_RESOURCE=$1

NIC_RESOURCE=$(az vm show --id $VM_RESOURCE | jq -r ".networkProfile.networkInterfaces[0].id")
IP_RESOURCE=$(az network nic show --id $NIC_RESOURCE | jq -r ".ipConfigurations[0].publicIPAddress.id")
IP_ADDR=$(az network public-ip show --id $IP_RESOURCE | jq -r ".ipAddress")

echo $IP_ADDR
24 changes: 24 additions & 0 deletions build-azure/test-connectivity
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

set -e

IP_ADDR=$1
VM_USER="${AZURE_VM_USER:-azureuser}"

echo "Making sure we can connect to the VM using IP $IP_ADDR..."
MAX_RETRIES=10
RETRY_DELAY=10
count=0
while [ $count -lt $MAX_RETRIES ]; do
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa "${VM_USER}@${IP_ADDR}" "uname -a" && break
count=$((count + 1))
echo "Retry $count/$MAX_RETRIES failed. Waiting $RETRY_DELAY seconds before next attempt..."
sleep $RETRY_DELAY
done

if [ $count -eq $MAX_RETRIES ]; then
echo "All $MAX_RETRIES attempts failed."
exit 1
fi

echo "$IP_ADDR is reachable for SSH!"
Loading