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

> Send AWS S3 requests through Cloud Adapter to Google Cloud Storage.

Keep an AWS S3 client unchanged while Cloud Adapter translates supported requests to Google Cloud Storage. This quickstart writes one object through the S3 API, verifies it natively in Google Cloud, exercises a translated not-found response, and removes the test object.

![AWS API requests pass through Tensor9 Cloud Adapter to Google Cloud services.](https://mintcdn.com/tensor9/ufP2gYsEkScmc1Bt/images/cloud-adapter-early-access/diagrams/cloud-adapter-quickstart-aws-to-google-cloud-dark.svg?fit=max\&auto=format\&n=ufP2gYsEkScmc1Bt\&q=85\&s=4073a29f25162cbf198124e2ff9b5e35)

## Start this route locally

Use the directed S3 to Cloud Storage mapping in the shared startup steps:

```bash theme={null}
export T9_ORIGIN_SERVICE="aws::1.0.0::s3"
export T9_BACKEND_SERVICE="google::1.0.0::gcs"
```

**1. Install or update the Tensor9 CLI**

Install the customer CLI with Homebrew, then confirm the binary is available:

```bash theme={null}
brew tap tensor9ine/tensor9
brew trust tensor9ine/tensor9
brew install tensor9
tensor9 --version
```

If `tensor9` is already installed, run `brew upgrade tensor9` instead of the install command.

**2. Authenticate with Tensor9**

To create a Tensor9 account and download an API key yourself, follow [Get a Tensor9 API key](https://docs.tensor9.com/byoc/getting-started/api-key.md).

A Tensor9 API key is required. Use the key issued during onboarding, or email [hello@tensor9.com](mailto:hello@tensor9.com) to request one for your organization. Do not share your account or key with another customer or organization.

If your secret manager has already supplied `T9_API_KEY`, skip the prompt. Otherwise, enter your key at a hidden prompt in the terminal where you will run `tensor9`:

> [tab] Bash
>
> ```bash theme={null}
> set +x
> IFS= read -r -s -p 'Tensor9 API key: ' T9_API_KEY
> printf '\n'
> export T9_API_KEY
> ```

> [tab] Zsh
>
> ```zsh theme={null}
> set +x
> IFS= read -r -s 'T9_API_KEY?Tensor9 API key: '
> printf '\n'
> export T9_API_KEY
> ```

Check that the variable is set without printing it, then verify your Tensor9 identity:

```bash theme={null}
: "${T9_API_KEY:?Set T9_API_KEY before continuing}"
tensor9 whoami
```

Confirm that the reported identity belongs to the intended customer account. Do not continue if authentication fails or the account is wrong. While `T9_API_KEY` is set, `tensor9` commands in this terminal use the key instead of any controller profile, so use a separate terminal for this work and run `unset T9_API_KEY` when you finish. Keep shell tracing disabled while using the key. Do not paste the key into commands, shell profiles, source files, screenshots or support messages.

See [Install and Authenticate](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/install-and-authenticate.md) for the planned license lifecycle, entitlements and credential boundaries.

**3. Confirm the directed service mapping**

Confirm that you exported the canonical origin and backend service names supplied by this quickstart:

```bash theme={null}
: "${T9_ORIGIN_SERVICE:?set the origin service name shown above}"
: "${T9_BACKEND_SERVICE:?set the backend service name shown above}"
printf 'Origin:  %s\nBackend: %s\n' \
  "$T9_ORIGIN_SERVICE" "$T9_BACKEND_SERVICE"
```

Then inspect the mapping before starting a process:

```bash theme={null}
tensor9 explain \
  -origin "$T9_ORIGIN_SERVICE" \
  -target "$T9_BACKEND_SERVICE" \
  -fmt Human
```

Read the supported operations and limitations for that direction. A similarly named service in the target cloud is not enough. If no directed profile exists, choose another mapping before continuing.

**4. Prepare target-cloud access**

Authenticate with the target cloud using its standard credential chain. The adapter uses that target identity when it calls the backend service.

Keep credentials in your shell, workload identity, or local credential store. Do not put secrets in the command line, source code, or screenshots.

**5. Start the service adapter**

Run one service adapter as a foreground process:

```bash theme={null}
tensor9 adapt svc run \
  --origin "$T9_ORIGIN_SERVICE" \
  --backend "$T9_BACKEND_SERVICE"
```

Leave this terminal open. This is the current foreground launcher, not the pending Docker launcher for [local development mode](https://docs.tensor9.com/cloud-adapter-early-access/deployment/single-binary.md). It calls your actual target-cloud services; it is separate from the in-memory emulator. Acquisition and license renewal require Tensor9 authentication. Keep the endpoint local to your test.

**6. Copy the listening endpoint**

When the command reports its listening endpoint, copy that exact value into a second terminal:

```bash theme={null}
export T9_CLOUD_ADAPTER_ENDPOINT="<endpoint printed by tensor9>"
```

Keep the endpoint local to the test unless you have deliberately configured network access and authentication for another machine.

**7. Run one bounded request**

Continue with this page's client or tool instructions. Point only the service under test at `T9_CLOUD_ADAPTER_ENDPOINT`, then perform one operation whose target effect you can verify independently.

Check both sides: read the origin-shaped response and inspect the native target resource. A successful client response alone does not prove that the target state is correct.

**8. Stop the local adapter**

Return to the first terminal and press **Control-C**. Confirm the process exits before deleting the test resource with the target cloud's native client.

If the request failed, preserve the request ID, adapter endpoint, operation name, target request ID, and any `x-t9-explain-*` receipt headers before stopping the process.

## What you will prove

| Boundary | Test |
| - | - |
| Origin API | AWS CLI sends S3 `PutObject`, `HeadObject`, `GetObject`, and `DeleteObject`. |
| Adaptation | Cloud Adapter translates S3 object behavior to Cloud Storage. |
| Target | The object exists in the expected Google Cloud project and bucket with identical bytes. |
| Error path | A missing object returns an AWS-shaped not-found response with diagnostic context. |

This test does not migrate existing objects, versions, bucket policies, or signed links.

## Before you begin

You need an installed AWS-origin Cloud Adapter endpoint, a configured S3 to Cloud Storage service adapter, an origin-side test identity, a Google Cloud runtime identity with access to one test bucket, AWS CLI v2, and `gcloud` for native verification.

Review [S3 on Google Cloud](https://docs.tensor9.com/cloud-adapter-early-access/service-catalog/aws/databases-storage/s3.md#on-google-cloud). The core object lifecycle is supported. Multipart upload is composed through temporary objects; `ListMultipartUploads` and `UploadPartCopy` are outside this target profile. Bucket policy, ACL, retention, and legal-hold behavior are not provided by this object endpoint.

## Set test values

```bash theme={null}
: "${T9_CLOUD_ADAPTER_ENDPOINT:?start the local adapter and copy its endpoint first}"
export AWS_PROFILE="adapter-test"
export AWS_REGION="us-east-1"
export AWS_REQUEST_CHECKSUM_CALCULATION="WHEN_REQUIRED"
export ORIGIN_BUCKET="adapter-smoke-test"
export TARGET_BUCKET="adapter-smoke-test-gcs"
export TEST_KEY="quickstart/aws-gcp-$(date +%s).txt"
printf 'hello from S3 to Cloud Storage\n' > /tmp/cloud-adapter-smoke.txt
```

Use the origin-facing bucket name in AWS commands and the native bucket name in Google Cloud commands. They may differ.

`AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED` keeps this smoke test on the required S3 checksum path. Validate optional flexible-checksum behavior separately if your application enables it.

The commands below use an explicit `--endpoint-url`. To route every S3 client in the process instead, set `AWS_ENDPOINT_URL_S3="$T9_CLOUD_ADAPTER_ENDPOINT"` and omit the command-level override.

## Verify target access first

Confirm that your verification identity can see the target bucket without using Cloud Adapter:

```bash theme={null}
gcloud storage buckets describe "gs://$TARGET_BUCKET"
```

This is a read-only verification identity. The adapter's runtime identity is configured separately and should have only the target permissions needed by the mapped operations.

## Write through the S3 API

```bash theme={null}
aws s3api put-object \
  --bucket "$ORIGIN_BUCKET" \
  --key "$TEST_KEY" \
  --body /tmp/cloud-adapter-smoke.txt \
  --content-type text/plain \
  --metadata quickstart=aws-to-google-cloud \
  --endpoint-url "$T9_CLOUD_ADAPTER_ENDPOINT" \
  --profile "$AWS_PROFILE" \
  --region "$AWS_REGION"
```

Keep the ETag and command timestamp from the response. The normal AWS CLI output does not expose arbitrary response headers; use an SDK with structured, redacted response metadata when a support workflow requires them. Do not log authorization headers or request bodies.

## Read it through both sides

```bash theme={null}
aws s3api head-object \
  --bucket "$ORIGIN_BUCKET" --key "$TEST_KEY" \
  --endpoint-url "$T9_CLOUD_ADAPTER_ENDPOINT" --profile "$AWS_PROFILE" --region "$AWS_REGION"

aws s3api get-object \
  --bucket "$ORIGIN_BUCKET" --key "$TEST_KEY" \
  --endpoint-url "$T9_CLOUD_ADAPTER_ENDPOINT" --profile "$AWS_PROFILE" --region "$AWS_REGION" \
  /tmp/cloud-adapter-origin.txt

gcloud storage objects describe "gs://$TARGET_BUCKET/$TEST_KEY"
gcloud storage cat "gs://$TARGET_BUCKET/$TEST_KEY" > /tmp/cloud-adapter-target.txt

cmp /tmp/cloud-adapter-smoke.txt /tmp/cloud-adapter-origin.txt
cmp /tmp/cloud-adapter-smoke.txt /tmp/cloud-adapter-target.txt
```

The S3 ETag and Cloud Storage generation are not interchangeable identifiers. Use each API's returned identity in its own context.

## Exercise the error mapping

```bash theme={null}
aws s3api get-object \
  --bucket "$ORIGIN_BUCKET" \
  --key "quickstart/missing-object" \
  --endpoint-url "$T9_CLOUD_ADAPTER_ENDPOINT" \
  --profile "$AWS_PROFILE" \
  --region "$AWS_REGION" \
  /tmp/cloud-adapter-missing.txt
```

Expect an AWS-shaped not-found error. S3 can return permission denied instead when the caller lacks permission to establish that the object is missing. First separate that origin-side authorization case from the adapter's Google Cloud backend permission. If the request times out, inspect Cloud Storage before retrying a mutation.

## Inspect an explanation

Use the [S3 to Cloud Storage service profile](https://docs.tensor9.com/cloud-adapter-early-access/service-catalog/aws/databases-storage/s3.md#on-google-cloud) to confirm the selected operation's coverage, then follow [Understanding Behavior with Explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/explain.md). A hypothetical explanation is the safe first choice when you are investigating how a covered request would map. The shorthand `x-t9-explain: true` executes the request as well as explaining it, so do not attach it to the completed upload merely to recreate evidence.

The [S3 to Cloud Storage worked investigation](https://docs.tensor9.com/cloud-adapter-early-access/debugging/worked-examples.md) shows how to read the origin result, explanation report and native object observation together. An explanation receipt is not proof that a write committed or that a retry is safe.

## Clean up

```bash theme={null}
aws s3api delete-object \
  --bucket "$ORIGIN_BUCKET" --key "$TEST_KEY" \
  --endpoint-url "$T9_CLOUD_ADAPTER_ENDPOINT" --profile "$AWS_PROFILE" --region "$AWS_REGION"

gcloud storage objects describe "gs://$TARGET_BUCKET/$TEST_KEY"
```

The final describe should report that the current object is no longer readable. 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. Remove only the files and object created by this test; retain the shared bucket unless its owner authorizes deletion.

## Before production traffic

Inventory the application's S3 operations, conditional headers, pagination, metadata, multipart behavior, versioning, and retry policy. Test each documented operation with representative sizes. Plan data migration separately because a new target bucket starts empty. Establish target quotas, lifecycle policy, observability, backup, and an uncertain-write procedure.

Next, read the complete [S3 target profile](https://docs.tensor9.com/cloud-adapter-early-access/service-catalog/aws/databases-storage/s3.md), then add the lifecycle to [CI/CD](https://docs.tensor9.com/cloud-adapter-early-access/guides/ci-cd.md).


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