Add GCP onboarding setup scripts - #2269
Conversation
Extend the onboarding scripts to GCE VMs (gcp_vm) and GKE clusters (gcp_gke), mirroring the Azure split: - aws/setup.sh: gcp_vm trust federates the IAM role directly with accounts.google.com (no OIDC provider resource; Google is a built-in web-identity provider), conditioned on the service account unique ID (:sub) and the sts.amazonaws.com audience (:oaud). gcp_gke registers the cluster's OIDC issuer as an IAM OIDC provider and trusts the amazon-cloudwatch/cloudwatch-agent service account. - gcp/setup.sh: new GCP-side script with the two-mode design keyed on CWAGENT_AWS_ROLE_ARN. Identity discovery is read-only: the VM's service account unique ID, or the cluster's OIDC issuer URL, constructed under locations/ for zonal and regional clusters alike. A VM install pushes install.sh over gcloud compute ssh behind a reachability probe, printing the command when SSH cannot reach the VM. A GKE install runs the CloudWatch Observability Helm chart with k8sMode=GKE when helm, kubectl, and gke-gcloud-auth-plugin are present, printing the commands otherwise. - install.sh: accept CWAGENT_CLOUD=gcp through the same web-identity branch as azure (set-env CWAGENT_ROLE_ARN and AWS_REGION, then fetch-config -m auto). - setup.sh: dispatcher chain gcp/setup.sh (identity) -> aws/setup.sh (trust) -> gcp/setup.sh (install) with the same cross-shell resume flow as Azure. - README.md: document the new platforms and flow.
Extend the gcp_vm trust conditions from :sub + :oaud to :aud + :sub + :oaud, the recommended trust policy form for Google-issued tokens. On service-account identity tokens the azp claim (matched by :aud) carries the service account unique ID, so the added key pins the authorized party alongside the subject and the requested audience, keeping the policy provably scoped to a single Google identity under automated policy analysis.
| # Describe doubles as the existence and access check, like the Azure | ||
| # script's scoped account show. | ||
| gcloud projects describe "${PROJECT}" --format='value(projectId)' >/dev/null 2>&1 || | ||
| die "cannot access project ${PROJECT} (run 'gcloud auth login'; check 'gcloud projects list')" |
There was a problem hiding this comment.
Normalize PROJECT to the project ID. We're using it directly in the GKE OIDC issuer URL, which needs it to be the project ID to match the issued token, but CWAGENT_GCP_PROJECT could come in as a project number.
The current describe call can take in either the ID or the number (https://docs.cloud.google.com/sdk/gcloud/reference/projects/describe) and it already is set to output the project ID. Capture the value and replace the PROJECT with it.
| # Describe doubles as the existence and access check, like the Azure | |
| # script's scoped account show. | |
| gcloud projects describe "${PROJECT}" --format='value(projectId)' >/dev/null 2>&1 || | |
| die "cannot access project ${PROJECT} (run 'gcloud auth login'; check 'gcloud projects list')" | |
| # Describe doubles as the existence and access check, like the Azure | |
| # script's scoped account show. | |
| _resolved_project=$(gcloud projects describe "${PROJECT}" --format='value(projectId)' 2>/dev/null) || | |
| die "cannot access project ${PROJECT} (run 'gcloud auth login'; check 'gcloud projects list')" | |
| PROJECT="${_resolved_project}" |
| # gcloud config default is used when unset) | ||
| # CWAGENT_EMIT_ENV When set (1/true/yes/on), print eval-able KEY='value' | ||
| # lines on stdout and route all logging to stderr | ||
| # gcp_vm: |
There was a problem hiding this comment.
Rename to gcp_gce to match aws_ec2. Azure VM was azure_vm because they don't have a separate product name.
Rename the related functions as well.
| # CWAGENT_EMIT_ENV When set (1/true/yes/on), print eval-able KEY='value' | ||
| # lines on stdout and route all logging to stderr | ||
| # gcp_vm: | ||
| # CWAGENT_GCP_ZONE Zone the VM lives in |
There was a problem hiding this comment.
Would it make sense to collapse the CWAGENT_GCP_ZONE and CWAGENT_GCP_LOCATION into a single CWAGENT_GCP_LOCATION?
Both of the variable names read as generic GCP, so users may end up using either on either platform. If I were trying to set up a zonal GKE cluster, I would expect CWAGENT_GCP_ZONE to work and if I were trying to set up a GCE instance, I may expect CWAGENT_GCP_LOCATION to work as well.
Since zone is a valid location, one variable covers both cleanly:
gcp_gcepasses it as--zone, so a region fails the describe and the script's die points at the zone
$ gcloud compute instances describe <instance_name> --zone us-east1 --project <project_id> --format 'value(serviceAccounts[0].email)' 2>&1
ERROR: (gcloud.compute.instances.describe) Could not fetch resource:
- Invalid value for field 'zone': 'us-east1'. Unknown zone.
$ echo $?
1
gcp_gkepasses it as--location
Would help to remove some confusion.
| # lines on stdout and route all logging to stderr | ||
| # gcp_vm: | ||
| # CWAGENT_GCP_ZONE Zone the VM lives in | ||
| # CWAGENT_GCP_VM_NAME VM name |
There was a problem hiding this comment.
nit: GCP refers to their VMs as Instances. Consider renaming to CWAGENT_GCP_INSTANCE_NAME.
https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/describe
Description of the issue
The onboarding setup scripts cover AWS and Azure platforms. The agent now
supports GCE (auto-detected host mode) and GKE (
RUN_IN_GKEvia the Helmchart), but there is no scripted onboarding for GCP workloads.
Important
Do not merge until the 1.300073.0 agent release completes its rollout: the
install commands fetch these scripts and the released agent from
main/the release buckets at install time, and GCE auto-detection first ships in
1.300073.0.
Description of changes
Extends the onboarding scripts to GCE VMs (
gcp_vm) and GKE clusters(
gcp_gke), mirroring the Azure split:aws/setup.sh:gcp_vmtrust federates the IAM role directly withaccounts.google.com(no OIDC provider resource; Google is a built-inweb-identity provider), pinning all three Google condition keys: the
service account unique ID (
:sub), thests.amazonaws.comaudience(
:oaud), and the authorized party (:aud, the unique ID again onservice-account tokens) - the trust policy form recommended for
Google-issued tokens (AWS Security Blog).
The audience condition matches the audience the agent requests for its
identity tokens and rejects tokens minted for other services being
replayed against STS, mirroring how the Azure trust policies pin their
requested audience.
gcp_gkeregisters the cluster's OIDC issuer as an IAM OIDC provider andtrusts the
amazon-cloudwatch/cloudwatch-agentservice account.gcp/setup.sh: new GCP-side script with the two-mode design keyed onCWAGENT_AWS_ROLE_ARN. Identity discovery is read-only: the VM's serviceaccount unique ID, or the cluster's OIDC issuer URL (constructed under
locations/for zonal and regional clusters alike). A VM install pushesinstall.shovergcloud compute sshbehind a reachability probe,printing the command when SSH cannot reach the VM. A GKE install runs the
CloudWatch Observability Helm chart with
k8sMode=GKEwhenhelm,kubectl, andgke-gcloud-auth-pluginare present, printing the commandsotherwise.
install.sh: acceptsCWAGENT_CLOUD=gcpthrough the same web-identitybranch as azure (
set-env CWAGENT_ROLE_ARNandAWS_REGION, thenfetch-config -m auto).setup.sh: dispatcher chaingcp/setup.sh(identity) ->aws/setup.sh(trust) ->
gcp/setup.sh(install), with the same cross-shell resume flowas Azure.
README.md: documents the new platforms and flow.License
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Tests
sh -nandshellcheckclean on all touched scripts;make fmt-shclean.gcp_vmidentity verified against a real GCE VM: service account email andunique ID discovery,
CWAGENT_EMIT_ENVstdout purity, interactive wizard.gcp_vmtrust verified against a test account: role create path,idempotent re-run ("trust policy up to date"), trust policy content, and
policy attachment. The generated trust policy was validated end to end
with a manual
sts assume-role-with-web-identityexchange using anidentity token minted on the VM (credentials returned, subject = the
service account unique ID). Re-verified after extending the conditions to
the three-key form: the rendered policy passes the Zelkova automated
reasoning check (the engine behind IAM Access Analyzer) as not publicly
assumable, and a fresh role create plus idempotent re-run with the updated
script succeeded against the same test account.
gcp_gkeidentity and trust verified against a real zonal cluster: issuerconstruction, IAM OIDC provider create path, both trust statements
coexisting on one role, and the printed helm command matching the chart's
validated GKE install.
remote transcript, and failure propagation. A side-loaded
install.shranthrough download/install/set-env on Debian 12; the full green install
completes once the 1.300073.0 agent reaches the release buckets (until
then
fetch-configcorrectly fails in on-prem mode).Requirements
make fmt-shrun