> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensor9.com/llms.txt
> Use this file to discover all available pages before exploring further.

# EC2

> EC2 APIs with Cloud Adapter.

This page describes how EC2 maps to services in the environment where the application runs, including backend choices, supported operations and service-specific behavior.

## Supported environments

* Akamai
* Azure
* DigitalOcean
* Google Cloud
* OCI
* Private Kubernetes
* Scaleway

Check the operation and capability tables for the behavior your application depends on. A supported environment does not imply that every operation of the origin service is available.

## How the backends compare

Each row compares a capability of EC2 with its adaptation on each backend.
A dash means this profile does not state the capability for that backend.

### Cloud Adapter

| Capability | EC2 | Akamai and Private Kubernetes | Azure | DigitalOcean | Google Cloud | OCI | Scaleway |
| - | - | - | - | - | - | - | - |
| General purpose · M-series | m7i / m6i / m8g | VM on a general-purpose node pool | Dsv5 / Dsv6 (Intel) · Dasv5 (AMD) | General-Purpose Droplet (dedicated) | n2 / n2d / n4 / c4 | VM.Standard3.Flex / E5.Flex | PRO2 (the production workhorse line) |
| Burstable · T-series | t3 / t4g | VM with CPU requests below limits; no EC2 credit model | B-series (Bsv2) | Basic / Premium (shared-core) | e2 | - (A1.Flex, no credit-burst) | STARDUST1 / PLAY2 (cost-optimised, small end) |
| Compute optimized · C-series | c7i / c6i / c7g | VM on a high-clock node pool | Fsv2 / FX | CPU-Optimized Droplet | c2 / c2d / c3 / c3d / h3 | VM.Optimized3.Flex | PRO2 |
| Memory optimized · R-series | r7i / r6i / r8g | VM on a high-memory node pool | Esv5 / Easv5 / Esv6 | Memory-Optimized Droplet | m1 / m3 / n2-highmem | E5.Flex at high GB/OCPU | GP1 (higher memory-per-core at the top end) |
| High-memory · X / U-series (multi-TB) | x2iedn / u-\* | VM on a large-memory / bare-metal node | M-series / Mv3 (to \~30 TB) | - | m3-ultramem / x4 (to 32 TB) | BM.Standard.E5 / extended-memory | - (GP1-XL, 256 GiB, is the ceiling) |
| Storage optimized · I / D-series | i4i / i7ie / d3 | VM on a node with local NVMe + a PV | Lsv3 (local NVMe) | Storage-Optimized Droplet (NVMe) | z3 (local SSD) | VM.DenseIO.E5 (local NVMe) | DEV1 / GP1 (bundled local storage) |
| Accelerated: GPU · P / G-series | p5 / p4d / g6 | VM with GPU passthrough / vGPU | ND H100 v5 / NC A100 v4 / NV (A10) | GPU Droplet (H100 / MI300X), 99% SLA | a3 (H100) / a2 (A100) / g2 (L4) | BM.GPU.H100 / GPU4 (A100) / VM.GPU.A10 / MI300X | RENDER-S (P100), L4-1-24G (L4 24 GB) |
| Accelerated: ML ASIC · Inf / Trn | inf2 / trn1 | - (no ASIC passthrough analog) | - (Maia not GA) | - | Cloud TPU v5e / v6 (separate product) | - | - |
| HPC · Hpc-series | hpc7g / hpc6a | VM on an HPC node pool (RDMA / SR-IOV) | HBv4 / HBv3 / HC | - | h3 / h4d | BM.Optimized3 / BM.HPC.E5 | - |
| Arm / Graviton · cross-class | m7g / c7g / r8g | VM on an arm64 node pool | Dpsv6 (Cobalt 100) | - (x86 only) | c4a (Axion) | A1.Flex (Ampere) | AMP2 (Ampere), C1 through C16 |
| Security groups use native policy · supported in-stack rules | vpc\_security\_group\_ids and in-stack security-group rules | a Kubernetes NetworkPolicy with default-deny and named platform exceptions | an Azure network security group with default-deny and named platform exceptions | a DigitalOcean cloud firewall with default-deny and named platform exceptions | Google Cloud firewall rules with default-deny and named platform exceptions | an OCI network security group with default-deny and named platform exceptions | - |
| Provisioning model · IaC and runtime lifecycle | RunInstances + infrastructure-as-code | KubeVirt infrastructure configuration | Azure Virtual Machines native resources | - | Google Compute Engine native resources | - | - |
| Instance discovery · EC2 response format | DescribeInstances / DescribeVpcs / DescribeSubnets / DescribeSecurityGroups | not served for the calling VM | managed resource state | not available | managed resource state | not available | not available |
| Instance identity · management and metadata | describe APIs + instance metadata | not served | - | - | - | - | - |
| Discovery scope · adapter-managed resources | fleet / cross-account describe | no local or fleet discovery | managed account and fleet | - | managed account and fleet | - | - |
| CPU per-core · host-relative | cloud instance | host node minus a small virtualization overhead | - | - | - | - | - |
| Cost · no separate SKU | per-instance on-demand | the underlying node | - | - | - | - | - |
| Availability · cluster-provided | 99.5% single-instance SLA | the cluster's SLA | - | - | - | - | - |
| API coverage | full | partial | partial | partial | partial | partial | partial |
| Instance identity · management API | describe APIs + instance metadata | - | the management record of each launched instance | - | the management record of each launched instance | - | - |
| Block + local storage | EBS gp3 / io2, instance store | - | Premium / Ultra SSD, Lsv3 local NVMe | - | - | - | - |
| Provisioning model · infrastructure-as-code only | RunInstances + infrastructure-as-code | - | - | DigitalOcean native resources | - | OCI Compute native resources | Scaleway native resources |
| Instance identity · no EC2 record | describe APIs + instance metadata | - | - | the VM's own DigitalOcean identity | - | the VM's own OCI Compute identity | the VM's own Scaleway identity |
| Discovery scope · none | fleet / cross-account describe | - | - | not available | - | not available | not available |
| Match the dedicated tier · not shared-core Basic | m6i (dedicated 2 vCPU) | - | - | General-Purpose Droplet (dedicated) | - | - | - |
| CPU per-core · independent 2026 benchmarks | current-generation silicon | - | - | below EC2 (older fleet) | - | - | - |
| Network throughput + latency | depends on EC2 instance type, size and placement | - | - | - | depends on Compute Engine machine type, size and placement | - | - |
| OCPU sizing model · x86: 1 OCPU = 2 vCPU | 1 vCPU = 1 hyperthread | - | - | - | - | x86: 1 OCPU = 2 vCPU; Flex configures CPU + memory | - |
| A Graviton instance has a real fit · unlike some clouds | Graviton (Arm) | - | - | - | - | - | AMP2 (Ampere) |
| A specific GPU may land on a different one · a known fidelity gap | a P100 instance | - | - | - | - | - | possibly an L4 |
| The instance is NOT placed on the projected Private Network · a reported drop, not a mapping | aws\_instance.subnet\_id | - | - | - | - | - | no private\_network block on scaleway\_instance\_server; the declared placement is reported as dropped |
| Security groups stop the build · any reference, not only in-stack | vpc\_security\_group\_ids (in-stack, computed, or an out-of-stack id), the legacy security\_groups names attribute, or a network\_interface block | - | - | - | - | - | the build STOPS -- no scaleway\_instance\_security\_group is compiled in v1 |
| An Instance is zonal · one zone per Cloud Adapter deployment | an AWS Region with Availability Zones | - | - | - | - | - | a Scaleway zone such as fr-par-1 |

## On Akamai and Private Kubernetes

