> ## 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: Azure to Google Cloud

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

This quickstart uses the Azure Blob Storage API at the application boundary and stores block blobs in Google Cloud Storage.

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

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

## Compatibility snapshot

The [Blob Storage to Google Cloud profile](/cloud-adapter/service-catalog/azure/databases-storage/blob-storage#on-google-cloud) supports block-blob CRUD and maps Azure ETag conditions to Cloud Storage generation behavior. Cloud Adapter retains lease state.

Append blobs, page blobs, and tag queries are outside the profile. Direct Cloud Storage writers bypass adapter-held leases. Existing content, metadata, and lease state are not copied automatically.

## Prerequisites

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

## Set values

```bash theme={null}
export ADAPTER_BLOB_ENDPOINT="https://adapter.example.test/origin-account"
export ORIGIN_ACCOUNT_NAME="origin-account"
export ORIGIN_ACCOUNT_KEY="use-your-test-secret-source"
export ORIGIN_CONTAINER="adapter-smoke-test"
export TARGET_BUCKET="adapter-smoke-test-gcs"
export TEST_BLOB="quickstart/azure-gcp-$(date +%s).txt"
```

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

## Write through the Azure client

```python theme={null}
import os
from azure.core.credentials import AzureNamedKeyCredential
from azure.storage.blob import BlobServiceClient, ContentSettings

service = BlobServiceClient(
    account_url=os.environ["ADAPTER_BLOB_ENDPOINT"],
    credential=AzureNamedKeyCredential(
        os.environ["ORIGIN_ACCOUNT_NAME"],
        os.environ["ORIGIN_ACCOUNT_KEY"],
    ),
)
blob = service.get_blob_client(
    container=os.environ["ORIGIN_CONTAINER"],
    blob=os.environ["TEST_BLOB"],
)
expected = b"hello from Blob Storage to Cloud Storage\n"
blob.upload_blob(
    expected,
    overwrite=True,
    content_settings=ContentSettings(content_type="text/plain"),
)
properties = blob.get_blob_properties()
assert blob.download_blob().readall() == expected
print({"etag": properties.etag, "size": properties.size})
```

## Verify Cloud Storage natively

```bash theme={null}
gcloud storage objects describe "gs://$TARGET_BUCKET/$TEST_BLOB"
gcloud storage cat "gs://$TARGET_BUCKET/$TEST_BLOB" > /tmp/cloud-adapter-target.txt
printf 'hello from Blob Storage to Cloud Storage\n' | cmp - /tmp/cloud-adapter-target.txt
```

Confirm content type, bytes, and target location. Keep Cloud Storage generation numbers in target-facing code and Azure ETags in origin-facing code.

## Test error and concurrency behavior

Request a missing blob through the Azure client and retain its Azure error code, HTTP status, request ID, and diagnostic headers. If your application uses `If-Match` or leases, add a test where one writer has stale state. Run every lease-dependent writer through Cloud Adapter.

## Clean up

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

Then confirm the current object is no longer readable with `gcloud storage objects describe`. 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. Do not delete a shared bucket as part of object cleanup.

## Before production

Test conditional requests, block upload sizes, listing and continuation, metadata, lease contention, retries, and direct-writer restrictions. Plan existing data migration separately. Define how you will resolve a timeout when the target write may have completed.

Read the full [Blob Storage profile](/cloud-adapter/service-catalog/azure/databases-storage/blob-storage) and preserve this flow in [CI/CD](/cloud-adapter/guides/ci-cd).
