|
| 1 | +# Deploy the Select AI A2A server to Google Cloud |
| 2 | + |
| 3 | +`gcloud/deploy.sh` builds or selects a Select AI container image, creates or |
| 4 | +updates a private Cloud Run service, and configures its database secrets. Run |
| 5 | +it on a machine with the [Google Cloud CLI](https://cloud.google.com/sdk/docs/install) |
| 6 | +installed and authenticated to the target project. |
| 7 | + |
| 8 | +## IAM permissions |
| 9 | + |
| 10 | +The scripts use the active `gcloud` identity. They do not elevate its access. |
| 11 | + |
| 12 | +### Deployer (the active gcloud identity) |
| 13 | + |
| 14 | +| Operation | Required permissions | |
| 15 | +| --- | --- | |
| 16 | +| Inspect and create the Artifact Registry repository | `artifactregistry.repositories.get`, `artifactregistry.repositories.create` | |
| 17 | +| Inspect and create the default runtime service account | `iam.serviceAccounts.get`, `iam.serviceAccounts.create` | |
| 18 | +| Deploy or update Cloud Run | `run.services.create`, `run.services.update`, `run.services.get`, `run.operations.get`; `iam.serviceAccounts.actAs` on the runtime service account; `artifactregistry.repositories.downloadArtifacts` on the image repository | |
| 19 | +| With `--build`, upload local source, submit, and wait for a build | `storage.buckets.get`, `storage.objects.create` on the configured source-staging bucket; `cloudbuild.builds.create`, `cloudbuild.builds.get`, `serviceusage.services.use` | |
| 20 | +| Inspect, create, and add versions to database or wallet secrets | `secretmanager.secrets.get`, `secretmanager.secrets.create`, `secretmanager.versions.add` | |
| 21 | +| Grant the runtime account access to those secrets | `secretmanager.secrets.getIamPolicy`, `secretmanager.secrets.setIamPolicy` | |
| 22 | +| Grant Gemini Enterprise and the active gcloud identity access to the service | `run.services.getIamPolicy`, `run.services.setIamPolicy` | |
| 23 | +| Obtain the project number | `resourcemanager.projects.get` | |
| 24 | + |
| 25 | +### Runtime service account |
| 26 | + |
| 27 | +| Operation | Required permissions | |
| 28 | +| --- | --- | |
| 29 | +| Read database and wallet secrets while serving requests | `secretmanager.versions.access` | |
| 30 | + |
| 31 | +### Other service identities |
| 32 | + |
| 33 | +| Principal | Operation | Required permissions | |
| 34 | +| --- | --- | --- | |
| 35 | +| Cloud Build execution service account | With `--build`, push the built image | `artifactregistry.repositories.uploadArtifacts` | |
| 36 | +| Gemini Enterprise service agent | Invoke the private Cloud Run service | `run.routes.invoke` | |
| 37 | +| Active gcloud identity | Fetch the Agent Card after deployment | `run.routes.invoke` | |
| 38 | + |
| 39 | +The source-staging bucket is Cloud Build's default unless a custom bucket is |
| 40 | +configured. Cloud Build also needs access to its build-log destination; the |
| 41 | +default same-project build account has that access. If your organization uses |
| 42 | +a custom build service account, source bucket, or log bucket, its administrator |
| 43 | +must grant the equivalent Cloud Storage permissions on those resources. |
| 44 | + |
| 45 | +Google Cloud references: [Service Usage access control](https://cloud.google.com/service-usage/docs/access-control), [Cloud Run deployment permissions](https://cloud.google.com/run/docs/reference/iam/roles), [Secret Manager access control](https://cloud.google.com/secret-manager/docs/access-control), [Artifact Registry roles](https://cloud.google.com/artifact-registry/docs/access-control), and [Cloud Build roles](https://cloud.google.com/build/docs/iam-roles-permissions). |
| 46 | + |
| 47 | +The rows that set IAM policy are administrative mutations. They are present |
| 48 | +because `deploy.sh` creates and rotates secrets and configures private-service |
| 49 | +invocation. If your customer deployment identity must not change IAM, provision |
| 50 | +the secrets and the `secretmanager.versions.access`/`run.routes.invoke` |
| 51 | +permissions beforehand, then |
| 52 | +remove those policy-setting commands from the deployment workflow. |
| 53 | + |
| 54 | +## Prerequisite: enable project APIs once |
| 55 | + |
| 56 | +An administrator must enable these APIs once for the project: |
| 57 | + |
| 58 | +```bash |
| 59 | +gcloud services enable \ |
| 60 | + run.googleapis.com \ |
| 61 | + cloudbuild.googleapis.com \ |
| 62 | + artifactregistry.googleapis.com \ |
| 63 | + secretmanager.googleapis.com \ |
| 64 | + discoveryengine.googleapis.com \ |
| 65 | + --project PROJECT_ID |
| 66 | +``` |
| 67 | + |
| 68 | +## Deploy (and update) the A2A server |
| 69 | + |
| 70 | +```bash |
| 71 | +gcloud/deploy.sh --build |
| 72 | +``` |
| 73 | + |
| 74 | +On the first deployment, the script prompts for the ADB user, password, and |
| 75 | +connect descriptor. It stores them in Secret Manager under names based on the |
| 76 | +Cloud Run service, and grants only the runtime service account access. The |
| 77 | +container receives the values as `SELECT_AI_USER`, `SELECT_AI_PASSWORD`, and |
| 78 | +`SELECT_AI_DB_CONNECT_STRING`; they are never placed in the image or source |
| 79 | +tree. |
| 80 | + |
| 81 | +### Optional: Autonomous Database mTLS wallet |
| 82 | + |
| 83 | +The Select AI SDK already supports `wallet_location` and `wallet_password`. |
| 84 | +For Cloud Run, pass the path to the downloaded Autonomous Database wallet ZIP |
| 85 | +on the first deployment (or when replacing it): |
| 86 | + |
| 87 | +```bash |
| 88 | +gcloud/deploy.sh --wallet-archive /path/to/Wallet_database.zip |
| 89 | +``` |
| 90 | + |
| 91 | +The script prompts for the wallet password, stores the ZIP and password as |
| 92 | +service-specific Secret Manager secrets, and grants access only to the runtime |
| 93 | +service account. Cloud Run mounts the ZIP read-only; its A2A launcher expands it |
| 94 | +into ephemeral `/tmp` storage before starting the SDK, verifies it contains |
| 95 | +`ewallet.pem`, and sets `SELECT_AI_WALLET_LOCATION` to that file's directory. |
| 96 | +Do not commit the wallet ZIP or put its contents in the image. |
| 97 | + |
| 98 | +Later deploys reuse the wallet. To replace it, pass `--wallet-archive` again. |
| 99 | + |
| 100 | +The first deployment needs `--build` (or an explicit `--image-uri`). Later |
| 101 | +deployments reuse the image already deployed to the service, so changing Cloud |
| 102 | +Run configuration or secrets does not create another image. The command |
| 103 | +deploys private Cloud Run, sets the final public URL in the Agent Card, grants your active |
| 104 | +gcloud identity and Gemini Enterprise Discovery Engine service agent the |
| 105 | +`run.routes.invoke` permission for this Cloud Run service. |
| 106 | + |
| 107 | +The default Cloud Run service is `oracle-a2a-agent`. Its default Agent Team, |
| 108 | +installed in Oracle Database, is `ORACLE_AI_DATABASE_AGENT`. Override either |
| 109 | +with explicit options: |
| 110 | + |
| 111 | +```bash |
| 112 | +gcloud/deploy.sh --service sales-analyst-a2a --a2a-team SALES_ANALYST |
| 113 | +``` |
| 114 | + |
| 115 | +Use a distinct `--service` value for each A2A team. Each service gets distinct Secret |
| 116 | +Manager secret names by default, so credentials remain attached to that A2A |
| 117 | +server. |
| 118 | + |
| 119 | +`--max-instances` controls the number of Cloud Run containers. Each container |
| 120 | +can use up to 10 Oracle connections by default; change that limit with |
| 121 | +`--pool-max-size`, for example `gcloud/deploy.sh --pool-max-size 20`. |
| 122 | + |
| 123 | +### Update the Select AI SDK or this repository |
| 124 | + |
| 125 | +Update the checkout (or modify its dependency version), then explicitly build |
| 126 | +and deploy the new image: |
| 127 | + |
| 128 | +```bash |
| 129 | +git pull |
| 130 | +gcloud/deploy.sh --build |
| 131 | +``` |
| 132 | + |
| 133 | +`--build` creates a freshly tagged image from the current source; without it, |
| 134 | +the existing image is reused. Existing database secrets are reused without |
| 135 | +prompting. To rotate the ADB credentials, explicitly request it: |
| 136 | + |
| 137 | +```bash |
| 138 | +gcloud/deploy.sh --rotate-db-credentials |
| 139 | +``` |
| 140 | + |
| 141 | +### What `cloudbuild.yaml` does |
| 142 | + |
| 143 | +`gcloud/deploy.sh --build` uses `gcloud/cloudbuild.yaml` to tell Cloud Build to build |
| 144 | +`docker/Dockerfile` and push it to Artifact Registry. It is build configuration, |
| 145 | +not a command you run. The build context is the repository root, so the image |
| 146 | +can install the Select AI source from `pyproject.toml` and `src/`. |
| 147 | + |
| 148 | +### Cloud Build upload contents |
| 149 | + |
| 150 | +Before the build starts, `gcloud builds submit` archives and uploads the |
| 151 | +repository root. The root `.gcloudignore` excludes local virtual environments, |
| 152 | +generated documentation, test data, caches, credentials, and Git metadata. |
| 153 | +Keep `src/`, `pyproject.toml`, `docker/`, and `gcloud/` in the upload; they are |
| 154 | +required to build the image. If the upload is unexpectedly large, check local |
| 155 | +directories against `.gcloudignore` before running `--build` again. |
| 156 | + |
| 157 | +After a successful deployment, the script prints the A2A Agent Card JSON. |
| 158 | +Paste that JSON into Gemini Enterprise to register the private service. The |
| 159 | +required Gemini Enterprise invocation permission has already been added. |
0 commit comments