### KubeVirt VM

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Fleet / cross-resource discovery | Control plane | Out of scope | Full surface | Not supported: the KubeVirt mapping provides no local or fleet EC2 discovery through the EC2 runtime API. |
| RunInstances / TerminateInstances / ModifyInstanceAttribute / CreateTags | Control plane | Out of scope | Full surface | KubeVirt maps VM infrastructure on an existing cluster, not managed lifecycle through these EC2 runtime APIs. Manage the VM through its infrastructure configuration and native cluster controls. |
| Instance provisioning | Instance lifecycle | Supported | Common | your aws\_instance / launch template compiles to a native KubeVirt VirtualMachine: the cheapest size with at least the same vCPUs and memory, CPU architecture and GPU type (the family rules are in the summary) |
| Start / Stop / Reboot / Terminate | Instance lifecycle | Supported | Common | Infrastructure configuration maps to native VM lifecycle controls; this row does not establish runtime EC2 API support. |
| DescribeAvailabilityZones | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeSecurityGroups | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM; native firewall translation does not add an EC2 DescribeSecurityGroups endpoint. |
| DescribeVolumes / DescribeNetworkInterfaces / DescribeTags (the caller's own) | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeVpcs / DescribeSubnets | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. The network describes for the VPC records are on the VPC card. |
| Instance metadata (IMDS) + DescribeInstances (the running instance) | Metadata + discovery | Out of scope | Common | EC2 instance metadata and AWS role credentials are not served inside a compiled VM. Use the target's own metadata service where one is available. A DescribeInstances call from inside a compiled VM is not answered with its own instance, because no Tensor9 endpoint is configured in the guest. |
| Public IP on the instance | Network | Out of scope | Common | a request for a per-instance public IP stops the build; target-native addressing still needs review |
| Security groups on the instance | Network | Partial | Common | supported in-stack rules become native firewall policy with default-deny ingress and egress plus reported platform exceptions. Unknown groups or unreadable ports grant no additional traffic; unresolved settings are reported or refused. |
| Attached data volumes (EBS volumes) | Storage | Partial | Common | supported inline or in-stack attached volumes become empty native disks on an ordinary instance; snapshots, external volumes, multi-attach, count/for\_each instances and launch-template data disks are not supported. Lifecycle and configured performance follow the target's limits. |
| Root volume | Storage | Partial | Common | root settings map within the target's native disk limits; some targets refuse pinned size or type, and no source disk contents are copied |

#### How it works

Your Terraform `aws_instance` compiles to a KubeVirt VirtualMachine that runs under KVM on the Kubernetes cluster you operate. The VM boots the Ubuntu image that matches your AMI's operating system, gets the instance's vCPUs and memory, and runs your user data once at first boot. Your processes run directly in the VM; Tensor9 adds nothing to the compute path.

You run the cluster and its nodes, so the VM's availability, live migration and rescheduling on node drain are the cluster's, and its performance follows the node it runs on. The VM is managed through its infrastructure configuration and native cluster controls, not through EC2 runtime calls.

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cluster the application workload runs on a KubeVirt VirtualMachine under KVM on Kubernetes nodes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2x1c3RlciB0aGUgYXBwbGljYXRpb24gd29ya2xvYWQgcnVucyBvbiBhIEt1YmVWaXJ0IFZpcnR1YWxNYWNoaW5lIHVuZGVyIEtWTSBvbiBLdWJlcm5ldGVzIG5vZGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJlMmt2YWgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj48L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0MCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIzMiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjM2IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMTEiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmEiPllvdXIgd29ya2xvYWQ8L3RleHQ+Cjx0ZXh0IHg9IjExMSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+aW1hZ2U8L3RleHQ+CjxsaW5lIHgxPSIxODYiIHkxPSIxMTEiIHgyPSIyMjQiIHkyPSIxMTEiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2Uya3ZhaCkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSIyMjQiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjI5OSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYSI+QW1hem9uIEVDMjwvdGV4dD4KPHRleHQgeD0iMjk5IiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5pbnN0YW5jZTwvdGV4dD4KPHJlY3QgeD0iNDM2IiB5PSI0MCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NTIiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5JTiBUSEUgVEFSR0VUIENMVVNURVI8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMmt2YWgpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPkt1YmVWaXJ0IFZNPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5kZXIgS1ZNIMK3IHlvdXIgbm9kZXM8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cluster the application workload runs on a KubeVirt VirtualMachine under KVM on Kubernetes nodes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2x1c3RlciB0aGUgYXBwbGljYXRpb24gd29ya2xvYWQgcnVucyBvbiBhIEt1YmVWaXJ0IFZpcnR1YWxNYWNoaW5lIHVuZGVyIEtWTSBvbiBLdWJlcm5ldGVzIG5vZGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJlMmt2YWgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj48L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0MCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIzMiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjM2IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMTEiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1ZjkiPllvdXIgd29ya2xvYWQ8L3RleHQ+Cjx0ZXh0IHg9IjExMSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+aW1hZ2U8L3RleHQ+CjxsaW5lIHgxPSIxODYiIHkxPSIxMTEiIHgyPSIyMjQiIHkyPSIxMTEiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2Uya3ZhaCkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSIyMjQiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjI5OSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOSI+QW1hem9uIEVDMjwvdGV4dD4KPHRleHQgeD0iMjk5IiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5pbnN0YW5jZTwvdGV4dD4KPHJlY3QgeD0iNDM2IiB5PSI0MCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NTIiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5JTiBUSEUgVEFSR0VUIENMVVNURVI8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMmt2YWgpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPkt1YmVWaXJ0IFZNPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5kZXIgS1ZNIMK3IHlvdXIgbm9kZXM8L3RleHQ+Cjwvc3ZnPg==)

Your instance becomes a KubeVirt VirtualMachine under KVM on the cluster you operate.

#### Images, sizing and disks

A `data aws_ami` lookup for Ubuntu 20.04, 22.04 or 24.04 LTS, on x86 or Arm, resolves to the matching Ubuntu container disk (for example `quay.io/containerdisks/ubuntu:22.04`), a bootable cloud image with cloud-init. A custom or opaque AMI requires `t9_kube_boot_image_…`, with no default: supply a pullable containerDisk image containing the converted disk under `/disk/`. Tensor9 does not convert it.

The VM's vCPUs and memory are read straight from the instance type rather than from a size table. The boot disk is an ephemeral, copy-on-write copy of the image, sized by the image. An instance whose `root_block_device` sets a size or type stops the build. IOPS and throughput settings cannot be provisioned independently and are reported; the StorageClass, CSI driver and node determine performance.

* **You must install KubeVirt and the Containerized Data Importer (CDI).** The VM depends on both. The build stops when the deployment has no KubeVirt-capable cluster.
* **You operate the hypervisor.** The VM runs under KVM on your nodes, not on a cloud provider's hosts; you operate the guest software.

#### Launch templates and Auto Scaling fleets

Auto Scaling groups and their launch templates are not translated to KubeVirt VirtualMachinePools by this mapping. Support for a standalone VirtualMachine does not establish a managed fleet or horizontal autoscaler.

If your workload needs a fleet, define and operate the VirtualMachinePool, its replica configuration and any autoscaler separately, or use a target with a supported fleet mapping. Check node capacity, storage and enforced network policy for every member.

#### Limitations

Compute runs natively on your cluster. These are the differences from EC2 to check against your workload:

Where it differs from EC2

* **You must operate the cluster.** Availability, live migration and rescheduling on node drain come from your Kubernetes cluster, not a cloud provider's single-instance SLA, and performance follows the node the VM lands on.
* **The EC2 instance metadata service is not supported.** Nothing answers EC2 metadata requests (IMDSv1 or IMDSv2) at `169.254.169.254` inside the VM, so code that reads its instance ID, region or role credentials from instance metadata gets no answer. No other metadata service answers at that address.
* **The instance's IAM role is not attached to the VM.** The VM gets no Kubernetes ServiceAccount and no AWS credentials from this mapping. A role named with `name_prefix` or a computed name stops the build.
* **EC2 discovery is not supported.** No EC2 endpoint is configured inside the VM, so Describe calls about the calling VM and its attached resources are not answered, and nothing lists a managed account or fleet. EC2 lifecycle calls such as `RunInstances` do not manage this VM.
* **A public IP is not supported.** The VM has an address on the cluster network only. An instance that requests a public IP (`associate_public_ip_address`), or sets it or `vpc_security_group_ids` to a computed value, stops the build.
* **Security groups use the target's own firewall.** Supported rules from groups in the stack are applied to the VM through Kubernetes NetworkPolicy, with default-deny ingress and egress. A named platform rule permits the traffic needed for boot, metadata, DNS and management, and the build reports that exception. Unknown groups and rules whose ports cannot be read are reported and grant no additional traffic. Your cluster's CNI must enforce the generated NetworkPolicies.
* **Root size and type cannot be set separately.** The boot disk is an ephemeral overlay. Pinned size or type stops the build; provisioned IOPS and throughput are reported as unsupported target settings. Data-disk performance follows the StorageClass and CSI driver. The ephemeral root disk cannot honor delete\_on\_termination=false; the build reports it.
* **You must supply the native disk image for a custom AMI.** The required input is a containerDisk image your cluster can pull. No image conversion or data copy is performed.
* **Attached data disks are created empty.** An inline `ebs_block_device`, or an in-stack `aws_ebs_volume` attached to an ordinary instance, becomes CDI DataVolumes. Existing data is never copied. Snapshots, external volumes and multi-attach are not supported. Data disks on an instance using `count` or `for_each`, or in a launch template, stop the build. A computed `delete_on_termination` also stops the build. An inline disk with delete\_on\_termination=true belongs to the VM. Other data disks are separate stack resources: they survive VM replacement but are deleted with the stack.
* **Auto Scaling groups are not supported on this target.** This mapping creates standalone VMs but does not translate the group's launch template, replica count or scaling policy to a VirtualMachinePool. Define and operate the native fleet separately, or use a target with a supported fleet mapping.

#### Other considerations

You operate the cluster and nodes, and Tensor9 runs nothing in the VM's compute path.

* **Before going live.** Install KubeVirt and CDI, then confirm the VM boots and your user data completes. Keep durable data off the boot disk. If your code reads EC2 instance metadata or uses the instance's IAM role, give it another source for its instance details and credentials.
* **When the VM is replaced.** Changing the image, subnet, key pair, availability zone, CPU options, placement or tenancy, root-volume encryption, or user data with `user_data_replace_on_change` replaces the VM. Review image, size and network changes before applying them.
* **Moving from AWS.** The VM starts from a fresh image. Data on the instance's EBS volumes is not copied, so move it separately before cutover.

#### Infrastructure and local discovery

KubeVirt maps VM infrastructure on the existing cluster, not managed lifecycle or discovery through the EC2 runtime API. EC2 instance metadata and EC2 describe calls are not answered for the VM. Use the native cluster and infrastructure configuration to manage and inspect the VM.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

No curated instance comparison is available for this source and target configuration yet.

Compare the published named instance mappings; a free-form EC2 cost calculator is not offered.

## On Azure

