Step 11: Install Apigee hybrid Using Helm Stay organized with collections Save and categorize content based on your preferences.
Install the Apigee hybrid runtime components
In this step, you will use Helm to install the following Apigee hybrid components:
- Apigee operator
- Apigee datastore
- Apigee telemetry
- Apigee Redis
- Apigee ingress manager
- Apigee organization
- Your Apigee environment(s)
You will install the charts for each environment one at a time. The sequence in which you install the components matters.
Pre-installation Notes
- If you have not already installed Helm v3.14.2+, follow the instructions inInstalling Helm.
Apigee hybrid uses Helm guardrails to verify the configuration before installing or upgrading a chart. You may see guardrail-specific information in the output of each of the commands in this section, for example:
# Source: apigee-operator/templates/apigee-operators-guardrails.yamlapiVersion: v1kind: Podmetadata: name: apigee-hybrid-helm-guardrail-operator namespace:APIGEE_NAMESPACE annotations: helm.sh/hook: pre-install,pre-upgrade helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded labels: app: apigee-hybrid-helm-guardrail
If any of the
helm upgradecommands fail, you can use the guardrails output to help diagnose the cause. SeeDiagnosing issues with guardrails.- Before executing any of the Helm upgrade/install commands, use the Helm dry-run feature by adding
--dry-run=serverat the end of the command. Seehelm install --hto list supported commands, options, and usage.
Installation steps
Select the installation instructions for the service account authentication type in your hybrid installation:
Kubernetes Secrets
- If you have not, navigate into your
APIGEE_HELM_CHARTS_HOMEdirectory. Run the following commands from that directory. - Install Apigee Operator/Controller:Note: This step requires elevated cluster permissions. Run
helm -horhelm install -hfor details- Dry run:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
- Install the chart:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify Apigee Operator installation:
helm ls -nAPIGEE_NAMESPACE
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONoperator apigee 3 2025-06-26 00:42:44.492009 -0800 PST deployed apigee-operator-1.15.1 1.15.1
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deploy apigee-controller-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-controller-manager 1/1 1 1 34s
- Dry run:
Install Apigee datastore:
- Dry run:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify
apigeedatastoreis up and running by checking its state before proceeding to the next step:kubectl -nAPIGEE_NAMESPACE get apigeedatastore default
NAME STATE AGEdefault running 51s
- Dry run:
Install Apigee telemetry:
- Dry run:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeetelemetry apigee-telemetry
NAME STATE AGEapigee-telemetry running 55s
- Dry run:
Install Apigee Redis:
Dry run:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeeredis default
NAME STATE AGEdefault running 79s
Install Apigee ingress manager:
Dry run:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deployment apigee-ingressgateway-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-ingressgateway-manager 2/2 2 2 16s
Install Apigee organization. If you have set the$ORG_NAME environment variable in your shell, you can use that in the following commands:
Dry run:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking the state of the respective org:
kubectl -nAPIGEE_NAMESPACE get apigeeorg
NAME STATE AGEmy-project-123abcd running 4m18s
Install the environment.
You must install one environment at a time. Specify the environment with
--set env=ENV_NAME. If you have set the$ENV_NAME environment variable in your shell, you can use that in the following commands:Dry run:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml \ --dry-run=server
ENV_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-envchart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_NAME. However, if your environment has the same name as your environment group, you must use different release names for the environment and environment group, for exampledev-env-releaseanddev-envgroup-release. For more information on releases in Helm, seeThree big concepts in the Helm documentation.Install the chart:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml
Verify it is up and running by checking the state of the respective env:
kubectl -nAPIGEE_NAMESPACE get apigeeenv
NAME STATE AGE GATEWAYTYPEapigee-my-project-my-env running 3m1s
- Install the environment groups (
virtualhosts).- You must install one environment group (virtualhost) at a time. Specify the environment group with
--set envgroup=ENV_GROUP. If you have set the$ENV_GROUP environment variable in your shell, you can use that in the following commands. Repeat the following commands for each env group mentioned in youroverrides.yamlfile:Dry run:
helm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml \ --dry-run=server
ENV_GROUP_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-virtualhostschart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_GROUP. However, if your environment group has the same name as an environment in your installation, you must use different release names for the environment group and environment, for exampledev-envgroup-releaseanddev-env-release. For more information on releases in Helm, see Three big concepts in the Helm documentation. Install the chart:
Note:ENV_GROUP must be unique within thehelm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml
apigeenamespace. For example, if you have aprodenv and envgroup, you should set this name toprod-envgroup. The later env group name should still beprod.- Check the state of the ApigeeRoute (AR).
Installing the
virtualhostscreates ApigeeRouteConfig (ARC) which internally creates ApigeeRoute (AR) once the Apigee watcher pulls env group related details from the control plane. Therefore, check that the corresponding AR's state is running:kubectl -nAPIGEE_NAMESPACE get arc
NAME STATE AGEapigee-org1-dev-egroup 2m
kubectl -nAPIGEE_NAMESPACE get ar
NAME STATE AGEapigee-ingressgateway-internal-chaining-my-project-123abcd running 19mmy-project-myenvgroup-000-321dcba running 2m30s
- You must install one environment group (virtualhost) at a time. Specify the environment group with
JSON files
- If you have not, navigate into your
APIGEE_HELM_CHARTS_HOMEdirectory. Run the following commands from that directory. - Install Apigee Operator/Controller:Note: This step requires elevated cluster permissions. Run
helm -horhelm install -hfor details- Dry run:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
- Install the chart:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify Apigee Operator installation:
helm ls -nAPIGEE_NAMESPACE
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONoperator apigee 3 2025-06-26 00:42:44.492009 -0800 PST deployed apigee-operator-1.15.1 1.15.1
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deploy apigee-controller-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-controller-manager 1/1 1 1 34s
- Dry run:
Install Apigee datastore:
- Dry run:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify
apigeedatastoreis up and running by checking its state before proceeding to the next step:kubectl -nAPIGEE_NAMESPACE get apigeedatastore default
NAME STATE AGEdefault running 51s
- Dry run:
Install Apigee telemetry:
- Dry run:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeetelemetry apigee-telemetry
NAME STATE AGEapigee-telemetry running 55s
- Dry run:
Install Apigee Redis:
Dry run:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeeredis default
NAME STATE AGEdefault running 79s
Install Apigee ingress manager:
Dry run:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deployment apigee-ingressgateway-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-ingressgateway-manager 2/2 2 2 16s
Install Apigee organization. If you have set the$ORG_NAME environment variable in your shell, you can use that in the following commands:
Dry run:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking the state of the respective org:
kubectl -nAPIGEE_NAMESPACE get apigeeorg
NAME STATE AGEmy-project-123abcd running 4m18s
Install the environment.
You must install one environment at a time. Specify the environment with
--set env=ENV_NAME. If you have set the$ENV_NAME environment variable in your shell, you can use that in the following commands:Dry run:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml \ --dry-run=server
ENV_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-envchart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_NAME. However, if your environment has the same name as your environment group, you must use different release names for the environment and environment group, for exampledev-env-releaseanddev-envgroup-release. For more information on releases in Helm, seeThree big concepts in the Helm documentation.Install the chart:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml
Verify it is up and running by checking the state of the respective env:
kubectl -nAPIGEE_NAMESPACE get apigeeenv
NAME STATE AGE GATEWAYTYPEapigee-my-project-my-env running 3m1s
- Install the environment groups (
virtualhosts).- You must install one environment group (virtualhost) at a time. Specify the environment group with
--set envgroup=ENV_GROUP. If you have set the$ENV_GROUP environment variable in your shell, you can use that in the following commands. Repeat the following commands for each env group mentioned in youroverrides.yamlfile:Dry run:
helm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml \ --dry-run=server
ENV_GROUP_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-virtualhostschart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_GROUP. However, if your environment group has the same name as an environment in your installation, you must use different release names for the environment group and environment, for exampledev-envgroup-releaseanddev-env-release. For more information on releases in Helm, see Three big concepts in the Helm documentation. Install the chart:
Note:ENV_GROUP must be unique within thehelm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml
apigeenamespace. For example, if you have aprodenv and envgroup, you should set this name toprod-envgroup. The later env group name should still beprod.- Check the state of the ApigeeRoute (AR).
Installing the
virtualhostscreates ApigeeRouteConfig (ARC) which internally creates ApigeeRoute (AR) once the Apigee watcher pulls env group related details from the control plane. Therefore, check that the corresponding AR's state is running:kubectl -nAPIGEE_NAMESPACE get arc
NAME STATE AGEapigee-org1-dev-egroup 2m
kubectl -nAPIGEE_NAMESPACE get ar
NAME STATE AGEapigee-ingressgateway-internal-chaining-my-project-123abcd running 19mmy-project-myenvgroup-000-321dcba running 2m30s
- You must install one environment group (virtualhost) at a time. Specify the environment group with
Vault
- If you have not, navigate into your
APIGEE_HELM_CHARTS_HOMEdirectory. Run the following commands from that directory. - Install Apigee Operator/Controller:Note: This step requires elevated cluster permissions. Run
helm -horhelm install -hfor details- Dry run:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
- Install the chart:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify Apigee Operator installation:
helm ls -nAPIGEE_NAMESPACE
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONoperator apigee 3 2025-06-26 00:42:44.492009 -0800 PST deployed apigee-operator-1.15.1 1.15.1
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deploy apigee-controller-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-controller-manager 1/1 1 1 34s
- Dry run:
Install Apigee datastore:
- Dry run:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify
apigeedatastoreis up and running by checking its state before proceeding to the next step:kubectl -nAPIGEE_NAMESPACE get apigeedatastore default
NAME STATE AGEdefault running 51s
- Dry run:
Install Apigee telemetry:
- Dry run:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeetelemetry apigee-telemetry
NAME STATE AGEapigee-telemetry running 55s
- Dry run:
Install Apigee Redis:
Dry run:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeeredis default
NAME STATE AGEdefault running 79s
Install Apigee ingress manager:
Dry run:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deployment apigee-ingressgateway-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-ingressgateway-manager 2/2 2 2 16s
Install Apigee organization. If you have set the$ORG_NAME environment variable in your shell, you can use that in the following commands:
Dry run:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking the state of the respective org:
kubectl -nAPIGEE_NAMESPACE get apigeeorg
NAME STATE AGEmy-project-123abcd running 4m18s
Install the environment.
You must install one environment at a time. Specify the environment with
--set env=ENV_NAME. If you have set the$ENV_NAME environment variable in your shell, you can use that in the following commands:Dry run:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml \ --dry-run=server
ENV_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-envchart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_NAME. However, if your environment has the same name as your environment group, you must use different release names for the environment and environment group, for exampledev-env-releaseanddev-envgroup-release. For more information on releases in Helm, seeThree big concepts in the Helm documentation.Install the chart:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml
Verify it is up and running by checking the state of the respective env:
kubectl -nAPIGEE_NAMESPACE get apigeeenv
NAME STATE AGE GATEWAYTYPEapigee-my-project-my-env running 3m1s
- Install the environment groups (
virtualhosts).- You must install one environment group (virtualhost) at a time. Specify the environment group with
--set envgroup=ENV_GROUP. If you have set the$ENV_GROUP environment variable in your shell, you can use that in the following commands. Repeat the following commands for each env group mentioned in youroverrides.yamlfile:Dry run:
helm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml \ --dry-run=server
ENV_GROUP_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-virtualhostschart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_GROUP. However, if your environment group has the same name as an environment in your installation, you must use different release names for the environment group and environment, for exampledev-envgroup-releaseanddev-env-release. For more information on releases in Helm, see Three big concepts in the Helm documentation. Install the chart:
Note:ENV_GROUP must be unique within thehelm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml
apigeenamespace. For example, if you have aprodenv and envgroup, you should set this name toprod-envgroup. The later env group name should still beprod.- Check the state of the ApigeeRoute (AR).
Installing the
virtualhostscreates ApigeeRouteConfig (ARC) which internally creates ApigeeRoute (AR) once the Apigee watcher pulls env group related details from the control plane. Therefore, check that the corresponding AR's state is running:kubectl -nAPIGEE_NAMESPACE get arc
NAME STATE AGEapigee-org1-dev-egroup 2m
kubectl -nAPIGEE_NAMESPACE get ar
NAME STATE AGEapigee-ingressgateway-internal-chaining-my-project-123abcd running 19mmy-project-myenvgroup-000-321dcba running 2m30s
- You must install one environment group (virtualhost) at a time. Specify the environment group with
WIF for GKE
- If you have not, navigate into your
APIGEE_HELM_CHARTS_HOMEdirectory. Run the following commands from that directory. - Install Apigee Operator/Controller:Note: This step requires elevated cluster permissions. Run
helm -horhelm install -hfor details- Dry run:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
- Install the chart:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify Apigee Operator installation:
helm ls -nAPIGEE_NAMESPACE
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONoperator apigee 3 2025-06-26 00:42:44.492009 -0800 PST deployed apigee-operator-1.15.1 1.15.1
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deploy apigee-controller-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-controller-manager 1/1 1 1 34s
- Dry run:
Install Apigee datastore:
- Dry run:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Set up the service account bindings for Cassandra for Workload Identity Federation for GKE:
The output from the
helm upgradecommand should have contained commands in theNOTES section. Follow those commands to set up the service account bindings. There should be two commands in the form of:Production
gcloud iam service-accounts add-iam-policy-bindingCASSANDRA_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-cassandra-default]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-cassandra-default]" \ --projectPROJECT_ID
And:
Production
kubectl annotate serviceaccount apigee-cassandra-default \ iam.gke.io/gcp-service-account=CASSANDRA_SERVICE_ACCOUNT_EMAIL \ --namespaceAPIGEE_NAMESPACE
Non-prod
kubectl annotate serviceaccount apigee-cassandra-default \ iam.gke.io/gcp-service-account=NON_PROD_SERVICE_ACCOUNT_EMAIL \ --namespaceAPIGEE_NAMESPACE
For example:
Production
NOTES:For Cassandra backup GKE Workload Identity, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). gcloud iam service-accounts add-iam-policy-binding apigee-cassandra@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-cassandra-default]" \ --project my-project kubectl annotate serviceaccount apigee-cassandra-default \ iam.gke.io/gcp-service-account=apigee-cassandra@my-project.iam.gserviceaccount.com \ --namespace apigee
Non-prod
NOTES:For Cassandra backup GKE Workload Identity, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-cassandra-default]" \ --project my-project kubectl annotate serviceaccount apigee-cassandra-default \ iam.gke.io/gcp-service-account=apigee-non-prod@my-project.iam.gserviceaccount.com \ --namespace apigee
Optional: If you do not want to set up Cassandra backup at this time, edit your overrides file to remove or comment out the
cassandra.backupstanza before running thehelm upgradecommand without the--dry-runflag. SeeCassandra backup and restore for more information about configuring Cassandra backup.Install the chart:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify
apigeedatastoreis up and running by checking its state before proceeding to the next step:kubectl -nAPIGEE_NAMESPACE get apigeedatastore default
NAME STATE AGEdefault running 51s
- Dry run:
Install Apigee telemetry:
- Dry run:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Set up the service account bindings for Loggeer and Metrics for Workload Identity Federation for GKE:
The output from the
helm upgradecommand should have contained commands in theNOTES section. Follow those commands to set up the service account bindings. There should be two commands in the form of:Logger KSA:
apigee-logger-apigee-telemetrygcloud iam service-accounts add-iam-policy-bindingLOGGER_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-logger-apigee-telemetry]" \ --projectPROJECT_ID
Metrics KSA:
apigee-metrics-saProduction
gcloud iam service-accounts add-iam-policy-bindingMETRICS_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-metrics-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-metrics-sa]" \ --projectPROJECT_ID
For example:
Production
NOTES:For GKE Workload Identity, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). Logger KSA: apigee-logger-apigee-telemetry gcloud iam service-accounts add-iam-policy-binding apigee-logger@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-logger-apigee-telemetry]" \ --project my-project Metrics KSA: apigee-metrics-sa gcloud iam service-accounts add-iam-policy-binding apigee-metrics@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-metrics-sa]" \ --project my-project
Non-prod
NOTES:For GKE Workload Identity, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). Logger KSA: apigee-logger-apigee-telemetry gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-logger-apigee-telemetry]" \ --project my-project Metrics KSA: apigee-metrics-sa gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-metrics-sa]" \ --project my-project
Install the chart:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeetelemetry apigee-telemetry
NAME STATE AGEapigee-telemetry running 55s
- Dry run:
Install Apigee Redis:
Dry run:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeeredis default
NAME STATE AGEdefault running 79s
Install Apigee ingress manager:
Dry run:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deployment apigee-ingressgateway-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-ingressgateway-manager 2/2 2 2 16s
Install Apigee organization. If you have set the$ORG_NAME environment variable in your shell, you can use that in the following commands:
Dry run:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Set up the service account bindings for org-scoped components for Workload Identity Federation for GKE, MART, Apigee Connect, UDCA, and Watcher.
The output from the
Note: The KSA names include a unique hash id for your organization, for example,helm upgradecommand should have contained commands in theNOTES section. Follow those commands to set up the service account bindings. There should be four commands.apigee-mart-my-project-123abcd-sa.MART KSA:
apigee-mart-PROJECT_ID-ORG_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingMART_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-mart-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-mart-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Connect Agent KSA:
Note: Apigee Connect uses the MART Google service account.apigee-connect-agent-PROJECT_ID-ORG_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingMART_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-connect-agent-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-connect-agent-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Mint Task Scheduler KSA: (If you are usingMonetization for Apigee hybrid)
apigee-mint-task-scheduler-PROJECT_ID-ORG_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingMINT_TASK_SCHEDULER_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-mint-task-scheduler-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-mint-task-scheduler-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
UDCA KSA:
apigee-udca-PROJECT_ID-ORG_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingUDCA_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-udca-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-udca-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Watcher KSA:
apigee-watcher-PROJECT_ID-ORG_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingWATCHER_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-watcher-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-watcher-PROJECT_ID-ORG_HASH_ID-sa]" \ --projectPROJECT_ID
For example:
Production
NOTES:For Apigee Organization GKE Workload Identity, my-project, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). MART KSA: apigee-mart-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-mart@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-mart-my-project-1a2b3c4-sa]" \ --project my-project Connect Agent KSA: apigee-connect-agent-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-mart@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-connect-agent-my-project-1a2b3c4-sa]" \ --project my-project Mint task scheduler KSA: apigee-mint-task-scheduler-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-mint-task-scheduler@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-mint-task-scheduler-my-project-1a2b3c4-sa]" \ --project my-project UDCA KSA: apigee-udca-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-udca@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-udca-my-project-1a2b3c4-sa]" \ --project my-project Watcher KSA: apigee-watcher-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-watcher@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-watcher-my-project-1a2b3c4-sa]" \ --project my-project
Non-prod
NOTES:For Apigee Organization GKE Workload Identity, my-project, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). MART KSA: apigee-mart-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-mart-my-project-1a2b3c4-sa]" \ --project my-project Connect Agent KSA: apigee-connect-agent-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-connect-agent-my-project-1a2b3c4-sa]" \ --project my-project UDCA KSA: apigee-udca-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-udca-my-project-1a2b3c4-sa]" \ --project my-project Watcher KSA: apigee-watcher-my-project-1a2b3c4-sa gcloud iam service-accounts add-iam-policy-binding apigee-non-prod@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-watcher-my-project-1a2b3c4-sa]" \ --project my-project
Install the chart:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking the state of the respective org:
kubectl -nAPIGEE_NAMESPACE get apigeeorg
NAME STATE AGEmy-project-123abcd running 4m18s
Install the environment.
You must install one environment at a time. Specify the environment with
--set env=ENV_NAME. If you have set the$ENV_NAME environment variable in your shell, you can use that in the following commands:Dry run:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml \ --dry-run=server
ENV_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-envchart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_NAME. However, if your environment has the same name as your environment group, you must use different release names for the environment and environment group, for exampledev-env-releaseanddev-envgroup-release. For more information on releases in Helm, seeThree big concepts in the Helm documentation.Set up the service account bindings for env-scoped components for Workload Identity Federation for GKE, Runtime, Synchronizer, and UDCA.
The output from the
Note: The KSA names include a unique hash id for your environment, for example,helm upgradecommand should have contained commands in theNOTES section. Follow those commands to set up the service account bindings. There should be four commands.apigee-mart-my-project--myenv-abc1234-sa.Runtime KSA:
apigee-runtime-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingRUNTIME_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-runtime-PROJECT_ID-ENV_NAME-ENV_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-runtime-PROJECT_ID-ENV_NAME-ENV_HASH_ID-sa]" \ --projectPROJECT_ID
Synchronizer KSA:
apigee-synchronizer-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingSYNCHRONIZER_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-synchronizer-PROJECT_ID-ENV_NAME-ENV_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-synchronizer-PROJECT_ID-ENV_NAME-ENV_HASH_ID-sa]" \ --projectPROJECT_ID
UDCA KSA:
apigee-udca-PROJECT_ID-ORG_HASH_ID-ENV_NAME-ENV_HASH_ID-saProduction
gcloud iam service-accounts add-iam-policy-bindingUDCA_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-udca-PROJECT_ID-ENV_NAME-ENV_HASH_ID-sa]" \ --projectPROJECT_ID
Non-prod
gcloud iam service-accounts add-iam-policy-bindingNON_PROD_SERVICE_ACCOUNT_EMAIL \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[apigee/apigee-udca-PROJECT_ID-ENV_NAME-ENV_HASH_ID-sa]" \ --projectPROJECT_ID
For example:
NOTES:For Apigee Environment GKE Workload Identity, my-env, please make sure to add the following membership to the IAM policy binding using the respective kubernetes SA (KSA). Runtime KSA: apigee-runtime-my-project-my-env-b2c3d4e-sa gcloud iam service-accounts add-iam-policy-binding apigee-runtime@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-runtime-my-project-my-env-b2c3d4e-sa]" \ --project my-project Synchronizer KSA: apigee-synchronizer-my-project-my-env-b2c3d4e-sa gcloud iam service-accounts add-iam-policy-binding apigee-synchronizer@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-synchronizer-my-project-my-env-b2c3d4e-sa]" \ --project my-project UDCA KSA: apigee-udca-my-project-my-env-b2c3d4e-sa: gcloud iam service-accounts add-iam-policy-binding apigee-udca@my-project.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:my-project.svc.id.goog[apigee/apigee-udca-my-project-my-env-b2c3d4e-sa]" \ --project my-project
Install the chart:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml
Verify it is up and running by checking the state of the respective env:
kubectl -nAPIGEE_NAMESPACE get apigeeenv
NAME STATE AGE GATEWAYTYPEapigee-my-project-my-env running 3m1s
- Install the environment groups (
virtualhosts).- You must install one environment group (virtualhost) at a time. Specify the environment group with
--set envgroup=ENV_GROUP. If you have set the$ENV_GROUP environment variable in your shell, you can use that in the following commands. Repeat the following commands for each env group mentioned in youroverrides.yamlfile:Dry run:
helm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml \ --dry-run=server
ENV_GROUP_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-virtualhostschart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_GROUP. However, if your environment group has the same name as an environment in your installation, you must use different release names for the environment group and environment, for exampledev-envgroup-releaseanddev-env-release. For more information on releases in Helm, see Three big concepts in the Helm documentation. Install the chart:
Note:ENV_GROUP must be unique within thehelm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml
apigeenamespace. For example, if you have aprodenv and envgroup, you should set this name toprod-envgroup. The later env group name should still beprod.- Check the state of the ApigeeRoute (AR).
Installing the
virtualhostscreates ApigeeRouteConfig (ARC) which internally creates ApigeeRoute (AR) once the Apigee watcher pulls env group related details from the control plane. Therefore, check that the corresponding AR's state is running:kubectl -nAPIGEE_NAMESPACE get arc
NAME STATE AGEapigee-org1-dev-egroup 2m
kubectl -nAPIGEE_NAMESPACE get ar
NAME STATE AGEapigee-ingressgateway-internal-chaining-my-project-123abcd running 19mmy-project-myenvgroup-000-321dcba running 2m30s
- You must install one environment group (virtualhost) at a time. Specify the environment group with
- (Optional) You can see the status of your Kubernetes service accounts in theKubernetes: Workloads Overview page in the Google Cloud console.Note: You may see an error status for the
apigee-cassandra-backupservice account. This is because you are not currently running backup or restore, and these processes have not been fully configured yet. For more information on Cassandra backup and restore, seeCassandra backup overview.
WIF on other platforms
- If you have not, navigate into your
APIGEE_HELM_CHARTS_HOMEdirectory. Run the following commands from that directory. - Install Apigee Operator/Controller:Note: This step requires elevated cluster permissions. Run
helm -horhelm install -hfor details- Dry run:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
- Install the chart:
helm upgrade operator apigee-operator/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify Apigee Operator installation:
helm ls -nAPIGEE_NAMESPACE
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONoperator apigee 3 2025-06-26 00:42:44.492009 -0800 PST deployed apigee-operator-1.15.1 1.15.1
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deploy apigee-controller-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-controller-manager 1/1 1 1 34s
- Dry run:
Install Apigee datastore:
- Dry run:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade datastore apigee-datastore/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
- If you have enabled Cassandra backup or Cassandra restore, grant the Cassandra Kubernetes service accounts access to impersonate the associated
apigee-cassandraIAM service account.- List the email addresses of the IAM service account for Cassandra:
Production
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-cassandra"
Non-prod
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-non-prod"
The output should look similar to the following:
Production
apigee-cassandra apigee-cassandra@my-project.iam.gserviceaccount.com False
Non-prod
apigee-non-prod apigee-non-prod@my-project.iam.gserviceaccount.com False
- List the Cassandra Kubernetes service accounts:
kubectl get serviceaccount -nAPIGEE_NAMESPACE | grep "apigee-cassandra"
The output should look similar to the following:
apigee-cassandra-backup-sa 0 7m37sapigee-cassandra-default 0 7m12sapigee-cassandra-guardrails-sa 0 6m43sapigee-cassandra-restore-sa 0 7m37sapigee-cassandra-schema-setup-my-project-1a2b2c4 0 7m30sapigee-cassandra-schema-val-my-project-1a2b2c4 0 7m29sapigee-cassandra-user-setup-my-project-1a2b2c4 0 7m22s
- If you have created the
apigee-cassandra-backup-saorapigee-cassandra-restore-saKubernetes service accounts, grant each of them access to impersonate theapigee-cassandraIAM service account with the following command:Production
Template
gcloud iam service-accounts add-iam-policy-binding \CASSANDRA_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-cassandra@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-cassandra-backup-sa" \ --role=roles/iam.workloadIdentityUser
Non-prod
Template
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-cassandra-backup-sa" \ --role=roles/iam.workloadIdentityUser
Where:
CASSANDRA_IAM_SA_EMAIL: the email address of the Cassandra IAM service account.PROJECT_NUMBER: theproject number of the project where you created the workload identity pool.Note: You must use theproject number in the member identifier. Using the project ID is not supported. You can find the project number with the following command:gcloud projects describePROJECT_ID --format="value(projectNumber)"
POOL_ID: the workload identity pool ID.MAPPED_SUBJECT: the Kubernetes ServiceAccount from the claim in your ID token. In most hybrid installations, this will have the format:system:serviceaccount:APIGEE_NAMESPACE:K8S_SA_NAME.- For
apigee-cassandra-backup-sa, this will be something similar tosystem:serviceaccount:apigee:apigee-cassandra-backup-sa. - For
apigee-cassandra-restore-sa, this will be something similar tosystem:serviceaccount:apigee:apigee-cassandra-restore-sa.
google.subject=assertions.sub. Therefore the value ofMAPPED_SUBJECTwill be the value in the ID token following"sub":. You can find the mapped subject for a Kubernetes service account by searching the ID token forsubfollowed by the name of the service account.For example: pipe the contents of the ID token through
grep -E 'sub.*apigee-cassandra-backup-sa'- For
- List the email addresses of the IAM service account for Cassandra:
Verify
apigeedatastoreis up and running by checking its state before proceeding to the next step:kubectl -nAPIGEE_NAMESPACE get apigeedatastore default
NAME STATE AGEdefault running 51s
- Dry run:
Install Apigee telemetry:
- Dry run:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade telemetry apigee-telemetry/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeetelemetry apigee-telemetry
NAME STATE AGEapigee-telemetry running 55s
- Grant the telemetry Kubernetes service accounts access to impersonate the associated
apigee-metricsIAM service account.- List the email address of the IAM service account for metrics:
Production
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-metrics"
The output should look similar to the following:
apigee-metrics apigee-metrics@my-project.iam.gserviceaccount.com False
Non-prod
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-non-prod"
The output should look similar to the following:
apigee-non-prod apigee-non-prod@my-project.iam.gserviceaccount.com False
- List the telemetry Kubernetes service accounts:
kubectl get serviceaccount -nAPIGEE_NAMESPACE | grep "telemetry"
The output should look similar to the following:
apigee-metrics-apigee-telemetry 0 42mapigee-open-telemetry-collector-apigee-telemetry 0 37m
- Grant each of the telemetry Kubernetes service accounts access to impersonate the
apigee-metricsIAM service account with the following command:Production
Apigee Metrics KSA:
apigee-metrics-apigee-telemetrytoapigee-metricsGoogle IAM service accountCode
gcloud iam service-accounts add-iam-policy-binding \METRICS_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-metrics@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-metrics-apigee-telemetry" \ --role=roles/iam.workloadIdentityUser
Apigee OpenTelemetry Collector KSA:
apigee-open-telemetry-collector-apigee-telemetrytoapigee-metricsGoogle IAM service accountCode
gcloud iam service-accounts add-iam-policy-binding \METRICS_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-metrics@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-open-telemetry-collector-apigee-telemetry" \ --role=roles/iam.workloadIdentityUser
Non-prod
Apigee Metrics KSA:
apigee-metrics-apigee-telemetrytoapigee-non-prodGoogle IAM service accountCode
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-metrics-apigee-telemetry" \ --role=roles/iam.workloadIdentityUser
Apigee OpenTelemetry Collector KSA:
apigee-open-telemetry-collector-apigee-telemetrytoapigee-non-prodGoogle IAM service accountCode
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-open-telemetry-collector-apigee-telemetry" \ --role=roles/iam.workloadIdentityUser
- List the email address of the IAM service account for metrics:
- Dry run:
Install Apigee Redis:
Dry run:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade redis apigee-redis/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its state:
kubectl -nAPIGEE_NAMESPACE get apigeeredis default
NAME STATE AGEdefault running 79s
Install Apigee ingress manager:
Dry run:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade ingress-manager apigee-ingress-manager/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking its availability:
kubectl -nAPIGEE_NAMESPACE get deployment apigee-ingressgateway-manager
NAME READY UP-TO-DATE AVAILABLE AGEapigee-ingressgateway-manager 2/2 2 2 16s
Install Apigee organization. If you have set the$ORG_NAME environment variable in your shell, you can use that in the following commands:
Dry run:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml \ --dry-run=server
Install the chart:
helm upgrade$ORG_NAME apigee-org/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ -foverrides.yaml
Verify it is up and running by checking the state of the respective org:
kubectl -nAPIGEE_NAMESPACE get apigeeorg
NAME STATE AGEmy-project-123abcd running 4m18s
- Grant the org-scoped Kubernetes service accounts access to impersonate the associated IAM service accounts.
- List the email addresses of the IAM service accounts used by the
apigee-mart,apigee-udca, andapigee-watchercomponents:Production
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-mart\|apigee-udca\|apigee-watcher"
The output should look similar to the following:
apigee-mart apigee-mart@my-project.iam.gserviceaccount.com Falseapigee-udca apigee-udca@my-project.iam.gserviceaccount.com Falseapigee-watcher apigee-watcher@my-project.iam.gserviceaccount.com False
If you are usingMonetization for Apigee hybrid, also get the email address of the
apigee-mint-task-schedulerservice account.gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-mint-task-scheduler"
The output should look similar to the following:
apigee-mint-task-scheduler apigee-mint-task-scheduler@my-project.iam.gserviceaccount.com False
Non-prod
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-non-prod"
The output should look similar to the following:
apigee-non-prod apigee-non-prod@my-project.iam.gserviceaccount.com False
- List the org-scoped Kubernetes service accounts:
kubectl get serviceaccount -nAPIGEE_NAMESPACE | grep "apigee-connect-agent\|apigee-mart\|apigee-udca\|apigee-watcher"
The output should look similar to the following:
apigee-connect-agent-my-project-123abcd 0 1h4mapigee-mart-my-project-123abcd 0 1h4mapigee-mint-task-scheduler-my-project-123abcd 0 1h3mapigee-udca-my-project-123abcd 0 1h2mapigee-watcher-my-project-123abcd 0 1h1m
- Use the following commands to grant the org-scoped Kubernetes service accounts access to impersonate the associated IAM service accounts as follows:
Production
Connect agent KSA:
apigee-connect-agent-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-martIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \APIGEE_MART_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-mart@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-connect-agent-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
MART KSA:
apigee-mart-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-martIAM service account. MART and Connect agent use the same IAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \APIGEE_MART_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-mart@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-mart-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Mint task scheduler KSA: (if usingMonetization for Apigee hybrid)
apigee-mint-task-scheduler-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-mint-task-schedulerIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \APIGEE_MINT_TASK_SCHEDULER_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-mint-task-scheduler@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-mint-task-scheduler-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Org-scoped UDCA KSA:
apigee-udca-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-udcaIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \APIGEE_UDCA_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-udca-task-scheduler@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-udca-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Watcher KSA:
apigee-watcher-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-watcherIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \APIGEE_WATCHER_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-watcher@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-watcher-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Non-prod
Connect agent KSA:
apigee-connect-agent-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-non-prodIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-connect-agent-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
MART KSA:
apigee-mart-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-non-prodIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-mart-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Mint task scheduler KSA: (if usingMonetization for Apigee hybrid)
apigee-mint-task-scheduler-ORG_NAME-UUIORG_HASH_IDDKubernetes service account toapigee-non-prodIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-mint-task-scheduler-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Org-scoped UDCA KSA:
apigee-udca-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-non-prodIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-udca-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
Watcher KSA:
apigee-watcher-ORG_NAME-ORG_HASH_IDKubernetes service account toapigee-non-prodIAM service account.Code
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-watcher-my-org-123abcd" \ --role=roles/iam.workloadIdentityUser
- List the email addresses of the IAM service accounts used by the
Install the environment.
You must install one environment at a time. Specify the environment with--set env=ENV_NAME. If you have set the$ENV_NAME environment variable in your shell, you can use that in the following commands:
Dry run:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml \ --dry-run=server
ENV_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-envchart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_NAME. However, if your environment has the same name as your environment group, you must use different release names for the environment and environment group, for exampledev-env-releaseanddev-envgroup-release. For more information on releases in Helm, seeThree big concepts in the Helm documentation.Install the chart:
helm upgradeENV_RELEASE_NAME apigee-env/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -foverrides.yaml
Verify it is up and running by checking the state of the respective env:
kubectl -nAPIGEE_NAMESPACE get apigeeenv
NAME STATE AGE GATEWAYTYPEapigee-my-project-my-env running 3m1s
- Grant the environment-scoped Kubernetes service accounts access to impersonate the associated IAM service accounts.
- List the email address of the IAM service accounts used by the
apigee-runtime,apigee-synchronizer, andapigee-udcacomponents:Production
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-runtime\|apigee-synchronizer\|apigee-udca"
Non-prod
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-non-prod"
gcloud iam service-accounts list --projectPROJECT_ID | grep "apigee-mart\|apigee-udca\|apigee-watcher"
The output should look similar to the following:
Production
apigee-runtime apigee-runtime@my-project.iam.gserviceaccount.com Falseapigee-synchronizer apigee-synchronizer@my-project.iam.gserviceaccount.com Falseapigee-udca apigee-udca@my-project.iam.gserviceaccount.com False
Non-prod
apigee-non-prod apigee-non-prod@my-project.iam.gserviceaccount.com False
- List the environment-scoped Kubernetes service accounts:
kubectl get serviceaccount -nAPIGEE_NAMESPACE | grep "apigee-runtime\|apigee-synchronizer\|apigee-udca"
The output should look similar to the following:
Note: You may see both org-scoped and environment-scopedapigee-runtime-my-project--my-env-cdef123 0 19mapigee-synchronizer-my-project-my-env-cdef123 0 17mapigee-udca-my-project-123abcd 0 1h29mapigee-udca-my-project-my-env-cdef123 0 22m
apigee-udcaKubernetes service accounts. In this step, grant access to the environment-scopedapigee-udcaservice account. - Use the following command to grant the environment-scoped Kubernetes service accounts access to impersonate the associated IAM service accounts as follows:
Production
Runtime KSA:
apigee-runtime-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saKSA toapigee-runtimeGoogle IAM SACode
gcloud iam service-accounts add-iam-policy-binding \RUNTIME_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-runtime@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-runtime-my-project-my-env-cdef123" \ --role=roles/iam.workloadIdentityUser
Synchronizer KSA:
apigee-synchronizer-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saKSA toapigee-synchronizerGoogle IAM SACode
gcloud iam service-accounts add-iam-policy-binding \SYNCHRONIZER_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-synchronizer@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-synchronizer-my-project-my-env-cdef123" \ --role=roles/iam.workloadIdentityUser
UDCA KSA:
apigee-udca-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saKSA toapigee-udcaGoogle IAM SACode
gcloud iam service-accounts add-iam-policy-binding \UDCA_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-udca@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-udca-my-project-my-env-cdef123" \ --role=roles/iam.workloadIdentityUser
Non-prod
Runtime KSA:
apigee-runtime-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saKSA toapigee-non-prodGoogle IAM SACode
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-runtime-my-project-my-env-cdef123" \ --role=roles/iam.workloadIdentityUser
Non-prod
Synchronizer KSA:
apigee-synchronizer-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saKSA toapigee-non-prodGoogle IAM SACode
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-synchronizer-my-project-my-env-cdef123" \ --role=roles/iam.workloadIdentityUser
Non-prod
UDCA KSA:
apigee-udca-PROJECT_ID-ENV_NAME-ENV_HASH_ID-saKSA toapigee-non-prodGoogle IAM SACode
gcloud iam service-accounts add-iam-policy-binding \NON_PROD_IAM_SA_EMAIL \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
Example
gcloud iam service-accounts add-iam-policy-binding \ apigee-non-prod@my-project.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/subject/system:serviceaccount:apigee:apigee-udca-my-project-my-env-cdef123" \ --role=roles/iam.workloadIdentityUser
- List the email address of the IAM service accounts used by the
virtualhosts).- You must install one environment group (virtualhost) at a time. Specify the environment group with
--set envgroup=ENV_GROUP. If you have set the$ENV_GROUP environment variable in your shell, you can use that in the following commands. Repeat the following commands for each env group mentioned in youroverrides.yamlfile:Dry run:
helm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml \ --dry-run=server
ENV_GROUP_RELEASE_NAME is a name used to keep track of installation and upgrades of the
apigee-virtualhostschart. This name must be unique from the other Helm release names in your installation. Usually this is the same asENV_GROUP. However, if your environment group has the same name as an environment in your installation, you must use different release names for the environment group and environment, for exampledev-envgroup-releaseanddev-env-release. For more information on releases in Helm, see Three big concepts in the Helm documentation. Install the chart:
Note:ENV_GROUP must be unique within thehelm upgradeENV_GROUP_RELEASE_NAME apigee-virtualhost/ \ --install \ --namespaceAPIGEE_NAMESPACE \ --atomic \ --set envgroup=$ENV_GROUP \ -foverrides.yaml
apigeenamespace. For example, if you have aprodenv and envgroup, you should set this name toprod-envgroup. The later env group name should still beprod.- Check the state of the ApigeeRoute (AR).
Installing the
virtualhostscreates ApigeeRouteConfig (ARC) which internally creates ApigeeRoute (AR) once the Apigee watcher pulls env group related details from the control plane. Therefore, check that the corresponding AR's state is running:kubectl -nAPIGEE_NAMESPACE get arc
NAME STATE AGEapigee-org1-dev-egroup 2m
kubectl -nAPIGEE_NAMESPACE get ar
NAME STATE AGEapigee-ingressgateway-internal-chaining-my-project-123abcd running 19mmy-project-myenvgroup-000-321dcba running 2m30s
You've successfully installed and configured the Apigee hybrid runtime plane.
Next step
In the next step, you will configure the Apigee ingress gateway and deploy a proxy to test your installation.
(NEXT) Step 1: Expose Apigee ingress2Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-19 UTC.