Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

src/backends/azure.rs

audience: ai

Azure Virtual Machines backend via ARM. Operator supplies a service principal (tenant_id + client_id + client_secret) scoped to a specific resource group the bridge is permitted to mutate.

Reports tdx_capable = true when [azure.tdx_vm_sizes] is non-empty. Azure’s Confidential Computing v3 family (Standard_DC*ds_v3, Standard_EC*ds_v3) exposes Intel TDX; grants with manifest.tdx = Required provision into those SKUs with security_profile.security_type = ConfidentialVM. Other grants use the broader vm_sizes list.

//! Azure Virtual Machines backend.
//!
//! Uses the Azure Resource Manager SDK via
//! `azure_mgmt_compute`. Operator supplies a service
//! principal (tenant id + client id + client secret) or
//! a managed identity, scoped to a resource group the
//! bridge is permitted to mutate.
//!
//! Azure's Confidential Computing v3 instance family
//! (`Standard_DCdsv3_*`, `Standard_ECdsv3_*`) exposes
//! Intel TDX. Operators list TDX-enabled SKUs in
//! `[azure.tdx_vm_sizes]` to mark this backend as
//! `tdx_capable`.

use anyhow::{anyhow, Context};
use async_trait::async_trait;
use coalition_compute::{AlmanacTick, ComputeGrant, UsageMetrics};

use crate::backends::{Backend, Capabilities, ProvisionedInstance};
use crate::config::AzureBootConfig;
use crate::zipnet_io::Envelope;

pub struct AzureBackend {
    cfg: AzureBootConfig,
    // TODO: cache azure_mgmt_compute Client, resolved per
    // subscription + resource group.
}

impl AzureBackend {
    pub async fn new(cfg: &AzureBootConfig) -> anyhow::Result<Self> {
        Ok(Self { cfg: cfg.clone() })
    }
}

#[async_trait]
impl Backend for AzureBackend {
    fn name(&self) -> &'static str { "azure" }

    async fn capabilities(&self) -> anyhow::Result<Capabilities> {
        Ok(Capabilities {
            regions: self.cfg.regions.clone(),
            tdx_capable: !self.cfg.tdx_vm_sizes.is_empty(),
            max_cpu_millicores: u32::MAX,
            max_ram_mib: u32::MAX,
        })
    }

    fn can_satisfy(&self, grant: &ComputeGrant<'_>) -> bool {
        let _ = grant;
        true
    }

    async fn provision(
        &self,
        grant: &ComputeGrant<'_>,
        envelope: &Envelope,
    ) -> anyhow::Result<ProvisionedInstance> {
        // Real flow (ARM API):
        //   1. Resolve target region.
        //   2. Pick VM SKU. TDX grants → tdx_vm_sizes.
        //   3. Create a per-grant ssh public key resource.
        //   4. virtual_machines.create_or_update({
        //          location, hardware_profile: {vm_size},
        //          storage_profile: {image_reference, os_disk},
        //          os_profile: {admin_username, linux_configuration.ssh.public_keys},
        //          network_profile,
        //          security_profile: {security_type: ConfidentialVM, ...} if TDX,
        //      })
        //   5. Poll provisioning_state == Succeeded.
        //   6. Read the allocated public IP, return ProvisionedInstance.
        let _ = (grant, envelope);
        Err(anyhow!(
            "AzureBackend::provision is a prototype stub; implement via \
             azure_mgmt_compute::virtual_machines::Client"
        ))
    }

    async fn watch_until_exit(
        &self,
        instance: &ProvisionedInstance,
        valid_to: AlmanacTick,
    ) -> anyhow::Result<UsageMetrics> {
        let _ = (instance, valid_to);
        Err(anyhow!(
            "AzureBackend::watch_until_exit is a prototype stub"
        ))
    }

    async fn terminate(&self, instance: &ProvisionedInstance) -> anyhow::Result<()> {
        let _ = instance;
        Ok(())
    }
}

Up: compute-bridgebackends.