### Virtual Machines

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Fleet / cross-resource discovery | Control plane | Partial | Full surface | The management API lists the managed instances it launched or registered, with supported filters and pagination. It does not list VMs compiled from your stack, and it does not enumerate unrelated cloud accounts. |
| RunInstances / TerminateInstances / ModifyInstanceAttribute / CreateTags | Control plane | Partial | Full surface | Maximum adaptation supports bounded instance launch, termination and tagging for adapter-managed resources. ModifyInstanceAttribute covers security-group changes; other attributes and unsupported launch settings are rejected. Creation completes asynchronously on the selected backend. |
| Instance provisioning | Instance lifecycle | Supported | Common | your aws\_instance / launch template compiles to a native Azure Virtual Machine: the cheapest size with at least the same vCPUs and memory, CPU architecture and GPU type (the family rules are in the summary) |
| Start / Stop / Reboot / Terminate | Instance lifecycle | Supported | Common | Infrastructure configuration maps to native VM lifecycle controls; this row does not establish runtime EC2 API support. |
| DescribeAvailabilityZones | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeSecurityGroups | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM; native firewall translation does not add an EC2 DescribeSecurityGroups endpoint. |
| DescribeVolumes / DescribeNetworkInterfaces / DescribeTags (the caller's own) | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeVpcs / DescribeSubnets | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. The network describes for the VPC records are on the VPC card. |
| Instance metadata (IMDS) + DescribeInstances (the running instance) | Metadata + discovery | Out of scope | Common | EC2 instance metadata and AWS role credentials are not served inside a compiled VM. Use the target's own metadata service where one is available. A DescribeInstances call from inside a compiled VM is not answered with its own instance, because no Tensor9 endpoint is configured in the guest. |
| Public IP on the instance | Network | Out of scope | Common | a request for a per-instance public IP stops the build; target-native addressing still needs review |
| Security groups on the instance | Network | Partial | Common | supported in-stack rules become native firewall policy with default-deny ingress and egress plus reported platform exceptions. Unknown groups or unreadable ports grant no additional traffic; unresolved settings are reported or refused. |
| Attached data volumes (EBS volumes) | Storage | Partial | Common | supported inline or in-stack attached volumes become empty native disks on an ordinary instance; snapshots, external volumes, multi-attach, count/for\_each instances and launch-template data disks are not supported. Lifecycle and configured performance follow the target's limits. |
| Root volume | Storage | Partial | Common | root settings map within the target's native disk limits; some targets refuse pinned size or type, and no source disk contents are copied |

#### How it works

Your Terraform `aws_instance` compiles to an Azure Linux Virtual Machine. The VM boots the Azure Marketplace image that matches your AMI's operating system, at the nearest VM size, and your user data runs once at first boot. Your processes run directly on the VM; Tensor9 adds nothing to the compute path.

Azure's own Instance Metadata Service answers inside the VM as usual. The EC2 instance metadata service is not available. The IAM role's projected user-assigned identity grants Azure permissions, not AWS credentials. Check code that reads EC2 metadata or the AWS SDK credential chain.

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native Azure Linux VM.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgQXp1cmUgTGludXggVk0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyYXZhaCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzYiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYSI+WW91ciB3b3JrbG9hZDwvdGV4dD4KPHRleHQgeD0iMTExIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5pbWFnZTwvdGV4dD4KPGxpbmUgeDE9IjE4NiIgeTE9IjExMSIgeDI9IjIyNCIgeTI9IjExMSIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZTJhdmFoKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjIyNCIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjk5IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5BbWF6b24gRUMyPC90ZXh0Pgo8dGV4dCB4PSIyOTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmluc3RhbmNlPC90ZXh0Pgo8cmVjdCB4PSI0MzYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ1MiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPklOIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMmF2YWgpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPkF6dXJlIExpbnV4IFZNPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+bmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native Azure Linux VM.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgQXp1cmUgTGludXggVk0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyYXZhaCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzYiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOSI+WW91ciB3b3JrbG9hZDwvdGV4dD4KPHRleHQgeD0iMTExIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5pbWFnZTwvdGV4dD4KPGxpbmUgeDE9IjE4NiIgeTE9IjExMSIgeDI9IjIyNCIgeTI9IjExMSIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZTJhdmFoKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjIyNCIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjk5IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5BbWF6b24gRUMyPC90ZXh0Pgo8dGV4dCB4PSIyOTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmluc3RhbmNlPC90ZXh0Pgo8cmVjdCB4PSI0MzYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ1MiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPklOIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMmF2YWgpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPkF6dXJlIExpbnV4IFZNPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+bmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

Your instance becomes an Azure Linux VM, with nothing between your workload and the VM.

#### Images and VM sizes

A `data aws_ami` lookup for Ubuntu 20.04, 22.04 or 24.04 LTS on x86 or Arm resolves to the matching Canonical image in the Azure Marketplace (a `source_image_reference` from the `Canonical` publisher). The image is kept at the version resolved at deployment, so a newer "latest" image does not rebuild the VM. The selected size must support the requested architecture; Arm images use the matching Canonical Arm SKU.

A custom AMI has no Azure equivalent. The build continues with a warning that names the AMI, and the VM's `source_image_id` becomes a Terraform variable (`t9_azure_boot_image_…`) with no default. You must set it to an Azure image you have converted yourself.

* **VM sizes follow the instance's class.** General purpose and burstable map to the `D`-series, compute optimized to `F`, memory optimized to `E` and GPU to the A100 `NC` and `ND` sizes, with at least the instance's vCPUs and memory. Storage-optimized types have no matching family, so they get the lowest-cost size that fits and the build warns that the class changed.
* **The root volume becomes an Azure managed OS disk.** Tier and capacity follow the translated settings and native limits. Root retention with delete\_on\_termination=false cannot be reproduced and is reported.
* **Microsoft operates the hardware.** Azure runs the hypervisor, host and availability; you operate the guest software.

#### Launch templates and Auto Scaling fleets

An Auto Scaling group and its launch template or launch configuration compile to an Azure Virtual Machine Scale Set. Azure keeps the VM definition inside the scale set, so there is no separate template resource. Each member uses the mapped image, size and root disk. Launch-template data disks and explicit fleet root IOPS or throughput remain unsupported; standalone data-disk support does not extend to the scale set.

`desired_capacity` sets the scale set's instance count, which is the desired size: running and ready capacity depend on allocation and startup. `min_size`, `max_size` and scaling policies do not create an Azure autoscale setting, so the scale set stays at that count and the build warns. The group's health check and `target_group_arns` are not applied either, and the build warns about each.

#### Limitations

Compute is native. These are the differences from EC2 to check against your workload:

Where it differs from EC2

* **The EC2 instance metadata service is not supported.** Nothing answers EC2 metadata requests (IMDSv1 or IMDSv2) at `169.254.169.254` inside the VM, so code that reads its instance ID, region or role credentials from instance metadata gets no answer. Azure's own Instance Metadata Service (`/metadata/…`) at that address works as usual.
* **The IAM role grants native Azure permissions.** The VM binds the user-assigned identity projected from its role, but receives no AWS credentials or EC2 metadata endpoint. A role named with `name_prefix` or a computed name is not supported.
* **Discovery behaves differently: it lists only instances the management API launched.** With maximum adaptation, Describe calls to the adapter's EC2 endpoint return the instances that API launched, with the supported filters and pagination. They do not list the VM your stack creates, and no EC2 endpoint is configured inside that VM, so it cannot describe itself through EC2 calls. Unrelated cloud accounts are outside the endpoint's scope.
* **You must supply the image for a custom AMI.** The VM's `source_image_id` is a variable with no default, and planning fails until you set it to a converted Azure image.
* **Burstable instances behave differently: there are no CPU credits.** A T-series instance maps to a general-purpose `D`-series size, not to a credit-based Azure size.
* **VM sizes behave differently: performance follows the Azure size.** The size is the nearest match, not identical hardware. The performance tab has the published comparison.
* **Security groups use the target's own firewall.** Supported rules from groups in the stack are applied to the VM through an Azure network security group, with default-deny ingress and egress. A named platform rule permits the traffic needed for boot, metadata, DNS and management, and the build reports that exception. Unknown groups and rules whose ports cannot be read are reported and grant no additional traffic. Review the reported differences before cutover.
* **A per-instance public IP is not supported.** An instance that requests one (`associate_public_ip_address`) stops the deployment with an error, because this target does not create a per-instance public IP.
* **Disk performance follows the selected tier and VM.** Provisioned settings select a native disk tier and capacity. The build reports increases or shortfalls, and the VM's own disk limits still apply. Configured IOPS and throughput are not a measured guarantee.
* **Attached data disks are created empty.** An inline `ebs_block_device`, or an in-stack `aws_ebs_volume` attached to an ordinary instance, becomes Azure managed data disks. Existing data is never copied. Snapshots, external volumes and multi-attach are not supported. Data disks on an instance using `count` or `for_each`, or in a launch template, stop the build. A computed `delete_on_termination` also stops the build. Data disks are separate stack resources: they survive VM replacement but are deleted with the stack. This differs from AWS inline delete\_on\_termination behavior; the build reports it.
* **You must check Auto Scaling groups on their own page.** A launch template or launch configuration defines each member, and the group maps to a Virtual Machine Scale Set. Launch-template data disks remain unsupported; GCP and Azure fleets also refuse explicit root IOPS or throughput. Scaling, health-check and rolling-update limits are listed on the Auto Scaling page.

#### Other considerations

Microsoft operates the hardware, and Tensor9 runs nothing in the VM's compute path.

* **Before going live.** Confirm the VM boots and your user data completes. If your code reads EC2 instance metadata or uses the instance's IAM role, give it another source for its instance details and credentials.
* **When the VM is replaced.** Changing the image, subnet, key pair, availability zone, CPU options, placement or tenancy, root-volume encryption, or user data with `user_data_replace_on_change` replaces the VM. Azure's own rules can replace it in other cases, so review image, size and network changes before applying them.
* **Moving from AWS.** The VM starts from a fresh image. Data on the instance's EBS volumes is not copied, so move it separately before cutover.

#### Runtime management on Azure

The [EC2 lifecycle and metadata model](https://docs.tensor9.com/cloud-adapter-early-access/service-catalog/aws/compute-containers/ec2-instance.md#runtime-lifecycle-and-instance-metadata) also applies to Azure VMs. Supported runtime requests reconcile onto Azure resources; acceptance precedes readiness. EC2 instance metadata is not served in the guest. The operation rows above bound supported launch and attribute changes.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

No curated instance comparison is available for this source and target configuration yet.

Compare the published named instance mappings; a free-form EC2 cost calculator is not offered.

## On DigitalOcean

### Droplet

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Fleet / cross-resource discovery | Control plane | Out of scope | Full surface | Not supported: The EC2 management API is not offered on this target, so no EC2 discovery or enumeration is answered. |
| RunInstances / TerminateInstances / ModifyInstanceAttribute / CreateTags | Control plane | Out of scope | Full surface | The EC2 management API is not offered on this target: RunInstances, TerminateInstances, ModifyInstanceAttribute and CreateTags are not answered. Manage the VM through its infrastructure configuration and the cloud's own tools. |
| Instance provisioning | Instance lifecycle | Supported | Common | your aws\_instance / launch template compiles to a native DigitalOcean Droplet: the cheapest size with at least the same vCPUs and memory, CPU architecture and GPU type (the family rules are in the summary) |
| Start / Stop / Reboot / Terminate | Instance lifecycle | Supported | Common | Infrastructure configuration maps to native VM lifecycle controls; this row does not establish runtime EC2 API support. |
| DescribeAvailabilityZones | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeSecurityGroups | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM; native firewall translation does not add an EC2 DescribeSecurityGroups endpoint. |
| DescribeVolumes / DescribeNetworkInterfaces / DescribeTags (the caller's own) | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeVpcs / DescribeSubnets | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. The network describes for the VPC records are on the VPC card. |
| Instance metadata (IMDS) + DescribeInstances (the running instance) | Metadata + discovery | Out of scope | Common | EC2 instance metadata and AWS role credentials are not served inside a compiled VM. Use the target's own metadata service where one is available. A DescribeInstances call from inside a compiled VM is not answered with its own instance, because no Tensor9 endpoint is configured in the guest. |
| Public IP on the instance | Network | Out of scope | Common | a request for a per-instance public IP stops the build; target-native addressing still needs review |
| Security groups on the instance | Network | Partial | Common | supported in-stack rules become native firewall policy with default-deny ingress and egress plus reported platform exceptions. Unknown groups or unreadable ports grant no additional traffic; unresolved settings are reported or refused. |
| Attached data volumes (EBS volumes) | Storage | Partial | Common | supported inline or in-stack attached volumes become empty native disks on an ordinary instance; snapshots, external volumes, multi-attach, count/for\_each instances and launch-template data disks are not supported. Lifecycle and configured performance follow the target's limits. |
| Root volume | Storage | Partial | Common | root settings map within the target's native disk limits; some targets refuse pinned size or type, and no source disk contents are copied |

#### How it works

Your Terraform `aws_instance` compiles to a DigitalOcean Droplet. The Droplet boots the Ubuntu image that matches your AMI's operating system, on a Droplet size with at least the instance's vCPUs and memory, and your user data runs once at first boot. Your processes run directly on the Droplet; Tensor9 adds nothing to the compute path.

Every Droplet has a public IPv4 address. To keep a private instance private, the deployment puts it behind a DigitalOcean firewall that denies all inbound traffic and allows outbound traffic, and creates that firewall before the Droplet, so the Droplet never starts unprotected.

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native DigitalOcean Droplet.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgRGlnaXRhbE9jZWFuIERyb3BsZXQuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyZG92YWgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj48L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0MCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIzMiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjM2IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMTEiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmEiPllvdXIgd29ya2xvYWQ8L3RleHQ+Cjx0ZXh0IHg9IjExMSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+aW1hZ2U8L3RleHQ+CjxsaW5lIHgxPSIxODYiIHkxPSIxMTEiIHgyPSIyMjQiIHkyPSIxMTEiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2UyZG92YWgpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMjI0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyOTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmEiPkFtYXpvbiBFQzI8L3RleHQ+Cjx0ZXh0IHg9IjI5OSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+aW5zdGFuY2U8L3RleHQ+CjxyZWN0IHg9IjQzNiIgeT0iNDAiIHdpZHRoPSIzODQiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNDUyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+SU4gVEhFIFRBUkdFVCBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iNDU2IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MzEiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmEiPllvdXIgd29ya2xvYWQ8L3RleHQ+Cjx0ZXh0IHg9IjUzMSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgc29mdHdhcmU8L3RleHQ+CjxsaW5lIHgxPSI2MDYiIHkxPSIxMTEiIHgyPSI2NDQiIHkyPSIxMTEiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2UyZG92YWgpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPkRpZ2l0YWxPY2VhbjwvdGV4dD4KPHRleHQgeD0iNzE5IiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPkRyb3BsZXQgwrcgbmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native DigitalOcean Droplet.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgRGlnaXRhbE9jZWFuIERyb3BsZXQuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyZG92YWgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj48L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0MCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIzMiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjM2IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMTEiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1ZjkiPllvdXIgd29ya2xvYWQ8L3RleHQ+Cjx0ZXh0IHg9IjExMSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+aW1hZ2U8L3RleHQ+CjxsaW5lIHgxPSIxODYiIHkxPSIxMTEiIHgyPSIyMjQiIHkyPSIxMTEiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2UyZG92YWgpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMjI0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyOTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1ZjkiPkFtYXpvbiBFQzI8L3RleHQ+Cjx0ZXh0IHg9IjI5OSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+aW5zdGFuY2U8L3RleHQ+CjxyZWN0IHg9IjQzNiIgeT0iNDAiIHdpZHRoPSIzODQiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNDUyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+SU4gVEhFIFRBUkdFVCBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iNDU2IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MzEiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1ZjkiPllvdXIgd29ya2xvYWQ8L3RleHQ+Cjx0ZXh0IHg9IjUzMSIgeT0iMTIzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgc29mdHdhcmU8L3RleHQ+CjxsaW5lIHgxPSI2MDYiIHkxPSIxMTEiIHgyPSI2NDQiIHkyPSIxMTEiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2UyZG92YWgpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPkRpZ2l0YWxPY2VhbjwvdGV4dD4KPHRleHQgeD0iNzE5IiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPkRyb3BsZXQgwrcgbmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

Your instance becomes a DigitalOcean Droplet, with nothing between your workload and the VM.

#### Images, sizes and disks

A `data aws_ami` lookup for Ubuntu 22.04 or 24.04 LTS resolves to the matching DigitalOcean image slug (Ubuntu 22.04 on x86 becomes `ubuntu-22-04-x64`), set directly on the Droplet. The image is kept at the version resolved at deployment, so a newer "latest" image does not rebuild the Droplet. Ubuntu 20.04 stops the build. A custom or opaque AMI requires a numeric DigitalOcean custom-image or snapshot ID in `t9_do_boot_image_…`, with no default. You supply that image; Tensor9 does not convert it.

The root disk comes with the Droplet size. A pinned root size or type stops the build rather than changing CPU and memory to make room. IOPS and throughput have no independent setting and produce named warnings. Supported data disks become separate empty DigitalOcean volumes, whose performance depends on the Droplet type.

* **Sizes must match architecture and GPU requirements.** The sizing table has x86 CPU and GPU options. Arm has no matching size here; an unavailable GPU combination also stops the build rather than dropping the accelerator.
* **DigitalOcean operates the hardware.** DigitalOcean runs the hypervisor, host and availability; you operate the guest software.

#### Launch templates and Auto Scaling fleets

Auto Scaling groups and their launch templates are not translated to DigitalOcean Droplet autoscale pools by this mapping. Support for a standalone Droplet does not establish fleet provisioning or autoscaling support.

If your workload needs a fleet, define and operate the native pool and scaling settings separately, or use a target with a supported fleet mapping. Every new Droplet needs the intended firewall, image and storage configuration before it receives application traffic.

#### Limitations

Compute is native. These are the differences from EC2 to check against your workload:

Where it differs from EC2

* **The EC2 instance metadata service is not supported.** Nothing answers as EC2 at `169.254.169.254` inside the Droplet. DigitalOcean's own metadata service answers there, including on some EC2-style `/latest` paths, but its answers describe the Droplet in DigitalOcean's terms, not an EC2 instance, and it gives the Droplet no AWS credentials.
* **The instance's IAM role is not attached to the Droplet.** DigitalOcean has no per-instance identity, and the Droplet gets no AWS credentials from this mapping. A role named with `name_prefix` or a computed name stops the build.
* **The EC2 management API is not supported on this target.** `RunInstances`, `DescribeInstances` and the other EC2 lifecycle and describe calls are not answered, and no EC2 endpoint is configured inside the Droplet. Launch and inspect the Droplet through its infrastructure configuration and the cloud's own tools.
* **Public addressing behaves differently: every Droplet is public.** A private instance is protected by a default-deny firewall instead. An instance that requests a public IP (`associate_public_ip_address`), or sets it or `vpc_security_group_ids` to a computed value, stops the build. Elastic IP attachments are not reproduced.
* **Security groups use the target's own firewall.** Supported rules from groups in the stack are applied to the Droplet through a DigitalOcean firewall, with default-deny ingress and egress. A named platform rule permits the traffic needed for boot, metadata, DNS and management, and the build reports that exception. Unknown groups and rules whose ports cannot be read are reported and grant no additional traffic. Review the reported differences before cutover.
* **Root size and type cannot be set separately.** They come with the Droplet size, so pinned values stop the build. Provisioned IOPS or throughput cannot be enforced independently and are reported; per-Droplet limits still apply. Root delete\_on\_termination=false cannot be honored and is reported.
* **The image and size must both be available.** Ubuntu 20.04 is not mapped. A custom AMI requires your native image ID; a mapped image does not establish support for an unavailable CPU architecture or GPU size.
* **Sizes behave differently: performance follows the Droplet size.** The size is the nearest match by vCPUs and memory, not identical hardware. The performance tab has the published comparison.
* **Attached data disks are created empty.** An inline `ebs_block_device`, or an in-stack `aws_ebs_volume` attached to an ordinary instance, becomes DigitalOcean block-storage volumes. Existing data is never copied. Snapshots, external volumes and multi-attach are not supported. Data disks on an instance using `count` or `for_each`, or in a launch template, stop the build. A computed `delete_on_termination` also stops the build. Data disks are separate stack resources: they survive VM replacement but are deleted with the stack. This differs from AWS inline delete\_on\_termination behavior; the build reports it.
* **Auto Scaling groups are not supported on this target.** This mapping creates standalone VMs but does not translate the group's launch template, replica count or scaling policy to a DigitalOcean autoscale pool. Define and operate the native fleet separately, or use a target with a supported fleet mapping.

#### Other considerations

DigitalOcean operates the hardware, and Tensor9 runs nothing in the Droplet's compute path.

* **Before going live.** Confirm the Droplet boots, your user data completes and the firewall allows exactly the traffic you expect. If your code reads EC2 instance metadata or uses the instance's IAM role, give it another source for its instance details and credentials.
* **When the Droplet is replaced.** Changing the image, subnet, key pair, availability zone, CPU options, placement or tenancy, root-volume encryption, or user data with `user_data_replace_on_change` replaces the Droplet. DigitalOcean's own rules can replace it in other cases, including some size changes.
* **Moving from AWS.** The Droplet starts from a fresh image. Data on the instance's EBS volumes is not copied, so move it separately before cutover.

#### Runtime lifecycle and instance metadata

The EC2 management API is offered at maximum adaptation on Google Cloud and Azure only. There, a supported lifecycle request records the instance state you asked for; a background process then creates or changes the VM and its related resources in the target cloud. A successful request can return a pending state while the machine is still being created, so use the describe operations to check when it is ready.

RunInstances, termination and tagging act on the instances this API launched. Attribute updates and launch shapes stay within the supported request fields and backend settings. Describe requests list those instances; they do not list VMs compiled from your stack or give access to unrelated cloud accounts.

EC2 instance metadata is not available inside a VM compiled from your stack: 169.254.169.254 answers with the target cloud's own metadata service. On Google Cloud, a VM launched through the management API with an instance profile installs a relay at first boot that answers EC2 metadata paths, including role credentials, for that VM.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

No curated instance comparison is available for this source and target configuration yet.

Compare the published named instance mappings; a free-form EC2 cost calculator is not offered.

## On Google Cloud

### Compute Engine

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Fleet / cross-resource discovery | Control plane | Partial | Full surface | The management API lists the managed instances it launched or registered, with supported filters and pagination. It does not list VMs compiled from your stack, and it does not enumerate unrelated cloud accounts. |
| RunInstances / TerminateInstances / ModifyInstanceAttribute / CreateTags | Control plane | Partial | Full surface | Maximum adaptation supports bounded instance launch, termination and tagging for adapter-managed resources. ModifyInstanceAttribute covers security-group changes; other attributes and unsupported launch settings are rejected. Creation completes asynchronously on the selected backend. |
| Instance provisioning | Instance lifecycle | Supported | Common | your aws\_instance / launch template compiles to a native Google Compute Engine instance: the cheapest size with at least the same vCPUs and memory, CPU architecture and GPU type (the family rules are in the summary) |
| Start / Stop / Reboot / Terminate | Instance lifecycle | Supported | Common | Infrastructure configuration maps to native VM lifecycle controls; this row does not establish runtime EC2 API support. |
| DescribeAvailabilityZones | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeSecurityGroups | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM; native firewall translation does not add an EC2 DescribeSecurityGroups endpoint. |
| DescribeVolumes / DescribeNetworkInterfaces / DescribeTags (the caller's own) | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeVpcs / DescribeSubnets | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. The network describes for the VPC records are on the VPC card. |
| Instance metadata (IMDS) + DescribeInstances (the running instance) | Metadata + discovery | Out of scope | Common | EC2 instance metadata is not available on a VM compiled from your stack: 169.254.169.254 answers with Google's own metadata server, so EC2 paths such as the instance id and role credentials return nothing. A VM launched at run time through the EC2 management API with an instance profile is different: it installs a relay at first boot that answers EC2 metadata and credentials for that VM. A DescribeInstances call from inside a compiled VM is not answered with its own instance, because no Tensor9 endpoint is configured in the guest. |
| Public IP on the instance | Network | Out of scope | Common | a request for a per-instance public IP stops the build; target-native addressing still needs review |
| Security groups on the instance | Network | Partial | Common | supported in-stack rules become native firewall policy with default-deny ingress and egress plus reported platform exceptions. Unknown groups or unreadable ports grant no additional traffic; unresolved settings are reported or refused. |
| Attached data volumes (EBS volumes) | Storage | Partial | Common | supported inline or in-stack attached volumes become empty native disks on an ordinary instance; snapshots, external volumes, multi-attach, count/for\_each instances and launch-template data disks are not supported. Lifecycle and configured performance follow the target's limits. |
| Root volume | Storage | Partial | Common | root settings map within the target's native disk limits; some targets refuse pinned size or type, and no source disk contents are copied |

#### How it works

Your Terraform `aws_instance` compiles to a Compute Engine VM. The VM boots the Compute Engine image that matches your AMI's operating system, on the nearest machine type, and your user data runs once at first boot. Your processes run directly on the VM; Tensor9 adds nothing to the compute path.

The VM runs as a Google service account created from the instance's IAM role, not as Compute Engine's default service account. A VM that your Terraform creates does not get the EC2 instance metadata service; the metadata section below explains what that means and which VMs do get it.

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native Compute Engine VM.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgQ29tcHV0ZSBFbmdpbmUgVk0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyZ3ZhaCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzYiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYSI+WW91ciB3b3JrbG9hZDwvdGV4dD4KPHRleHQgeD0iMTExIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5pbWFnZTwvdGV4dD4KPGxpbmUgeDE9IjE4NiIgeTE9IjExMSIgeDI9IjIyNCIgeTI9IjExMSIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZTJndmFoKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjIyNCIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjk5IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5BbWF6b24gRUMyPC90ZXh0Pgo8dGV4dCB4PSIyOTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmluc3RhbmNlPC90ZXh0Pgo8cmVjdCB4PSI0MzYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ1MiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPklOIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMmd2YWgpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPkNvbXB1dGUgRW5naW5lIFZNPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+bmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native Compute Engine VM.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgQ29tcHV0ZSBFbmdpbmUgVk0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyZ3ZhaCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzYiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOSI+WW91ciB3b3JrbG9hZDwvdGV4dD4KPHRleHQgeD0iMTExIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5pbWFnZTwvdGV4dD4KPGxpbmUgeDE9IjE4NiIgeTE9IjExMSIgeDI9IjIyNCIgeTI9IjExMSIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZTJndmFoKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjIyNCIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjk5IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5BbWF6b24gRUMyPC90ZXh0Pgo8dGV4dCB4PSIyOTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmluc3RhbmNlPC90ZXh0Pgo8cmVjdCB4PSI0MzYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ1MiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPklOIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMmd2YWgpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPkNvbXB1dGUgRW5naW5lIFZNPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+bmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

Your instance becomes a Compute Engine VM, with nothing between your workload and the VM.

#### Images and machine types

A `data aws_ami` lookup for Ubuntu 22.04 or 24.04 LTS on x86 resolves to the matching Compute Engine image family (Ubuntu 22.04 becomes `ubuntu-os-cloud/ubuntu-2204-lts`). The image is kept at the version resolved at deployment, so a newer "latest" image does not rebuild the VM. Compute Engine also maps Ubuntu 22.04 and 24.04 Arm images to Arm VM sizes. Standard Ubuntu 20.04 is refused; the build does not silently substitute paid Ubuntu Pro.

A custom AMI has no Compute Engine equivalent. The build continues with a warning that names the AMI, and the VM's boot image becomes a Terraform variable (`t9_gcp_boot_image_…`) with no default. You must set it to a Compute Engine image you have converted yourself.

* **Machine types follow the instance's class.** General purpose maps to `n2`, compute optimized to `c2`, burstable to `e2` and GPU to `g2`, sized to at least the instance's vCPUs and memory. Memory- and storage-optimized types have no matching family, so they get the lowest-cost type that fits and the build warns that the class changed.
* **The root volume uses a native persistent disk.** Class and capacity may change to provision requested settings, with a build warning. Root delete\_on\_termination=false retains the disk.
* **Google operates the hardware.** Google runs the hypervisor, host and availability; you operate the guest software.

#### Instance metadata and identity

**VMs your Terraform creates.** Nothing answers EC2 metadata requests at `169.254.169.254`. Google's own metadata server answers there as on any Compute Engine VM, for `/computeMetadata/v1/` paths with the `Metadata-Flavor: Google` header. The VM's Google permissions come from its service account, which is created from the instance's IAM role.

**VMs launched at runtime.** With maximum adaptation, a VM that the EC2 management API launches with an instance profile gets a small relay in the guest, when the deployment enables it. The relay sends EC2 requests, including the IMDSv2 token request (`PUT /latest/api/token`) and reads that include `X-aws-ec2-metadata-token`, to the Cloud Adapter deployment. The Cloud Adapter deployment answers with the same details `DescribeInstances` returns for that instance, and with credentials for its instance profile. A VM it cannot match to exactly one instance gets HTTP 403. Requests for Google's paths, or with the Google header, are forwarded to Google unchanged.

#### Launch templates and Auto Scaling fleets

An Auto Scaling group and its launch template or launch configuration compile to a `google_compute_instance_template` and a regional managed instance group. Each member gets the same image, machine type, disk and service account as a standalone VM.

`desired_capacity` becomes the group's target size (`min_size` when it is unset): the requested number of instances. Running and ready capacity depend on allocation and startup. A CPU target-tracking policy adds a regional autoscaler that uses `min_size` and `max_size` as its bounds; without a policy the group holds its target size.

In-stack `target_group_arns` references and `aws_autoscaling_attachment` registrations join the managed instance group to the translated network load balancer's native backend service. Duplicate registration adds that managed group only once. Literal target-group ARNs, missing target groups and groups without a supported native GCP backend service produce named build warnings; those registrations receive no load-balanced traffic. Each listener must use the registered target port, and all referenced target groups must have identical members. This membership does not add application autohealing: the group's health check is not an automatic repair policy, so a running but unhealthy VM is not replaced.

#### Limitations

Compute is native. These are the differences from EC2 to check against your workload:

Where it differs from EC2

* **The EC2 instance metadata service is not supported on VMs your Terraform creates.** Code that reads its instance ID, region or role credentials from `169.254.169.254` gets no EC2 answer there. Only VMs launched at runtime through the EC2 management API get the metadata relay.
* **The signed instance identity document is not supported.** Its signature cannot be reproduced, so a workload that verifies it does not work.
* **Relay credentials work only with the adapter.** On a VM with the relay, the credentials work with the adapter endpoints given to the guest (the `AWS_ENDPOINT_URL_…` variables), not with AWS endpoints reached directly.
* **Discovery behaves differently: it lists only instances the management API launched.** With maximum adaptation, Describe calls to the adapter's EC2 endpoint return the instances that API launched, with the supported filters and pagination. They do not list the instance your stack creates, and no EC2 endpoint is configured inside that instance, so it cannot describe itself through EC2 calls. Unrelated cloud accounts are outside the endpoint's scope.
* **You must give the instance's IAM role a literal name.** The VM runs as a Google service account created from that role. A role named with `name_prefix` or a computed name stops the build, rather than leaving the VM on Compute Engine's default account.
* **You must supply the image for a custom AMI.** The VM's boot image is a variable with no default, and planning fails until you set it to a converted Compute Engine image.
* **Machine types behave differently: performance follows the Compute Engine type.** The type is the nearest match, not identical hardware. Older Intel generations trail EC2 on single-core speed; the performance tab has the published comparison.
* **Security groups use the target's own firewall.** Supported rules from groups in the stack are applied to the VM through Compute Engine firewall rules, with default-deny ingress and egress. A named platform rule permits the traffic needed for boot, metadata, DNS and management, and the build reports that exception. Unknown groups and rules whose ports cannot be read are reported and grant no additional traffic. Review the reported differences before cutover.
* **A per-instance public IP is not supported.** An instance that requests one (`associate_public_ip_address`) stops the deployment with an error, because this target does not create a per-instance public IP.
* **Disk performance follows the selected disk and VM.** Provisioned settings select a compatible native disk class and capacity; the build reports capacity increases or shortfalls. The gp3 free baseline is not treated as a paid request. Per-VM limits still apply; configured IOPS and throughput are not a measured guarantee.
* **Attached data disks are created empty.** An inline `ebs_block_device`, or an in-stack `aws_ebs_volume` attached to an ordinary instance, becomes Compute Engine persistent disks. Existing data is never copied. Snapshots, external volumes and multi-attach are not supported. Data disks on an instance using `count` or `for_each`, or in a launch template, stop the build. A computed `delete_on_termination` also stops the build. Data disks are separate stack resources: they survive VM replacement but are deleted with the stack. This differs from AWS inline delete\_on\_termination behavior; the build reports it.
* **You must check Auto Scaling groups on their own page.** A launch template or launch configuration defines each member, and the group maps to a regional managed instance group. Launch-template data disks remain unsupported; GCP and Azure fleets also refuse explicit root IOPS or throughput. Scaling, health-check and rolling-update limits are listed on the Auto Scaling page.

#### Other considerations

Google operates the hardware, and Tensor9 runs nothing in the VM's compute path.

* **Before going live.** Confirm the VM boots and your user data completes. If your code reads EC2 instance metadata, give it another source for its instance ID and region, and check that its Google service account has the permissions it needs.
* **When the VM is replaced.** Changing the AMI, subnet, key pair, availability zone, CPU options, placement or tenancy, root-volume encryption, or user data with `user_data_replace_on_change` replaces the VM. Compute Engine's own rules can replace it in other cases, so review image, machine type and network changes before applying them.
* **Moving from AWS.** The VM starts from a fresh image. Data on the instance's EBS volumes is not copied, so move it separately before cutover.

#### Runtime lifecycle and instance metadata

The EC2 management API is offered at maximum adaptation on Google Cloud and Azure only. There, a supported lifecycle request records the instance state you asked for; a background process then creates or changes the VM and its related resources in the target cloud. A successful request can return a pending state while the machine is still being created, so use the describe operations to check when it is ready.

RunInstances, termination and tagging act on the instances this API launched. Attribute updates and launch shapes stay within the supported request fields and backend settings. Describe requests list those instances; they do not list VMs compiled from your stack or give access to unrelated cloud accounts.

EC2 instance metadata is not available inside a VM compiled from your stack: 169.254.169.254 answers with the target cloud's own metadata service. On Google Cloud, a VM launched through the management API with an instance profile installs a relay at first boot that answers EC2 metadata paths, including role credentials, for that VM.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### On-demand virtual machines · m6i.large → n2-standard-2

Feature: On-demand virtual machines.

Source configuration: **m6i.large · 2 vCPU / 8 GiB**. Mapped target: n2-standard-2 · 2 vCPU / 8 GiB. Compute only for the named Linux on-demand instances, each running 730 hours per month.

Estimated monthly service charges by Number of running instances. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![On-demand virtual machines · m6i.large → n2-standard-2: monthly service charges by Number of running instances. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/87be5c23176ed1d2bf2738a7585981b7a16c76fd51846f7306141707cb4d558b-light.svg)

![On-demand virtual machines · m6i.large → n2-standard-2: monthly service charges by Number of running instances. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/5e38b161c930175d9dc69670ce620b07bffbd2733b3a59d46423d9faefa305e5-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Number of running instances (instances) | EC2 Instances | Compute Engine (n2-standard-2) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 70.08 | 70.90 | 0.82 |
| 2 | 140.16 | 141.79 | 1.63 |
| 4 | 280.32 | 283.58 | 3.26 |
| 8 | 560.64 | 567.17 | 6.53 |
| 16 | 1,121.28 | 1,134.34 | 13.06 |
| 32 | 2,242.56 | 2,268.68 | 26.12 |
| 64 | 4,485.12 | 4,537.35 | 52.23 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Target / origin VM CPU and RAM | 1 | multiplier |

* Compute only for the named Linux on-demand instances, each running 730 hours per month. m6i.large (us-east-1) → n2-standard-2 (us-central1). Storage, network, licenses, discounts, adapter hosting and Tensor9 fees are excluded. Resource matching does not establish equal measured performance.
* Named Linux on-demand instances at cited list prices; source us-east-1, target us-central1. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* m6i.large: m6i.large, Linux, shared tenancy, on-demand, us-east-1: Amazon EC2 price list (AWS Price List API) ([https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv), read 2026-10-22). The named m6i.large (2 vCPU, 8 GiB) is USD 0.096 per instance-hour.
* n2-standard-2: n2-standard-2, Linux, on-demand, us-central1: Compute Engine general-purpose machine pricing ([https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose), read 2026-10-22). The listed n2-standard-2 (2 vCPU, 8 GiB) is USD 0.097118 per instance-hour, reproduced by 2 x 0.031611 + 8 x 0.004237; price this whole configuration.
* The compiler preserves the declared resource and architecture fit; equal workload performance has not been measured.
* AWS Price List API, AmazonEC2 offer (CSV): [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv)
* AWS Price List API, AWSDataTransfer offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSDataTransfer/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSDataTransfer/current/us-east-1/index.json)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Compute only for the named Linux on-demand instances, each running 730 hours per month.

Excluded costs and workload features:

* Attached disks, network transfer, operating-system and software licenses, GPUs, discounts, commitments, credits and tax.
* Adapter hosting and Tensor9 fees.

List prices read: 2026-10-22. Model: `plan-bcccbdac70e36a2d5723c9a953ac234422fd2119` / `2026-10-22.planning.2`. Curve: `ec2-m6i-large-gcp-n2-standard-2`.

Sources: [AWS Price List API, AmazonEC2 offer (CSV)](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv), [AWS Price List API, AWSDataTransfer offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSDataTransfer/current/us-east-1/index.json), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

##### On-demand virtual machines · m7i.large → n2-standard-2

Feature: On-demand virtual machines.

Source configuration: **m7i.large · 2 vCPU / 8 GiB**. Mapped target: n2-standard-2 · 2 vCPU / 8 GiB. Compute only for the named Linux on-demand instances, each running 730 hours per month.

Estimated monthly service charges by Number of running instances. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![On-demand virtual machines · m7i.large → n2-standard-2: monthly service charges by Number of running instances. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/030a0a9757d10b993df4625c996f6427208e2d6b32dfbc9a4749596af2c9a80f-light.svg)

![On-demand virtual machines · m7i.large → n2-standard-2: monthly service charges by Number of running instances. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e69c988a59d71bfb47bc06230ae904d2806a18f525cf79c845f87820f9808abe-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Number of running instances (instances) | EC2 Instances | Compute Engine (n2-standard-2) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 73.58 | 70.90 | -2.69 |
| 2 | 147.17 | 141.79 | -5.38 |
| 4 | 294.34 | 283.58 | -10.75 |
| 8 | 588.67 | 567.17 | -21.50 |
| 16 | 1,177.34 | 1,134.34 | -43.01 |
| 32 | 2,354.69 | 2,268.68 | -86.01 |
| 64 | 4,709.38 | 4,537.35 | -172.02 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Target / origin VM CPU and RAM | 1 | multiplier |

* Compute only for the named Linux on-demand instances, each running 730 hours per month. m7i.large (us-east-1) → n2-standard-2 (us-central1). Storage, network, licenses, discounts, adapter hosting and Tensor9 fees are excluded. Resource matching does not establish equal measured performance.
* Named Linux on-demand instances at cited list prices; source us-east-1, target us-central1. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* m7i.large: EC2 Linux on-demand BoxUsage:m7i.large (2 vCPU, 8 GiB), us-east-1: AWS Price List API, AmazonEC2 offer (CSV) ([https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv), read 2026-10-22). USD 0.1008 per instance-hour; matches the default 2 vCPU / 8 GiB blueprint.
* n2-standard-2: n2-standard-2, Linux, on-demand, us-central1: Compute Engine general-purpose machine pricing ([https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose), read 2026-10-22). The listed n2-standard-2 (2 vCPU, 8 GiB) is USD 0.097118 per instance-hour, reproduced by 2 x 0.031611 + 8 x 0.004237; price this whole configuration.
* The compiler preserves the declared resource and architecture fit; equal workload performance has not been measured.
* AWS Price List API, AmazonEC2 offer (CSV): [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv)
* AWS Price List API, AWSDataTransfer offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSDataTransfer/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSDataTransfer/current/us-east-1/index.json)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Compute only for the named Linux on-demand instances, each running 730 hours per month.

Excluded costs and workload features:

* Attached disks, network transfer, operating-system and software licenses, GPUs, discounts, commitments, credits and tax.
* Adapter hosting and Tensor9 fees.

List prices read: 2026-10-22. Model: `plan-bcccbdac70e36a2d5723c9a953ac234422fd2119` / `2026-10-22.planning.2`. Curve: `ec2-m7i-large-gcp-n2-standard-2`.

Sources: [AWS Price List API, AmazonEC2 offer (CSV)](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/us-east-1/index.csv), [AWS Price List API, AWSDataTransfer offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSDataTransfer/current/us-east-1/index.json), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

Compare the published named instance mappings; a free-form EC2 cost calculator is not offered.

## On OCI

### Compute Instance

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Fleet / cross-resource discovery | Control plane | Out of scope | Full surface | Not supported: The EC2 management API is not offered on this target, so no EC2 discovery or enumeration is answered. |
| RunInstances / TerminateInstances / ModifyInstanceAttribute / CreateTags | Control plane | Out of scope | Full surface | The EC2 management API is not offered on this target: RunInstances, TerminateInstances, ModifyInstanceAttribute and CreateTags are not answered. Manage the VM through its infrastructure configuration and the cloud's own tools. |
| Instance provisioning | Instance lifecycle | Supported | Common | your aws\_instance / launch template compiles to a native OCI Compute instance: the cheapest size with at least the same vCPUs and memory, CPU architecture and GPU type (the family rules are in the summary) |
| Start / Stop / Reboot / Terminate | Instance lifecycle | Supported | Common | Infrastructure configuration maps to native VM lifecycle controls; this row does not establish runtime EC2 API support. |
| DescribeAvailabilityZones | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeSecurityGroups | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM; native firewall translation does not add an EC2 DescribeSecurityGroups endpoint. |
| DescribeVolumes / DescribeNetworkInterfaces / DescribeTags (the caller's own) | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeVpcs / DescribeSubnets | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. The network describes for the VPC records are on the VPC card. |
| Instance metadata (IMDS) + DescribeInstances (the running instance) | Metadata + discovery | Out of scope | Common | EC2 instance metadata and AWS role credentials are not served inside a compiled VM. Use the target's own metadata service where one is available. A DescribeInstances call from inside a compiled VM is not answered with its own instance, because no Tensor9 endpoint is configured in the guest. |
| Public IP on the instance | Network | Out of scope | Common | a request for a per-instance public IP stops the build; target-native addressing still needs review |
| Security groups on the instance | Network | Partial | Common | supported in-stack rules become native firewall policy with default-deny ingress and egress plus reported platform exceptions. Unknown groups or unreadable ports grant no additional traffic; unresolved settings are reported or refused. |
| Attached data volumes (EBS volumes) | Storage | Partial | Common | supported inline or in-stack attached volumes become empty native disks on an ordinary instance; snapshots, external volumes, multi-attach, count/for\_each instances and launch-template data disks are not supported. Lifecycle and configured performance follow the target's limits. |
| Root volume | Storage | Partial | Common | root settings map within the target's native disk limits; some targets refuse pinned size or type, and no source disk contents are copied |

#### How it works

Your Terraform `aws_instance` compiles to an OCI Compute instance (`oci_core_instance`). It boots the Canonical Ubuntu image that matches your AMI's operating system, on the nearest OCI shape, and your user data runs once at first boot. Your processes run directly on the instance; Tensor9 adds nothing to the compute path.

OCI's own Instance Metadata Service answers inside the instance as usual. The EC2 instance metadata service is not available, so plan another source for the workload's instance details and credentials.

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native OCI Compute instance.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgT0NJIENvbXB1dGUgaW5zdGFuY2UuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyb3ZhaCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzYiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYSI+WW91ciB3b3JrbG9hZDwvdGV4dD4KPHRleHQgeD0iMTExIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5pbWFnZTwvdGV4dD4KPGxpbmUgeDE9IjE4NiIgeTE9IjExMSIgeDI9IjIyNCIgeTI9IjExMSIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZTJvdmFoKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjIyNCIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjk5IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5BbWF6b24gRUMyPC90ZXh0Pgo8dGV4dCB4PSIyOTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmluc3RhbmNlPC90ZXh0Pgo8cmVjdCB4PSI0MzYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ1MiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPklOIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMm92YWgpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPk9DSSBDb21wdXRlPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+aW5zdGFuY2U8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS your workload runs on an Amazon EC2 instance. After: in the target cloud the application workload runs on a native OCI Compute instance.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcyIiB2aWV3Qm94PSIwIDAgODM2IDE3MiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIHdvcmtsb2FkIHJ1bnMgb24gYW4gQW1hem9uIEVDMiBpbnN0YW5jZS4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIGFwcGxpY2F0aW9uIHdvcmtsb2FkIHJ1bnMgb24gYSBuYXRpdmUgT0NJIENvbXB1dGUgaW5zdGFuY2UuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImUyb3ZhaCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMyIiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzYiIHk9IjgwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOSI+WW91ciB3b3JrbG9hZDwvdGV4dD4KPHRleHQgeD0iMTExIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5pbWFnZTwvdGV4dD4KPGxpbmUgeDE9IjE4NiIgeTE9IjExMSIgeDI9IjIyNCIgeTI9IjExMSIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZTJvdmFoKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjIyNCIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjk5IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5BbWF6b24gRUMyPC90ZXh0Pgo8dGV4dCB4PSIyOTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmluc3RhbmNlPC90ZXh0Pgo8cmVjdCB4PSI0MzYiIHk9IjQwIiB3aWR0aD0iMzg0IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ1MiIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPklOIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ1NiIgeT0iODAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNjIiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTMxIiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5Zb3VyIHdvcmtsb2FkPC90ZXh0Pgo8dGV4dCB4PSI1MzEiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zYW1lIHNvZnR3YXJlPC90ZXh0Pgo8bGluZSB4MT0iNjA2IiB5MT0iMTExIiB4Mj0iNjQ0IiB5Mj0iMTExIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNlMm92YWgpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNjQ0IiB5PSI4MCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI2MiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3MTkiIHk9IjEwNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPk9DSSBDb21wdXRlPC90ZXh0Pgo8dGV4dCB4PSI3MTkiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+aW5zdGFuY2U8L3RleHQ+Cjwvc3ZnPg==)

Your instance becomes an OCI Compute instance, with nothing between your workload and the VM.

#### Images and shapes

A `data aws_ami` lookup for Ubuntu 20.04, 22.04 or 24.04 LTS on x86 resolves, through a `data oci_core_images` lookup, to the matching Canonical Ubuntu image. The image is kept at the version resolved at deployment, so a newer "latest" image does not rebuild the instance. Arm Ubuntu uses a matching Arm shape. A custom or opaque AMI requires `t9_oci_boot_image_…`, with no default: supply a native OCI custom-image OCID compatible with that shape. Tensor9 does not convert the source AMI.

* **Shapes are sized from the instance.** An x86 instance maps to a `VM.Standard.E5.Flex` shape with enough OCPUs and memory for its vCPUs and RAM; a GPU instance maps to a `VM.GPU.A10` shape. On x86 shapes, 1 OCPU provides 2 vCPUs.
* **The root volume becomes an OCI boot volume.** Capacity and VPUs/GB follow translated settings and native limits; increases are reported. Root delete\_on\_termination=false preserves the boot volume.
* **Oracle operates the hardware.** OCI runs the hypervisor, host and availability domain; you operate the guest software.

#### Launch templates and Auto Scaling fleets

Auto Scaling groups and their launch templates are not translated to OCI instance pools by this mapping. Support for a standalone OCI instance does not establish fleet provisioning or autoscaling support.

If your workload needs a fleet, define and operate the OCI instance configuration, pool and scaling policy separately, or use a target with a supported fleet mapping. Check image inputs, identity, disks and network policy for every member before sending traffic.

#### Limitations

Compute is native. These are the differences from EC2 to check against your workload:

Where it differs from EC2

* **The EC2 instance metadata service is not supported.** Nothing answers EC2 metadata requests (IMDSv1 or IMDSv2) at `169.254.169.254` inside the instance, so code that reads its instance ID, region or role credentials from instance metadata gets no answer. OCI's own Instance Metadata Service (`/opc/…`) at that address works as usual.
* **IAM roles use OCI instance principals.** An EC2-trusted role's dynamic group is narrowed to the declaring migrated instances when their IDs can be resolved in the same module. Generated, cross-module or mixed-trust cases retain a broader rule with a warning. OCI policy propagation can lag first boot. No AWS credentials are delivered.
* **The EC2 management API is not supported on this target.** `RunInstances`, `DescribeInstances` and the other EC2 lifecycle and describe calls are not answered, and no EC2 endpoint is configured inside the instance. Launch and inspect the instance through its infrastructure configuration and the cloud's own tools.
* **You must supply the native image for a custom AMI.** Stock Ubuntu has x86 and Arm mappings. Other images require an OCI image OCID supplied by your own pipeline; the build performs no image conversion.
* **Availability zones are not mapped.** The instance is placed in the first availability domain of the compartment, whatever zone the AWS instance named.
* **Burstable instances behave differently: there are no CPU credits.** A T-series instance gets a regular `VM.Standard.E5.Flex` shape sized to its vCPUs and memory.
* **Shapes behave differently: performance follows the OCI shape.** The shape is the nearest match, not identical hardware. The performance tab has the published comparison.
* **Security groups use the target's own firewall.** Supported rules from groups in the stack are applied to the instance through an OCI network security group, with default-deny ingress and egress. A named platform rule permits the traffic needed for boot, metadata, DNS and management, and the build reports that exception. Unknown groups and rules whose ports cannot be read are reported and grant no additional traffic. Review the reported differences before cutover.
* **A per-instance public IP is not supported.** An instance that requests one (`associate_public_ip_address`) stops the deployment with an error, because this target does not create a per-instance public IP.
* **Disk performance follows OCI's capacity and performance settings.** The mapping selects native capacity and VPUs/GB for provisioned settings and reports increases or shortfalls. Native minimum capacity can raise size and cost, with a build warning. VM limits and attachment requirements still apply; this is not a measured performance guarantee.
* **Attached data disks are created empty.** An inline `ebs_block_device`, or an in-stack `aws_ebs_volume` attached to an ordinary instance, becomes OCI block volumes. Existing data is never copied. Snapshots, external volumes and multi-attach are not supported. Data disks on an instance using `count` or `for_each`, or in a launch template, stop the build. A computed `delete_on_termination` also stops the build. Data disks are separate stack resources: they survive VM replacement but are deleted with the stack. This differs from AWS inline delete\_on\_termination behavior; the build reports it.
* **Auto Scaling groups are not supported on this target.** This mapping creates standalone VMs but does not translate the group's launch template, replica count or scaling policy to an OCI instance pool. Define and operate the native fleet separately, or use a target with a supported fleet mapping.

#### Other considerations

Oracle operates the hardware, and Tensor9 runs nothing in the instance's compute path.

* **Before going live.** Confirm the instance boots and your user data completes. If your code reads EC2 instance metadata, give it another source for its instance details and credentials. Review any warning that a dynamic group could not be narrowed, and account for OCI policy propagation during startup.
* **When the instance is replaced.** Changing the image, subnet, SSH key pair, availability zone, CPU options, placement or tenancy, root-volume encryption, or user data with `user_data_replace_on_change` replaces the instance. OCI's own rules can replace it in other cases.
* **Moving from AWS.** The instance starts from a fresh image. Data on the instance's EBS volumes is not copied, so move it separately before cutover.

#### Runtime management on OCI

The EC2 management API is not offered on OCI: RunInstances, DescribeInstances and the other EC2 lifecycle calls are not answered for OCI instances, and EC2 instance metadata is not available in the guest. Manage and inspect the instances through their infrastructure configuration and OCI's own tools.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

No curated instance comparison is available for this source and target configuration yet.

Compare the published named instance mappings; a free-form EC2 cost calculator is not offered.

## On Scaleway

### Scaleway Instance

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Fleet / cross-resource discovery | Control plane | Out of scope | Full surface | Not supported: The EC2 management API is not offered on this target, so no EC2 discovery or enumeration is answered. |
| RunInstances / TerminateInstances / ModifyInstanceAttribute / CreateTags | Control plane | Out of scope | Full surface | The EC2 management API is not offered on this target: RunInstances, TerminateInstances, ModifyInstanceAttribute and CreateTags are not answered. Manage the VM through its infrastructure configuration and the cloud's own tools. |
| Instance provisioning | Instance lifecycle | Supported | Common | your aws\_instance / launch template compiles to a native Scaleway Instance: the cheapest size with at least the same vCPUs and memory, CPU architecture and GPU type (the family rules are in the summary) |
| Start / Stop / Reboot / Terminate | Instance lifecycle | Supported | Common | Infrastructure configuration maps to native VM lifecycle controls; this row does not establish runtime EC2 API support. |
| DescribeAvailabilityZones | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeSecurityGroups | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM; native firewall translation does not add an EC2 DescribeSecurityGroups endpoint. |
| DescribeVolumes / DescribeNetworkInterfaces / DescribeTags (the caller's own) | Metadata + discovery | Out of scope | Most usage | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. |
| DescribeVpcs / DescribeSubnets | Metadata + discovery | Out of scope | Common | Not answered for a call from inside a compiled VM: no Tensor9 endpoint is configured in the guest. The network describes for the VPC records are on the VPC card. |
| Instance metadata (IMDS) + DescribeInstances (the running instance) | Metadata + discovery | Out of scope | Common | EC2 instance metadata and AWS role credentials are not served inside a compiled VM. Use the target's own metadata service where one is available. A DescribeInstances call from inside a compiled VM is not answered with its own instance, because no Tensor9 endpoint is configured in the guest. |
| Public IP on the instance | Network | Out of scope | Common | a request for a per-instance public IP stops the build; target-native addressing still needs review |
| Security groups on the instance | Network | Out of scope | Common | security-group references on Scaleway instances stop the build; no native rule binding is emitted |
| Attached data volumes (EBS volumes) | Storage | Out of scope | Common | data disks on Scaleway instances are not supported and stop the build |
| Root volume | Storage | Partial | Common | root settings map within the target's native disk limits; some targets refuse pinned size or type, and no source disk contents are copied |

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

No curated instance comparison is available for this source and target configuration yet.

Compare the published named instance mappings; a free-form EC2 cost calculator is not offered.

## Costs

Estimated monthly service charges for each backend with a published cost model, at one sampled workload from that model's cost curve. Adapter hosting and Tensor9 fees are excluded. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method, what the estimates include and how to read their qualifications.

| Origin API | Backend | Sampled workload | Price basis | Origin USD/month | Backend USD/month | Difference | Mapping |
| - | - | - | - | -: | -: | -: | - |
| `aws::1.0.0::ec2::control` | Compute Engine | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |
| `aws::1.0.0::ec2::control` | Virtual Machines | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |
| `aws::1.0.0::ec2::instance` | Compute Engine | m6i.large → n2-standard-2; Number of running instances: 8 instances; n2-standard-2 | Cited list prices, 2026-10-22 | 560.64 | 567.17 | +6.53 | Service adapter |
| `aws::1.0.0::ec2::instance` | Compute Instance | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |
| `aws::1.0.0::ec2::instance` | Droplet | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |
| `aws::1.0.0::ec2::instance` | KubeVirt VM | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |
| `aws::1.0.0::ec2::instance` | Scaleway Instance | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |
| `aws::1.0.0::ec2::instance` | Virtual Machines | No curated instance comparison | Cited list prices, 2026-10-22 | Unavailable | Unpriced | Unavailable | Service adapter |

Difference means backend minus origin; a positive difference means the backend costs more. Workloads and target configurations differ by model, so compare each row's difference at its stated workload rather than charges across rows.
Cost curves across workload sizes, with every assumption and exclusion: [EC2 Control Plane costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/additional-services/aws-ec2-control), [EC2 Instances costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/additional-services/aws-ec2-instance).

## Service level agreements

> [!WARNING]
>
> These tables show Tensor9's standard service levels and adapters whose standard terms are still being defined. Your signed agreement determines the SLAs, covered adapters and operations, limits, remedies and support terms that apply to your deployment.

Listed terms cover requests sent through this service adapter. They do not cover direct connections to the target service or replace the cloud provider's own SLA. Each origin-to-target pair has its own terms or an explicit pending status.

See the [SLA tables](https://docs.tensor9.com/cloud-adapter-early-access/support/service-adapter-slas.md), [measurement rules](https://docs.tensor9.com/cloud-adapter-early-access/support/service-levels.md), and [scaling conditions](https://docs.tensor9.com/cloud-adapter-early-access/support/scaling-and-limits.md).

### EC2 Instances to Virtual Machines

**SLA status:** Pending

Operation-specific service levels for this adapter have not yet been defined. This adapter does not inherit another target service's latency budget. Your signed agreement sets the applicable terms.

### EC2 Instances to Droplet

**SLA status:** Pending

Operation-specific service levels for this adapter have not yet been defined. This adapter does not inherit another target service's latency budget. Your signed agreement sets the applicable terms.

### EC2 Instances to Compute Engine

**SLA status:** Pending

Operation-specific service levels for this adapter have not yet been defined. This adapter does not inherit another target service's latency budget. Your signed agreement sets the applicable terms.

### EC2 Instances to KubeVirt VM

**SLA status:** Pending

Operation-specific service levels for this adapter have not yet been defined. This adapter does not inherit another target service's latency budget. Your signed agreement sets the applicable terms.

### EC2 Instances to Compute Instance

**SLA status:** Pending

Operation-specific service levels for this adapter have not yet been defined. This adapter does not inherit another target service's latency budget. Your signed agreement sets the applicable terms.

### EC2 Instances to Scaleway Instance

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Instance and volume lifecycle admission adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::ec2`: `AttachVolume`, `CreateVolume`, `RebootInstances`, `RunInstances`, `StartInstances`, `StopInstances`, `TerminateInstances` | at most 20 resources/tags per call; image/volume payload not transferred through adapter; readiness separate. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::ec2`: `AttachVolume`, `CreateVolume`, `RebootInstances`, `RunInstances`, `StartInstances`, `StopInstances`, `TerminateInstances` | IMDS and describe responses identify the same instance, network and attached resources. Lifecycle success means desired state is durably recorded, IDs are stable, foreign resources are not exposed, and unsupported mutation forms fail before partial target changes. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

Local metadata and self-discovery are synthesized from the resolved deployment without a cloud round trip. Fleet reads and lifecycle mutations use the control-plane record/reconcile path for scaleway::1.0.0::instance. Native VM or disk creation time is reported as readiness, not hidden inside the adapter processing estimate.

#### How the latency targets were chosen

**Instance and volume lifecycle admission: +20 ms monthly p99 (adapter-added).** `AttachVolume`, `CreateVolume`, `RebootInstances`, `RunInstances`, `StartInstances`, `StopInstances`, `TerminateInstances`. Validation, durable desired-state commit and reconciliation scheduling.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Self-discovery scales per host and should remain independent of fleet size. Fleet lists are bounded pages; lifecycle writes serialize per resource identity while unrelated instances and volumes reconcile concurrently. Qualification fixes filter count, returned resources, tag count and mutation fan-out.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

IMDS and describe responses identify the same instance, network and attached resources. Lifecycle success means desired state is durably recorded, IDs are stable, foreign resources are not exposed, and unsupported mutation forms fail before partial target changes.

#### Example and diagnosis

DescribeInstances for the calling VM is a local identity read. RunInstances records one bounded launch request and returns an adapter identity; the target VM becoming ready is a separate state transition. A later DescribeInstances must report that same identity and observed readiness.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

## Install and run

The documentation and SLAs are public. Downloading and running the Cloud Adapter binary requires an entitled customer account. Set `T9_API_KEY` as described in [Install and Authenticate](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/install-and-authenticate.md), then list the adapters your account may use with this origin:

```sh theme={null}
tensor9 adapt svc list \
  -origin aws::1.0.0::ec2::instance
```

The result is limited to directed mappings for this origin that your account is entitled to use. Use a returned backend identifier when configuring the adapter or investigating a request.

Request binary access from [hello@tensor9.com](mailto:hello@tensor9.com) if your account does not yet include this direction.

## Existing data and credentials

Selecting a backend does not copy existing data, credentials or access policies. Plan and verify migration separately before changing an application's endpoint. Do not assume an identifier, credential or encrypted value from the origin service works unchanged on the target.

## Configure, tune and debug

Start with [setup](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/overview.md) and [configuration](https://docs.tensor9.com/cloud-adapter-early-access/configuration/overview.md). Use [tuning](https://docs.tensor9.com/cloud-adapter-early-access/tuning/overview.md) to understand supported request tags, [debugging](https://docs.tensor9.com/cloud-adapter-early-access/debugging/overview.md) to investigate a request, and [High Fidelity Cloud Emulators](https://docs.tensor9.com/cloud-adapter-early-access/local-testing/overview.md) to validate a bounded reproduction.

For requests that go through an entitled service adapter, use [tensor9 explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/explain.md) and [x-t9-explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/response-headers.md) to inspect the selected mapping.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.