> ## 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.

# Quickstart: Google Cloud to Azure

> Send Google Cloud Storage requests through Cloud Adapter to Azure Blob Storage.

This route preserves the Google Cloud Storage API while Cloud Adapter stores object data in Azure Blob Storage.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/tensor9/3qwgIru3kCfHriJC/images/diagrams/cloud-adapter-quickstart-google-cloud-to-azure-dark.svg?fit=max&auto=format&n=3qwgIru3kCfHriJC&q=85&s=27b25b8b67b938c7fbe19f7902447002" alt="Google Cloud API requests pass through Tensor9 Cloud Adapter to Azure services." width="1100" height="360" data-path="images/diagrams/cloud-adapter-quickstart-google-cloud-to-azure-dark.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/tensor9/3qwgIru3kCfHriJC/images/diagrams/cloud-adapter-quickstart-google-cloud-to-azure-light.svg?fit=max&auto=format&n=3qwgIru3kCfHriJC&q=85&s=31ba5b9f96a044e5f2ab9bc0a95ecb01" alt="Google Cloud API requests pass through Tensor9 Cloud Adapter to Azure services." width="1100" height="360" data-path="images/diagrams/cloud-adapter-quickstart-google-cloud-to-azure-light.svg" />
</Frame>

## Compatibility snapshot

The [Cloud Storage to Azure profile](/cloud-adapter/service-catalog/google-cloud/databases-storage/gcs#on-azure) supports object CRUD and compose through Azure block lists. Each bucket maps to a container, the profile marks bucket lifecycle as supported, and generation preconditions adapt to Blob ETags.

Google V4 signed URLs, retention policy, and `ARCHIVE` reads are rejected. Uniform access is partial. Existing data, versions, and signed links are not migrated.

## Prerequisites

* an installed Google Cloud-origin endpoint;
* a Cloud Storage to Blob Storage service adapter;
* an origin-side Google credential;
* an Azure runtime identity with access to one test container;
* a separate Azure verification identity;
* Python 3 with `google-cloud-storage` and Azure CLI.

## Set values

```bash theme={null}
export ADAPTER_STORAGE_ENDPOINT="https://adapter.example.test"
export GOOGLE_CLOUD_PROJECT="origin-project"
export ORIGIN_BUCKET="adapter-smoke-test"
export AZURE_STORAGE_ACCOUNT="adaptedsmoke"
export AZURE_CONTAINER="adapter-smoke-test"
export TEST_OBJECT="quickstart/gcp-azure-$(date +%s).txt"
```

The API endpoint shape and origin authentication in this sample are deployment-specific placeholders. Use the exact endpoint and caller credential mode supplied by your Cloud Adapter deployment. Target Azure credentials remain adapter-owned.

## Write through the Google Cloud client

```python theme={null}
import os
import google.auth
from google.api_core.client_options import ClientOptions
from google.cloud import storage

credentials, _ = google.auth.default()
client = storage.Client(
    project=os.environ["GOOGLE_CLOUD_PROJECT"],
    credentials=credentials,
    client_options=ClientOptions(api_endpoint=os.environ["ADAPTER_STORAGE_ENDPOINT"]),
)

blob = client.bucket(os.environ["ORIGIN_BUCKET"]).blob(os.environ["TEST_OBJECT"])
expected = b"hello from Cloud Storage to Blob Storage\n"
blob.upload_from_string(expected, content_type="text/plain")
blob.reload()
assert blob.download_as_bytes() == expected
print({"generation": blob.generation, "etag": blob.etag, "size": blob.size})
```

## Verify Azure natively

```bash theme={null}
az storage blob show \
  --account-name "$AZURE_STORAGE_ACCOUNT" \
  --container-name "$AZURE_CONTAINER" \
  --name "$TEST_OBJECT" \
  --auth-mode login

az storage blob download \
  --account-name "$AZURE_STORAGE_ACCOUNT" \
  --container-name "$AZURE_CONTAINER" \
  --name "$TEST_OBJECT" \
  --file /tmp/cloud-adapter-target.txt \
  --auth-mode login \
  --overwrite

printf 'hello from Cloud Storage to Blob Storage\n' | cmp - /tmp/cloud-adapter-target.txt
```

Verify bytes, content type, and target container. Keep target Blob ETags and origin generation semantics within their respective APIs.

## Test precondition and error behavior

Request a missing object and retain the Google API status, reason, request ID, and diagnostic headers. If the application uses generation preconditions, deliberately send one stale precondition and confirm the translated failure before relying on concurrency control.

Do not include signed-URL, retention-policy, or `ARCHIVE` workflows in this route; the target profile rejects them.

## Clean up

```python theme={null}
blob.delete()
```

Confirm that the current Azure blob is no longer readable with `az storage blob show`. Versioned or soft-delete-enabled targets can retain prior versions or recovery state; use an unversioned disposable target for this quickstart or remove the created version explicitly. Keep container deletion separate.

## Before production

Test compose sizes and ordering, generation conditions, list pagination, lifecycle, metadata, retries, and direct target writers. Plan existing data, versions, and shared-link migration separately. Establish a process for checking Azure state before retrying a timed-out mutation.

Use [Debugging Your Adapters](/cloud-adapter/debugging/overview) when the Google response and Azure state disagree.
