omarcevi.dev / workshops / deploy-agents / 2 · Deploy

Step 2 · Deploy

8 min

In this step, you deploy the agent to Agent Runtime with its own Agent Identity. Then you let that identity call the MCP servers, and you ask the agent questions.

checkpoint branch step-2-deploy

How it works

What agents-cli deploy does. 1: It uploads the project folder with its Dockerfile. 2: Agent Runtime builds the container in a Google-managed project. It deploys the container as an autoscaled service with query and streamQuery endpoints, sessions, Memory Bank and telemetry. 3: With --agent-identity, it creates a principal for the agent. 4: grant_agent_access.sh gives that principal roles/run.invoker on the MCP servers. 5: You send questions through query or streamQuery with agents-cli run or the console playground. Optionally, agents-cli publish gemini registers the agent with Gemini Enterprise.
agents-cli deploy changes a folder into a managed, autoscaled agent. Your code never runs on a VM that you manage.

What the package contains. agents-cli deploy uploads the project and its Dockerfile, without the files that .gcloudignore excludes. Agent Runtime builds the image in a Google-managed project. Thus, the build is not in your Cloud Build history. The values in .env become environment variables of the deployed agent. For this reason, do not put secrets in .env.

What Agent Runtime gives you. You get a container that scales to zero, behind two IAM-protected methods, :query and :streamQuery. The defaults are min 0 and max 10 instances, 1 vCPU and 4 GiB. The platform stores the sessions. Traces and logs go to Cloud Trace and Cloud Logging. The console has a playground for each deployment.

Agent Identity. With --agent-identity, the agent gets its own principal, principal://agents.global.…/reasoningEngines/ID. A SPIFFE certificate supports this principal. You grant roles to the agent, not to a shared service account. When you delete the agent, its access stops.

Why the model runs on global. Agent Runtime is in europe-west1, but Google serves Gemini 3.x Flash from the global and eu endpoints. With Agent Identity, the SDK calls Google APIs on their mTLS hostnames. The eu endpoint does not have an mTLS hostname, so the agent uses global.

Gemini Enterprise. agents-cli publish gemini registers the deployed agent in a Gemini Enterprise app. There, employees use the agent together with their other agents. This step needs a Gemini Enterprise app, and it is optional in this lab.

Run

Deploy the agent (approximately 5 minutes). Read the section above while the deploy runs.

source .workshop.env
agents-cli deploy --project $PROJECT_ID --agent-identity --no-confirm-project

Then give the agent identity access to the MCP servers. This script also sets the Memory Bank topics for step 3:

./scripts/grant_agent_access.sh

Ask the agent questions. IAM grants need one or two minutes to apply. If an answer says that the HRIS or the compensation system is not available, ask again.

AGENT_URL=$(./scripts/agent_url.sh)
agents-cli run --url "$AGENT_URL" --mode adk "What can you help me with?"
agents-cli run --url "$AGENT_URL" --mode adk "How many unused leave days can I carry over?"
agents-cli run --url "$AGENT_URL" --mode adk "What is the salary band for an L5 in Istanbul?"

Remember the last answer: the agent read the compensation system. In step 4, a policy stops these calls, and you do not change the code.

Optional: open the console playground. Go to Agent Platform → Agents → Deployments → workplace-assistant → Playground.

Expected result

🔧 Creating agent identity for: workplace-assistant 🔐 Granting IAM roles to: principal://agents.global.proj-123456789012.system.id.goog/resources/aiplatform/projects/123456789012/locations/europe-west1/reasoningEngines/1913890203655733248 🚀 Updating agent: workplace-assistant (this can take a few minutes)... ✅ Deployment successful! [user]: How many unused leave days can I carry over? [concierge]: [hr_policy_agent]: You can carry up to 5 unused days into the next year. They expire on 31 March. [01-leave-policy.md#carry-over]

agents-cli run --url always sends the user id cli-user. The demo changes this id to the fictional employee Deniz Kaya (platform team, Istanbul). Gemini Enterprise sends the user who signed in.

Check

./scripts/check.sh 2
✔ Agent Identity: principal://agents.global.proj-123456789012.system.id.goog/… ✔ agent may invoke hris-mcp ✔ agent may invoke ticketing-mcp ✔ agent may invoke compensation-mcp ✔ handbook answer: You can carry up to 5 unused days… ==> Step 2 checks passed.
If this fails
confirmation required … --project
A deploy without a prompt needs --project and --no-confirm-project, as in the command above.
Deploy fails on setIamPolicy
With Agent Identity, the first deploy grants six project roles to the agent. Thus, you need resourcemanager.projects.setIamPolicy, which the Owner role includes. If you do not have this permission, deploy with --no-agent-identity. Then, in step 4, use the fallback instead of Agent Gateway.
“HRIS server is unavailable” immediately after the deploy
The run.invoker grants need one or two minutes to apply. Ask again. Until then, the Cloud Run log shows The IAM principal lacks run.routes.invoke.
The first answer takes a minute
This is a cold start, because the agent and the MCP servers scale to zero. Later answers take 5–20 seconds.
A question does not get an answer
Sometimes, the shared model capacity stops a call. The agent stops a model call after 25 seconds and tries it again, up to three times.
No deployed agent from the scripts
Run the scripts from the repo root. The deploy writes deployment_metadata.json there.