This page applies to Apigee, but not to Apigee hybrid.
View
Apigee Edge documentation.
This document describes how to install and configure Apigee from the command line with VPC peering. These steps apply to both Subscription and Pay-as-you-go pricing models for paid organizations with or without data residency enabled.
Summary of steps
The provisioning steps are as follows:
- Step 1: Define environment variables:
Set up
gcloud
and define environment variables. The Google Cloud CLI manages authentication, local configuration, developer workflow,and interactions with the Google Cloud APIs. - Step 2: Enable APIs: Apigee requires you to enable several Google Cloud APIs.
- Step 3: Create the Apigee service identity: This service account is used by the Google Cloud client libraries to authenticate with Google Cloud APIs.
- Step 4: Configure service networking: Service networking automates the private connectivity set up (using VPC Network Peering) between your network and Apigee.
- Step 5: Create an organization: An Apigee organization (sometimes referred to as an org) is the top-level container in Apigee. It includes all of your environments and environment groups, users, API proxies, and related resources.
- Step 6: Create a runtime instance: An instance, or runtime is where your project and related services are stored; it provides the user-facing endpoint for your services.
- Step 7: Create an environment: An API proxy must be deployed to an environment, and added to an environment group, before the APIs it exposes are accessible over the network.
- Step 8: Configure routing: Allow external access or internal only access to your API.
- Step 9: Deploy a sample proxy: Test the provisioning by deploying and calling an API proxy.
Step 1: Define environment variables
Set up gcloud
and define environment variables for use in later steps:
- Be sure you have completed the setup requirements listed in Before you begin.
- You must have the Cloud SDK installed. If you need to install it, see Installing Cloud SDK.
- Initialize the Cloud SDK, as described in Initializing the gcloud CLI, or otherwise ensure that
the Google Cloud project you created in Prerequisites is the default project for
gcloud
. - Define the following environment variables in your command terminal.
Select the tab that corresponds to the type of organization you need:
No data residency or with
Data residency:
No data residency
AUTH="$(gcloud auth print-access-token)"
PROJECT_ID="YOUR_PROJECT_ID"
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
RUNTIME_LOCATION="YOUR_RUNTIME_LOCATION"
ANALYTICS_REGION="YOUR_ANALYTICS_REGION"
BILLING_TYPE="YOUR_BILLING_TYPE"
Where:
-
AUTH defines the
Authentication
header with a bearer token. You will use this header when calling Apigee APIs. Note that the token expires after a period of time and when it does, you can simply regenerate it using the same command. For more information, see the reference page for the print-access-token command. - PROJECT_ID is the Cloud project ID that you created as part of the Prerequisites.
- PROJECT_NUMBER is the Cloud project number that you created as part of the Prerequisites.
-
RUNTIME_LOCATION is the physical location where the Apigee instance you will create later is located. For a list of available runtime locations, see Apigee locations.
-
ANALYTICS_REGION is the physical location at which Apigee analytics data will be stored. For a list of available Apigee API Analytics regions, see Apigee locations.
Both RUNTIME_LOCATION and ANALYTICS_REGION can be the same region, but they do not have to be the same.
-
BILLING_TYPE is the billing type for the organization you create. Valid values are:
PAYG
for Pay-as-you-go organizations.SUBSCRIPTION
for Subscription organizations.
Data residency
AUTH="$(gcloud auth print-access-token)"
PROJECT_ID="YOUR_PROJECT_ID"
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
RUNTIME_LOCATION="YOUR_RUNTIME_LOCATION"
CONTROL_PLANE_LOCATION="YOUR_CONTROL_PLANE_LOCATION"
CONSUMER_DATA_REGION="YOUR_CONSUMER_DATA_REGION"
BILLING_TYPE="YOUR_BILLING_TYPE"
Where:
-
AUTH defines the
Authentication
header with a bearer token. You will use this header when calling Apigee APIs. Note that the token expires after a period of time and when it does, you can simply regenerate it using the same command. For more information, see the reference page for the print-access-token command. - PROJECT_ID is the Cloud project ID that you created as part of the Prerequisites.
- PROJECT_NUMBER is the Cloud project number that you created as part of the Prerequisites.
-
RUNTIME_LOCATION is the physical location where the Apigee instance you will create later is located. For a list of available runtime locations, see Apigee locations.
The runtime location must be within the control plane location. - CONTROL_PLANE_LOCATION is the physical location at which Apigee control plane data will be stored. For a list of available control plane locations, see Apigee locations.
- CONSUMER_DATA_REGION is a sub-region of the control plane region. You must specify both the CONTROL_PLANE_LOCATION and the CONSUMER_DATA_REGION. For a list of available consumer data regions, see Apigee locations.
-
BILLING_TYPE is the billing type for the organization you create. Valid values are:
PAYG
for Pay-as-you-go organizations.SUBSCRIPTION
for Subscription organizations.
-
AUTH defines the
- (Optional) Check your work by echoing the values you just set. Note that when you want
to use a variable in your commands, precede the variable's name with a dollar sign
($).
No data residency
echo $AUTH
echo $PROJECT_ID
echo $PROJECT_NUMBER
echo $RUNTIME_LOCATION
echo $ANALYTICS_REGION
echo $BILLING_TYPE
The responses to your
echo
commands should look something like the following:YOUR_TOKEN my-cloud-project 1234567890 us-west1 us-west1 SUBSCRIPTION
Data residency
echo $AUTH
echo $PROJECT_ID
echo $PROJECT_NUMBER
echo $RUNTIME_LOCATION
echo $CONTROL_PLANE_LOCATION
echo $CONSUMER_DATA_REGION
echo $BILLING_TYPE
The responses to your
echo
commands should look something like the following:YOUR_TOKEN my-cloud-project 1234567890 us-west1 us us-west1 SUBSCRIPTION
Step 2: Enable APIs
-
Apigee requires you to enable several Google Cloud APIs. Enable them by executing the following
services enable
command:gcloud services enable apigee.googleapis.com \ servicenetworking.googleapis.com \ compute.googleapis.com \ cloudkms.googleapis.com --project=$PROJECT_ID
(Optional) To check your work, use the
services list
command to show all the enabled APIs:gcloud services list
The response shows all enabled services, including the APIs that you just enabled.
Step 3: Create the Apigee service identity
-
Create the Apigee service identity:
gcloud beta services identity create --service=apigee.googleapis.com \ --project=$PROJECT_ID
Verify that the agent was successfully created. The response should show the name of the agent in the following format:
service-PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com
. for example:Service identity created: service-1234567890@gcp-sa-apigee.iam.gserviceaccount.com
Step 4: Configure service networking
In this step, you allocate a pair of IP Address Ranges (a /22 and /28 CIDR range) to Apigee and perform the VPC peering between your network and Apigee's network. Each Apigee instance requires a non-overlapping CIDR range of /22 and /28. The Apigee runtime plane is assigned IP addresses from within this CIDR range. As a result, it's important that the range is reserved for Apigee and not used by other applications in your VPC network. For more information and important considerations, see Understanding peering ranges.
Note that you are creating sufficient network IP range for one Apigee instance. If you plan to create additional Apigee instances, you have to repeat this step for each one. The ranges cannot be shared between instances. See also Expanding Apigee to multiple regions.
- Create these environment variables:
RANGE_NAME=YOUR_RANGE_NAME
NETWORK_NAME=YOUR_NETWORK_NAME
Where:
- RANGE_NAME is the name of the IP address range you are creating.
You can name the range anything you want. For example:
google-svcs
- NETWORK_NAME is the name of the network resource in which the addresses
should be reserved.
Google creates a default network (named
default
) for each new project, so you can use that. However, Google does not recommend using the default network for anything other than testing.
- RANGE_NAME is the name of the IP address range you are creating.
You can name the range anything you want. For example:
- Create a network IP range with a CIDR length of /22:
gcloud compute addresses create $RANGE_NAME \ --global \ --prefix-length=22 \ --description="Peering range for Apigee services" \ --network=$NETWORK_NAME \ --purpose=VPC_PEERING \ --addresses=OPTIONAL_ADDRESSES \ --project=$PROJECT_ID
Where
--addresses
lets you optionally specify an address range. For example, to allocate the CIDR block192.168.0.0/22
, specify192.168.0.0
for the address and22
for the prefix length. See also Creating an IP allocation.If you do not provide the
--addresses
parameter, then gcloud selects an available address range for you.On success,
gcloud
responds with the following:Created [https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/addresses/google-svcs].
After you create a range of IP addresses, the addresses are associated with the project until you release them.
- Verify the network IP range was created with a CIDR length of /22:
gcloud compute addresses list --global --project=$PROJECT_ID
gcloud compute addresses describe $RANGE_NAME --global --project=$PROJECT_ID
- Create a network IP range with a CIDR length of /28. This range is required and is
used by Apigee for troubleshooting purposes and cannot be customized or changed.
gcloud compute addresses create google-managed-services-support-1 \ --global \ --prefix-length=28 \ --description="Peering range for supporting Apigee services" \ --network=$NETWORK_NAME \ --purpose=VPC_PEERING \ --addresses=OPTIONAL_ADDRESSES \ --project=$PROJECT_ID
Where
--addresses
lets you optionally specify an address range. For example, to allocate the CIDR block192.168.0.0/28
, specify192.168.0.0
for the address and28
for the prefix length. See also Creating an IP allocation.If you do not provide the
--addresses
parameter, then gcloud selects an available address range for you. - Verify the network IP range was created with a CIDR length of /28:
gcloud compute addresses list --global --project=$PROJECT_ID
gcloud compute addresses describe google-managed-services-support-1 --global \ --project=$PROJECT_ID
- Connect your services to the network using the following command:
gcloud services vpc-peerings connect \ --service=servicenetworking.googleapis.com \ --network=$NETWORK_NAME \ --ranges=$RANGE_NAME,google-managed-services-support-1 \ --project=$PROJECT_ID
This operation can take several minutes to complete. On success,
gcloud
responds with the following, where OPERATION_ID is the UUID of the LRO.Operation "operations/OPERATION_ID" finished successfully.
- After few minutes, verify whether VPC peering succeeded:
gcloud services vpc-peerings list \ --network=$NETWORK_NAME \ --service=servicenetworking.googleapis.com \ --project=$PROJECT_ID
Apigee creates a connection between your network and Google's services; specifically, Apigee connects your project to the Service Networking API through VPC peering. Apigee also associates IP addresses with your project.
Step 5: Create an organization
Before you can create an organization, you must create a runtime database encryption key ring and key (see step 1) and, if you are using data residency, control plane encryption key rings and keys (see step 2). These Cloud KMS keys encrypt data that is stored and replicated across runtime and control plane locations. Apigee uses these entities to encrypt application data such as KVMs, cache, and client secrets, which is then stored in the database. For more information, see About the Apigee encryption keys.
-
Create a runtime database encryption key ring and key.
-
Define an environment variable for the location of your runtime database encryption ring and key. This helps ensure consistency when you create them and makes it easier for you to follow along in the documentation.
The value is the physical location where your runtime database encryption key ring and key are stored.
Single region
Single region configurations (in which you have just one instance in one region): Choose from the supported KMS regional locations.
For example:
RUNTIMEDBKEY_LOCATION="us-west1"
The value can be the same as your $RUNTIME_LOCATION (also a region) but it does not have to be. However, there may be a performance benefit if they are the same.
Multi-region
Multi-region configurations: Choose from the supported multi-regional locations (such as
us
oreurope
) or dual-regional locations.For example:
RUNTIMEDBKEY_LOCATION="us"
We recommend that if you have a multi-region configuration in the US, use
us
for your location if possible. Otherwise, usenam4
. - Define environment variables for database key rings and key names.
The key ring's name must be unique to your organization. If you create a second or subsequent region, the name cannot be the same as other key rings' names.
RUNTIMEDB_KEY_RING_NAME=YOUR_DB_KEY_RING_NAME
RUNTIMEDB_KEY_NAME=YOUR_DB_KEY_NAME
- (Optional) Check your work by echoing the values you just set. Remember that when you want
to use a variable in your commands, precede the variable's name with a dollar sign
($).
echo $RUNTIMEDBKEY_LOCATION
echo $RUNTIMEDB_KEY_RING_NAME
echo $RUNTIMEDB_KEY_NAME
- Create a new key ring:
gcloud kms keyrings create $RUNTIMEDB_KEY_RING_NAME \ --location $RUNTIMEDBKEY_LOCATION --project $PROJECT_ID
The Apigee runtime database encryption key's location supports all Cloud KMS locations that support Cloud HSM and Cloud EKM.
Create a key:
gcloud kms keys create $RUNTIMEDB_KEY_NAME \ --keyring $RUNTIMEDB_KEY_RING_NAME \ --location $RUNTIMEDBKEY_LOCATION \ --purpose "encryption" \ --project $PROJECT_ID
This command creates the key and adds it to the key ring.
Get the key ID:
gcloud kms keys list \ --location=$RUNTIMEDBKEY_LOCATION \ --keyring=$RUNTIMEDB_KEY_RING_NAME \ --project=$PROJECT_ID
The key ID has the following syntax (similar to a file path):
projects/PROJECT_ID/locations/RUNTIMEDBKEY_LOCATION/keyRings/RUNTIMEDB_KEY_RING_NAME/cryptoKeys/RUNTIMEDB_KEY_NAME
Put the key ID in an environment variable. You will use this variable in a later command:
RUNTIMEDB_KEY_ID=YOUR_RUNTIMEDB_KEY_ID
Grant access for the Apigee Service Agent to use the new key:
gcloud kms keys add-iam-policy-binding $RUNTIMEDB_KEY_NAME \ --location $RUNTIMEDBKEY_LOCATION \ --keyring $RUNTIMEDB_KEY_RING_NAME \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter \ --project $PROJECT_ID
This command binds the key to the Apigee Service Agent.
On successful completion of this request,
gcloud
responds with something similar to the following:Updated IAM policy for key [runtime]. bindings: - members: - serviceAccount:service-1234567890@gcp-sa-apigee.iam.gserviceaccount.com role: roles/cloudkms.cryptoKeyEncrypterDecrypter etag: BwWqgEuCuwk= version: 1
If you get an error like the following:
INVALID_ARGUMENT: Role roles/cloudkms.cryptokms.cryptoKeyEncrypterDecrypter is not supported for this resource.
Be sure that you used the project number and not the project name in the service account email address.
-
- If you are using data residency, create a control plane encryption key ring and key. If you are not using data residency, go to step 3.
- Define an environment variable for the location of your control plane database encryption ring and key:
CONTROL_PLANE_LOCATION=YOUR_CONTROL_PLANE_LOCATION
CONSUMER_DATA_REGION=YOUR_CONSUMER_DATA_REGION
Where:
- CONTROL_PLANE_LOCATION is the physical location at which Apigee control plane data will be stored. For a list of available control plane locations, see Apigee locations.
- CONSUMER_DATA_REGION is a sub-region of the control plane region. You must specify both the CONTROL_PLANE_LOCATION and the CONSUMER_DATA_REGION. For a list of available consumer data regions, see Apigee locations.
Define environment variables for control plane database key rings and key names.
The key ring's name must be unique to your organization.
CONTROL_PLANE_KEY_RING_NAME=YOUR_CONTROL_PLANE_KEY_RING_NAME
CONTROL_PLANE_KEY_NAME=YOUR_CONTROL_PLANE_KEY_NAME
CONSUMER_DATA_KEY_RING_NAME=YOUR_CONSUMER_DATA_KEY_RING_NAME
CONSUMER_DATA_KEY_NAME=YOUR_CONSUMER_DATA_REGION_KEY_NAME
Where:
- CONTROL_PLANE_KEY_RING_NAME is the name of the key ring you will use to identify your control plane encryption key ring.
- CONTROL_PLANE_KEY_NAME is the name of the key you will use to identify your control plane encryption key.
- CONSUMER_DATA_KEY_RING_NAME is the name of the key ring you will use to identify your consumer data region encryption key ring.
- CONSUMER_DATA_KEY_NAME is the name of the key you will use to identify your consumer data region encryption key.
- Create a new key ring:
gcloud kms keyrings create $CONTROL_PLANE_KEY_RING_NAME \ --location $CONTROL_PLANE_LOCATION \ --project $PROJECT_ID
gcloud kms keyrings create $CONSUMER_DATA_KEY_RING_NAME \ --location $CONSUMER_DATA_REGION \ --project $PROJECT_ID
- Create a key:
gcloud kms keys create $CONTROL_PLANE_KEY_NAME \ --keyring $CONTROL_PLANE_KEY_RING_NAME \ --location $CONTROL_PLANE_LOCATION \ --purpose "encryption" \ --project $PROJECT_ID
gcloud kms keys create $CONSUMER_DATA_KEY_NAME \ --keyring $CONSUMER_DATA_KEY_RING_NAME \ --location $CONSUMER_DATA_REGION \ --purpose "encryption" \ --project $PROJECT_ID
This command creates the key and adds it to the key ring.
Get the key ID:
gcloud kms keys list \ --location=$CONTROL_PLANE_LOCATION \ --keyring=$CONTROL_PLANE_KEY_RING_NAME \ --project=$PROJECT_ID
gcloud kms keys list \ --location=$CONSUMER_DATA_REGION \ --keyring=$CONSUMER_DATA_KEY_RING_NAME \ --project=$PROJECT_ID
The key ID has the following syntax (similar to a file path):
projects/PROJECT_ID/locations/CONTROL_PLANE_LOCATION/keyRings/CONTROL_PLANE_KEY_RING_NAME/cryptoKeys/CONTROL_PLANE_KEY_NAME
projects/PROJECT_ID/locations/CONSUMER_DATA_REGION/keyRings/CONSUMER_DATA_KEY_RING_NAME/cryptoKeys/CONSUMER_DATA_KEY_NAME
- Put the key ID in an environment variable. You will use this variable in a later command:
CONTROL_PLANE_KEY_ID=YOUR_CONTROL_PLANE_KEY_ID
CONSUMER_DATA_KEY_ID=YOUR_CONSUMER_DATA_KEY_ID
- Grant access for the Apigee Service Agent to use the new key:
gcloud kms keys add-iam-policy-binding $CONTROL_PLANE_KEY_NAME \ --location $CONTROL_PLANE_LOCATION \ --keyring $CONTROL_PLANE_KEY_RING_NAME \ --member "serviceAccount:service-$PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com" \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter \ --project $PROJECT_ID
gcloud kms keys add-iam-policy-binding $CONSUMER_DATA_KEY_NAME \ --location $CONSUMER_DATA_REGION \ --keyring $CONSUMER_DATA_KEY_RING_NAME \ --member "serviceAccount:service-$PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com" \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter \ --project $PROJECT_ID
This command binds the key to the Apigee Service Agent. On successful completion of this request, gcloud responds with something similar to the following:
Updated IAM policy for key [runtime]. bindings: - members: - serviceAccount:service-1234567890@gcp-sa-apigee.iam.gserviceaccount.com role: roles/cloudkms.cryptoKeyEncrypterDecrypter etag: BwWqgEuCuwk= version: 1
If you get an error like the following:
INVALID_ARGUMENT: Role roles/cloudkms.cryptokms.cryptoKeyEncrypterDecrypter is not supported for this resource.
Be sure that you used the project number and not the project name in the service account email address.
-
Create the organization by sending the following request to the Apigee organizations API:
No data residency
curl "https://apigee.googleapis.com/v1/organizations?parent=projects/$PROJECT_ID" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name":"'"$PROJECT_ID"'", "analyticsRegion":"'"$ANALYTICS_REGION"'", "runtimeType":"CLOUD", "billingType":"'"$BILLING_TYPE"'", "authorizedNetwork":"'"$NETWORK_NAME"'", "runtimeDatabaseEncryptionKeyName":"'"$RUNTIMEDB_KEY_ID"'" }'
Where:
-d
defines the data payload for the request. This payload must include the following:name
: Identifies your new organization. It must be the same name as your project ID.analyticsRegion
: Specifies the physical location where your analytics data will be stored.runtimeType
: Set this value toCLOUD
.billingType
: Specifies the billing type of the organization created.authorizedNetwork
: Identifies the peering network that you specified in Configure service networking.runtimeDatabaseEncryptionKeyName
: The ID of the application encryption key that you created in the previous step. Recall that the ID is structured like a file path. For example:projects/my-project/locations/us-west1/keyRings/my-key-ring/cryptoKeys/my-key
Data residency
Create an organization using the API:
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations?parent=projects/$PROJECT_ID" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name":"'"$PROJECT_ID"'", "runtimeType":"CLOUD", "billingType":"'"$BILLING_TYPE"'", "controlPlaneEncryptionKeyName":"'"$CONTROL_PLANE_KEY_ID"'", "apiConsumerDataLocation":"'"$CONSUMER_DATA_REGION"'", "apiConsumerDataEncryptionKeyName":"'"$CONSUMER_DATA_KEY_ID"'", "authorizedNetwork":"'"$NETWORK_NAME"'", "runtimeDatabaseEncryptionKeyName":"'"$RUNTIMEDB_KEY_ID"'" }'
Where:
-d
defines the data payload for the request. This payload must include the following:name
: Identifies your new organization. It must be the same name as your project ID.runtimeType
: Set this value toCLOUD
.billingType
: Specifies the billing type of the organization created.controlPlaneEncryptionKeyName
: Is your control plane key ID.apiConsumerDataLocation
: You must also specify a sub-region for use by internal resources. See Data residency regions for supported values.apiConsumerDataEncryptionKeyName
: Is your consumer data region key ID.authorizedNetwork
: Identifies the peering network that you specified in Configure service networking.runtimeDatabaseEncryptionKeyName
: The ID of the application encryption key that you created in the previous step. Recall that the ID is structured like a file path. For example:
projects/my-project/locations/us-west1/keyRings/my-key-ring/cryptoKeys/my-key
After you execute this command, Apigee starts a long-running operation, which can take a few minutes to complete.
If you get an error, check your use of quotation marks around the variable values in the data payload. Be sure that you have double-single-double quotes around the $PROJECT_ID variable, as the following example shows:
"'"$PROJECT_ID"'"
If you use plain strings (not environment variables) for request values, you can wrap them in double quotes within the single-quoted payload string, as the following example shows:
'{ "name":"my-gcp-project", ... }'
- Wait a few minutes.
- To check the status of your creation request, you can send a
GET
request to the Apigee List organizations API, as the following example shows:No data residency
curl -H "Authorization: Bearer $AUTH" "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID"
Data residency
curl -H "Authorization: Bearer $AUTH" "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID"
If you see this response, then the organization creation has not completed yet:
{ "error": { "code": 403, "message": "Permission denied on resource \"organizations/apigee-docs-m\" (or it may not exist)", "status": "PERMISSION_DENIED" } }
If Apigee has successfully created a new organization, you will receive a response that is similar to the following:
No data residency
{ "name": "my-cloud-project", "createdAt": "1592586495539", "lastModifiedAt": "1592586495539", "environments": [], "properties": { "property": [ { "name": "features.hybrid.enabled", "value": "true" }, { "name": "features.mart.connect.enabled", "value": "true" } ] }, "analyticsRegion": "us-west1", "runtimeType": "CLOUD", "subscriptionType": "PAID", "caCertificate": "YOUR_CERTIFICATE", "authorizedNetwork": "my-network", "projectId": "my-cloud-project" }
Data residency
{ "name": "my-cloud-project", "createdAt": "1681412783749", "lastModifiedAt": "1681412783749", "environments": [ "test-env" ], "properties": { "property": [ { "name": "features.mart.connect.enabled", "value": "true" }, { "name": "features.hybrid.enabled", "value": "true" } ] }, "authorizedNetwork": "default", "runtimeType": "CLOUD", "subscriptionType": "PAID", "caCertificate": "YOUR_CERTIFICATE", "runtimeDatabaseEncryptionKeyName": "projects/my-cloud-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-key-name", "projectId": "my-cloud-project", "state": "ACTIVE", "billingType": "PAYG", "addonsConfig": { "advancedApiOpsConfig": {}, "integrationConfig": {}, "monetizationConfig": {}, "connectorsPlatformConfig": {} }, "apiConsumerDataEncryptionKeyName": "projects/my-cloud-project/locations/us-central1/keyRings/my-key-ring/cryptoKeys/my-key-name", "controlPlaneEncryptionKeyName": "projects/my-cloud-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-key-name", "apiConsumerDataLocation": "us-central1", "apigeeProjectId": "i0c2a37e80f9850ab-tp" }
If Apigee returns an HTTP error response, then see Creating an Apigee organization.
Perform the following steps to create a control plane encryption key ring and key.
See also: CMEK troubleshooting.
Step 6: Create a runtime instance
A runtime instance is where your Apigee project and related services are stored; it provides the user-facing endpoint for your services. To create a new runtime instance:
-
Check that Apigee has finished creating your organization. You submitted a request to create a new organization in Create an Apigee organization, but you need to be sure it's done before you continue.
To do this, send the following request to the organizations API:
No data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID"
Data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID"
If the organization exists (and you have the proper permissions to view it), Apigee responds with details about it. If Apigee responds with an error, wait a couple of minutes and send the request again.
- Similar to the preceding task where you created an encryption key for the database,
now you need to create a
Cloud KMS key used to encrypt data on the server side.
To get started, define the following environment variables:
INSTANCE_NAME=YOUR_INSTANCE_NAME
RUNTIME_LOCATION=YOUR_RUNTIME_LOCATION
DISK_KEY_RING_NAME=YOUR_DISK_KEY_RING_NAME
DISK_KEY_NAME=YOUR_DISK_KEY_NAME
- INSTANCE_NAME: Your new instance's name. For example,
my-runtime-instance
. The name must start with a lowercase letter, can be up to 32 characters long, and can include only lowercase letters, numbers and hyphens. It cannot start or end with a hyphen and must be at least two characters long. - RUNTIME_LOCATION is the physical place in which your cluster is hosted.
Valid values are any location allowed by Compute Engine. (See
Available regions and zones.) This example uses
us-west1
. - DISK_KEY_RING_NAME is the name of the disk encryption key ring.
- DISK_KEY_NAME is the name of the disk encryption key.
- Create a disk encryption key:
- Create a new disk key ring:
gcloud kms keyrings create $DISK_KEY_RING_NAME \ --location $RUNTIME_LOCATION \ --project $PROJECT_ID
Your disk key ring must be set to the same location as the instance. Each instance and key ring should have its own location.
- Create a new disk key:
gcloud kms keys create $DISK_KEY_NAME \ --keyring $DISK_KEY_RING_NAME \ --location $RUNTIME_LOCATION \ --purpose "encryption" \ --project $PROJECT_ID
The key can be referenced by its key path. You can get the key path with the following command:
gcloud kms keys list \ --location=$RUNTIME_LOCATION \ --keyring=$DISK_KEY_RING_NAME \ --project=$PROJECT_ID
The key path looks something like the following:
projects/PROJECT_ID/locations/RUNTIME_LOCATION/keyRings/my-disk-key-ring/cryptoKeys/my-disk-key
Put the key path in an environment variable. You will use this variable in a later command:
DISK_KEY_ID=YOUR_DISK_KEY_ID
For example:
DISK_KEY_ID=projects/my-project/locations/us-west1/keyRings/my-key-ring/cryptoKeys/my-key
Grant access for the Apigee Service Agent to use the new key:
gcloud kms keys add-iam-policy-binding $DISK_KEY_NAME \ --location $RUNTIME_LOCATION \ --keyring $DISK_KEY_RING_NAME \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter \ --project $PROJECT_ID
This command binds the key to the Apigee Service Agent.
For more information, see About the Apigee encryption keys.
- Create a new disk key ring:
- Reserve an IP range that will be used for the Apigee instance creation.
- Create a new runtime instance for your project by sending a
POST
request to the Apigee Instances API:No data residency
curl "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances" \ -X POST -H "Authorization: Bearer $AUTH" \ -H "Content-Type:application/json" \ -d '{ "name":"'"$INSTANCE_NAME"'", "location":"'"$RUNTIME_LOCATION"'", "diskEncryptionKeyName":"'"$DISK_KEY_ID"'", "consumerAcceptList":["'"$PROJECT_ID"'"] }'
Data residency
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances" \ -X POST -H "Authorization: Bearer $AUTH" \ -H "Content-Type:application/json" \ -d '{ "name":"'"$INSTANCE_NAME"'", "location":"'"$RUNTIME_LOCATION"'", "diskEncryptionKeyName":"'"$DISK_KEY_ID"'", "consumerAcceptList":["'"$PROJECT_ID"'"] }'
Where:
consumerAcceptList
(Optional) Specifies a list of Google Cloud project IDs that can privately connect to the Apigee VPC's service attachment. Service attachment is an entity used with Google Cloud Private Service Connect to allow service producers (in this case, Apigee) to expose services to consumers (in this case, one or more Cloud projects that you own). By default, we use the Cloud project that is already associated with your Apigee organization. For example:"consumerAcceptList": ["project1", "project2", "project3"]
Note that you can also set and change the list of accepted projects in the Instance UI. For details, see Managing instances.
This request can take up to 20 minutes to complete because Apigee must create and launch a new Kubernetes cluster, install the Apigee resources on that cluster, and set up load balancing.
If Apigee returns an error, see Creating a new instance.
To check the status of your runtime instance creation request, execute the following command. When the state is ACTIVE, you can go on to the next step.
No data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME"
Data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME"
Where:
Step 7: Create an environment
To create an environment and attach it to the runtime on the command line:
- Define environment variables to be used in this section. The specific environment variables you create
will depend upon whether you are creating an environment for a subscription or Pay-as-you-go
org.
Subscription
For a subscription environment, create these variables:
ENVIRONMENT_NAME="YOUR_ENV_NAME"
ENV_GROUP_NAME="YOUR_ENV_GROUP_NAME"
ENV_GROUP_HOSTNAME="YOUR_ENV_GROUP_HOSTNAME"
Where:
ENVIRONMENT_NAME
is a string name. For example:test
ENV_GROUP_NAME
is a string name. For example:test-group
ENV_GROUP_HOSTNAME
is a valid domain host name. For example:foo.example.com
Pay-as-you-go
For a Pay-as-you-go environment, create these variables:
ENVIRONMENT_NAME="YOUR_ENV_NAME"
ENVIRONMENT_TYPE="YOUR_ENV_TYPE"
ENV_GROUP_NAME="YOUR_ENV_GROUP_NAME"
ENV_GROUP_HOSTNAME="YOUR_ENV_GROUP_HOSTNAME"
Where:
ENVIRONMENT_NAME
is a string name. For example:test
ENVIRONMENT_TYPE
is the environment type for this environment and is only applicable for Pay-as-you-go users, who must specify one of these values:BASE
,INTERMEDIATE
, orCOMPREHENSIVE
. Other users should omit the environment type.ENV_GROUP_NAME
is a string name. For example:test-group
ENV_GROUP_HOSTNAME
is a valid domain host name. For example:foo.example.com
- Create a new environment with the Environments API. The specific commands you use
will depend upon whether you are creating an environment for a subscription or Pay-as-you-go
org.
Subscription
For a new subscription environment, use the following command:
No data residency
curl "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name":"'"$ENVIRONMENT_NAME"'" }'
Data residency
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name":"'"$ENVIRONMENT_NAME"'" }'
Apigee creates a new environment.
Pay-as-you-go
For a new Pay-as-you-go environment, use the following command:
No data residency
curl "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name":"'"$ENVIRONMENT_NAME"'", "type":"'"$ENVIRONMENT_TYPE"'" }'
Data residency
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name":"'"$ENVIRONMENT_NAME"'", "type":"'"$ENVIRONMENT_TYPE"'" }'
Apigee creates a new environment.
- Before you continue, check that Apigee finished creating the new environment by
calling the Environments API:
No data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments"
Data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments"
Apigee responds with a list of available environments; for example, if your environment name is
test
, Apigee responds with the following:[ "test" ]
- Attach the new environment to the runtime instance:
No data residency
curl "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME/attachments" \ -X POST -H "Authorization: Bearer $AUTH" \ -H "content-type:application/json" \ -d '{ "environment":"'"$ENVIRONMENT_NAME"'" }'
Data residency
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME/attachments" \ -X POST -H "Authorization: Bearer $AUTH" \ -H "content-type:application/json" \ -d '{ "environment":"'"$ENVIRONMENT_NAME"'" }'
This operation can take several minutes to complete. To check to see if the attachment is completed, execute this command:
No data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME/attachments"
Data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME/attachments"
When you see output like the following, you can go to the next step:
{ "attachments": [ { "name": "ed628782-c893-4095-b71c-f4731805290a", "environment": "test", "createdAt": "1641604447542" } ] }
- Create a new environment group using the following command. For more information, see
About environments and environment groups:
No data residency
curl "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name": "'"$ENV_GROUP_NAME"'", "hostnames":["'"$ENV_GROUP_HOSTNAME"'"] }'
Data residency
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups" \ -H "Authorization: Bearer $AUTH" \ -X POST \ -H "Content-Type:application/json" \ -d '{ "name": "'"$ENV_GROUP_NAME"'", "hostnames":["'"$ENV_GROUP_HOSTNAME"'"] }'
- Wait for the operation to complete. You can check the status of your new group using a
request like the following:
No data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME"
Data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME"
- Attach the new environment to the new environment group with the following command:
No data residency
curl "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME/attachments" \ -X POST \ -H "Authorization: Bearer $AUTH" \ -H "content-type:application/json" \ -d '{ "environment":"'"$ENVIRONMENT_NAME"'" }'
Data residency
curl "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME/attachments" \ -X POST \ -H "Authorization: Bearer $AUTH" \ -H "content-type:application/json" \ -d '{ "environment":"'"$ENVIRONMENT_NAME"'" }'
- To check the status of the operation, call this API:
No data residency
curl -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME/attachments"
Data residency
curl -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME/attachments"
Step 8: Configure routing
In this step, you configure how client applications communicate with Apigee. Client to Apigee traffic is also called "northbound" traffic. Northbound configuration options include the following. Go to the configuration option you wish to use and perform the steps for that option:
Access type | Description of the configuration and deployment process |
---|---|
Internal with VPC peering |
Allow only internal access to your API proxies. You must create a new VM inside the network and connect to it. From the new VM, you can send a request to an Apigee API proxy. |
External with MIG |
Allow external access to your API proxies. Use a managed instance group (MIG) to send API traffic from a global load balancer's backend service to Apigee. With this configuration, Apigee is only able to connect to the peered VPC. This configuration lets you send Apigee API proxy requests from any network-enabled machine. |
Internal with PSC (New) |
Allow only internal access to your API proxies from any of your Google Cloud projects using Private Service Connect (PSC). PSC enables private connection between a service producer (Apigee) and a service consumer (the peered VPC project and/or one or more other Cloud projects that you control). With this method, requests pass through either a service endpoint or a regional internal load balancer to a single point of attachment, called a service attachment. This configuration lets your internal clients send Apigee API proxy requests from any network-enabled machine. |
External with PSC (New) |
Allow external access to your API proxies using Private Service Connect (PSC). Use Private Service Connect (PSC) to enable private connection between a service producer (Apigee) and a service consumer (the peered VPC project and/or one or more other Cloud projects that you control). With this method, requests pass through either a global external load balancer or a regional external load balancer to a single point of attachment, called a service attachment. This configuration lets you send Apigee API proxy requests from any network-enabled machine. |
Each of these routing approaches is presented in the instructions below.
Internal routing (VPC)
For routing of traffic from internal clients to Apigee, you can choose to use TLS termination or not:
- TLS Options: You have two choices if you want to make API proxy
calls from internal clients with TLS enabled:
- (Option 1) Configure an internal load balancer (ILB):
- Create a managed instance group (MIG) in your project. To create the MIG, follow the steps 8a, 8b, and 8c in the External routing (MIG) tab.
- Create and configure an internal HTTPS(S) load balancer (ILB), and attach the MIG you created to the backend service of the ILB, as explained in Set up Internal HTTP(S) Load Balancing with VM instance group backends. With the ILB configuration, you have full control over the CA certificates used with the ILB.
- Go to Calling an API proxy with internal-only access to test the setup.
- (Option 2) Use the internal, default fully qualified domain name and the internal load balancer IP of the Apigee instance. This case is recommended only for testing purposes, and not for a production environment. In this case, Apigee-created self-signed certificates are used, with Apigee's internal load balancer, and you cannot change them. See Calling an API proxy with internal-only access.
- (Option 1) Configure an internal load balancer (ILB):
- Non-TLS option: If you don't need to enable TLS termination, you can call API proxies
where the client disables TLS. For example, by using the
-k
option with cURL, you can disable TLS. See Calling an API proxy with internal-only access.
External routing (MIG)
This section describes how to configure routing to allow external access to API proxies using a managed instance group (MIG) to send API traffic from a global load balancer's backend service to Apigee. You must do this before you can send a request from an external client to your Apigee runtime instance.
The general process is as follows:
Step 8a: Enable Private Google Access for a subnet of your VPC network
Step 8b: Set up environment variables
Step 8c: Create a managed instance group
Step 8d: Create an SSL certificate and key for the load balancer
Step 8e: Create a global load balancer
Step 8f: Get a reserved IP address and create firewall rules
Each of these steps is described in the sections that follow.
Step 8a: Enable Private Google Access for a subnet of your VPC network
To enable Private Google Access for a subnet of your VPC network, follow the steps listed in Enabling Private Google Access.
Step 8b: Set up environment variables
The instructions in this section use environment variables to refer to repeatedly used strings. We recommend that you set these before continuing:
MIG_NAME=apigee-mig-MIG_NAME # You can choose a different name if you likeVPC_NAME=default # If you are using a shared VPC, use the shared VPC name
VPC_SUBNET=default # Private Google Access must be enabled for this subnet
REGION=RUNTIME_REGION # The same region as your Apigee runtime instance
APIGEE_ENDPOINT=APIGEE_INSTANCE_IP
# See the tip below for details on getting this IP address value
You'll use these variables several times during the remaining processes. If you wish to configure multiple regions, then create variables with values specific for each region.
Step 8c: Create a managed instance group
In this step, you create and configure a managed instance group (MIG). In a later step, you add the MIG to a backend service which is attached to a global load balancer. A MIG is required to send API traffic from the global load balancer's backend service to Apigee.
To create a MIG:
- Create an instance template by executing the following command.
gcloud compute instance-templates create $MIG_NAME \ --project $PROJECT_ID \ --region $REGION \ --network $VPC_NAME \ --subnet $VPC_SUBNET \ --tags=https-server,apigee-mig-proxy,gke-apigee-proxy \ --machine-type e2-medium --image-family debian-12 \ --image-project debian-cloud --boot-disk-size 20GB \ --no-address \ --metadata ENDPOINT=$APIGEE_ENDPOINT,startup-script-url=gs://apigee-5g-saas/apigee-envoy-proxy-release/latest/conf/startup-script.sh
As you can see from this command, machines are of type
e2-medium
. They run Debian 12 and have 20GB of disk. Thestartup-script.sh
script configures the MIG to route inbound traffic from the load balancer to the Apigee instance. - Create a managed instance group by executing the following command:
gcloud compute instance-groups managed create $MIG_NAME \ --project $PROJECT_ID --base-instance-name apigee-mig \ --size 2 --template $MIG_NAME --region $REGION
- Configure autoscaling for the group by executing the following command:
gcloud compute instance-groups managed set-autoscaling $MIG_NAME \ --project $PROJECT_ID --region $REGION --max-num-replicas 3 \ --target-cpu-utilization 0.75 --cool-down-period 90
- Define a named port by executing the following command:
gcloud compute instance-groups managed set-named-ports $MIG_NAME \ --project $PROJECT_ID --region $REGION --named-ports https:443
Step 8d: Create an SSL certificate and key for the load balancer
You only need to create the credentials once, whether you are installing in single or multi regions. In a later step, you will associate these credentials with the load balancer's target HTTPS proxy.
You can create the credentials with:
- Your own certificate from a certificate authority
- A Google-managed SSL certificate
- A self-signed certificate (not recommended for production).
For more information on creating and using SSL certificates for Google Cloud load balancer, see SSL certificates and SSL certificate overview.
In the following example, we create a Google-managed SSL certificate:
- Create these environment variables:
CERTIFICATE_NAME=YOUR_CERT_NAME
DOMAIN_HOSTNAME=YOUR_DOMAIN_HOSTNAME
Set
DOMAIN_HOSTNAME
to a valid domain hostname that you have registered. In a later step, you will obtain the load balancer's IP address and update the domain A record to point to that address. For example, a domain hostname might look like this:foo.example.com
. - Execute the
gcloud compute ssl-certificates create command:
gcloud compute ssl-certificates create $CERTIFICATE_NAME \ --domains=$DOMAIN_HOSTNAME \ --project $PROJECT_ID \ --global
The certificate can take up to an hour to be provisioned. To check the status of the provisioning, execute this command:
gcloud compute ssl-certificates describe $CERTIFICATE_NAME \ --global \ --format="get(name,managed.status, managed.Status)"
Step 8e: Create a global load balancer
- Create a health check:
gcloud compute health-checks create https HEALTH_CHECK_NAME \ --project $PROJECT_ID --port 443 --global \ --request-path /healthz/ingress
You'll use this health check to ensure that the backend service is running. For configuring more advanced health checks against a specific proxy, see Performing health checks.
- Create a backend service:
gcloud compute backend-services create PROXY_BACKEND_NAME \ --project $PROJECT_ID \ --protocol HTTPS \ --health-checks HEALTH_CHECK_NAME \ --port-name https \ --timeout 302s \ --connection-draining-timeout 300s \ --global
- Add the MIG to your backend service with the following command:
gcloud compute backend-services add-backend PROXY_BACKEND_NAME \ --project $PROJECT_ID --instance-group $MIG_NAME \ --instance-group-region $REGION \ --balancing-mode UTILIZATION --max-utilization 0.8 --global
- Create a load balancing URL map with the following command:
gcloud compute url-maps create MIG_PROXY_MAP_NAME \ --project $PROJECT_ID --default-service PROXY_BACKEND_NAME
- Create a load balancing target HTTPS proxy with the following command:
gcloud compute target-https-proxies create MIG_HTTPS_PROXY_NAME \ --project $PROJECT_ID --url-map MIG_PROXY_MAP_NAME \ --ssl-certificates $CERTIFICATE_NAME
Step 8f: Get a reserved IP address and create firewall rules
You must assign an IP address to the load balancer and then create rules that allow the load balancer to access the MIG. You only need to do this step once, whether you are installing in single or multi regions.
- Reserve an IP address for the load balancer:
gcloud compute addresses create ADDRESSES_NAME \ --project $PROJECT_ID \ --ip-version=IPV4 \ --global
- Create a global forwarding rule with the following command:
gcloud compute forwarding-rules create FORWARDING_RULE_NAME \ --project $PROJECT_ID --address ADDRESSES_NAME --global \ --target-https-proxy MIG_HTTPS_PROXY_NAME --ports 443
- Get the reserved IP address by executing the following command:
gcloud compute addresses describe ADDRESSES_NAME \ --project $PROJECT_ID --format="get(address)" --global
- Important step: Go to the site, DNS host, or ISP where your DNS records are managed, and make sure your domain's DNS record resolves to the IP address of the Google Cloud load balancer. This address is the IP value returned in the last step. For more detail, see Update the DNS A and AAAA records to point to the load balancer's IP address.
- Create a firewall rule that lets the load balancer access the MIG by using the
following command:
gcloud compute firewall-rules create FIREWALL_RULE_NAME \ --description "Allow incoming from GLB on TCP port 443 to Apigee Proxy" \ --project $PROJECT_ID --network $VPC_NAME --allow=tcp:443 \ --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=gke-apigee-proxy
Note that the IP address ranges
130.211.0.0/22
and35.191.0.0/16
are the source IP address ranges for Google Load Balancing. This firewall rule allows Google Cloud Load Balancing to make health check requests to the MIG.
Apigee provisioning is complete. Go to Deploy a sample proxy.
Internal routing (PSC)
This section explains how to allow only internal access to your API proxies from any of your Google Cloud projects using Private Service Connect (PSC).
You have two options for configuring internal access with PSC:
- Service endpoint: Requests pass through a service endpoint to a single point of attachment, called a service attachment.
- Internal regional load balancer: Requests pass through a regional internal HTTP(S) load balancer. See also Global vs regional load balancing.
Select the tab below for your configuration choice and follow the steps:
Service endpoint
Create a PSC service endpoint for the service attachment
- Get the service attachment from the instance you created previously:
No data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
Data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
In the following sample output, the
serviceAttachment
value is shown in bold type:{ "instances": [ { "name": "us-west1", "location": "us-west1", "host": "10.82.192.2", "port": "443", "createdAt": "1645731488019", "lastModifiedAt": "1646504754219", "diskEncryptionKeyName": "projects/my-project/locations/us-west1/keyRings/us-west1/cryptoKeys/dek", "state": "ACTIVE", "peeringCidrRange": "SLASH_22", "runtimeVersion": "1-7-0-20220228-190814", "ipRange": "10.82.192.0/22,10.82.196.0/28", "consumerAcceptList": [ "875609189304" ], "serviceAttachment": "projects/bfac74a67a320c43a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw1" } ] }
- Create a PSC Service Endpoint that points to the service attachment that you obtained from the instance response body in the previous step, as explained in Create a Private Service Connect endpoint.
- To test the setup, go to Calling an API proxy with internal-only access.
Internal regional LB
Step 8a: Set up environment variables
The instructions in this section use environment variables to refer to repeatedly used strings. Be sure you have set the variables in Define environment variables.
In addition, set the following environment variables:
NEG_NAME=YOUR_NEG_NAME"TARGET_SERVICE=YOUR_TARGET_SERVICE"
NETWORK_NAME=YOUR_NETWORK_NAME"
SUBNET_NAME=YOUR_SUBNET_NAME"
Where:
- NEG_NAME: a name for the network endpoint group.
- TARGET_SERVICE: the service attachment that you want to
connect to. For example:
projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7
- NETWORK_NAME: (Optional) Name of the network in which the NEG is created. If you omit
this parameter, the
default
project network is used. - SUBNET_NAME: Name of the subnet used for private connectivity to the producer. The subnet size can be small: the PSC NEG only needs one IP from the subnet. For Apigee, only one PSC NEG is needed per region. The subnet can be shared and used by VMs or other entities. If a subnet is not specified, network endpoints may belong to any subnetwork in the region where the network endpoint group is created.
Step 8b: Create a proxy-only subnet
gcloud compute networks subnets create testproxyonlysubnet \ --purpose=REGIONAL_MANAGED_PROXY --role=ACTIVE --region=$RUNTIME_REGION --network=$NETWORK_NAME \ --range=100.0.0.0/24 --project=$PROJECT_ID
Step 8c: Create a network endpoint group (NEG)
- Get the service attachment from the instance you created previously:
No data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
Data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
In the following sample output, the
serviceAttachment
value is shown in bold type:{ "instances": [ { "name": "us-west1", "location": "us-west1", "host": "10.82.192.2", "port": "443", "createdAt": "1645731488019", "lastModifiedAt": "1646504754219", "diskEncryptionKeyName": "projects/my-project/locations/us-west1/keyRings/us-west1/cryptoKeys/dek", "state": "ACTIVE", "peeringCidrRange": "SLASH_22", "runtimeVersion": "1-7-0-20220228-190814", "ipRange": "10.82.192.0/22,10.82.196.0/28", "consumerAcceptList": [ "875609189304" ], "serviceAttachment": "projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7" } ] }
Create a Private Service Connect NEG that points to the service attachment that you obtained from the instance response body in the previous step.
gcloud compute network-endpoint-groups create $NEG_NAME \ --network-endpoint-type=private-service-connect \ --psc-target-service=$TARGET_SERVICE \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Where $PROJECT_ID can be the Cloud project that is already associated with your Apigee organization, or a Cloud project included in the
consumerAcceptlist
when the Apigee runtime instance was created.
Step 8d: Configure the regional internal load balancer
- Reserve an internal IPv4 address for the load balancer.
gcloud compute addresses create ADDRESS_NAME \ --ip-version=IPV4 --subnet=$SUBNET_NAME \ --region=$RUNTIME_LOCATION --project=$PROJECT_ID
Replace ADDRESS_NAME with a name for the IP address resource.
Run this command to view the reserved IP address:
gcloud compute addresses describe ADDRESS_NAME \ --format="get(address)" --region=$RUNTIME_LOCATION --project=$PROJECT_ID
- Create a backend service for the NEG.
gcloud compute backend-services create BACKEND_SERVICE_NAME \ --load-balancing-scheme=INTERNAL_MANAGED \ --protocol=HTTPS \ --region=$RUNTIME_REGION \ --project=$PROJECT_ID
- Add the backend service to the NEG.
gcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --network-endpoint-group=$NEG_NAME \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace the following:
- NEG_NAME: the name of the network endpoint group.
- BACKEND_SERVICE_NAME with the name of the backend service.
-
To create an HTTPS load balancer, you must have an SSL certificate resource to use in the HTTPS target proxy.
Use this command to create a self-managed SSL certificate resource. To create a self-managed SSL certificate, you need a local private key file and a local certificate file. If you need to create these files, see step 1 of using self-managed SSL certificates.
gcloud compute ssl-certificates create CERTIFICATE \ --certificate LB_CERT \ --private-key LB_PRIVATE_KEY --region=$RUNTIME_LOCATION --project=$PROJECT_ID
Replace the following:
- CERTIFICATE: a name for the certificate.
- LB_CERT: the path to the PEM-formatted certificate file for your self-managed certificate.
- LB_PRIVATE_KEY: the path to the PEM-formatted private key file for your self-managed certificate.
-
Create a URL map for the load balancer.
A URL map must reference a default backend service. Set the backend service you just created as the default.
gcloud compute url-maps create URL_MAP_NAME \ --default-service=DEFAULT_BACKEND_SERVICE_NAME \ --global --project=$PROJECT_ID
Replace the following:
- URL_MAP_NAME: a name for the URL map.
- DEFAULT_BACKEND_SERVICE_NAME: the name of the load balancer's default backend service. The default is used when no host rule matches the requested hostname.
-
Use the SSL certificate resource to create a target HTTPS proxy.
gcloud compute target-https-proxies create PROXY_NAME \ --url-map=URL_MAP_NAME \ --ssl-certificates=CERTIFICATE \ --region=$RUNTIME_LOCATION --project=$PROJECT_ID
Replace the following:
- PROXY_NAME: a name for the target HTTPS proxy.
- URL_MAP_NAME: the name of the URL map.
- CERTIFICATE: the name of the certificate resource.
- Create the forwarding rule.
gcloud compute forwarding-rules create FWD_RULE \ --load-balancing-scheme=INTERNAL_MANAGED \ --address=ADDRESS_NAME \ --target-https-proxy=PROXY_NAME \ --ports=443 \ --target-https-proxy-region=$RUNTIME_REGION \ --region=$RUNTIME_REGION --project=$PROJECT_ID
Replace the following:
- FWD_RULE: a name for the forwarding rule.
- ADDRESS_NAME: the IP address resource that you reserved to use for the forwarding rule.
- PROXY_NAME: the name of the target HTTPS proxy.
- Apigee provisioning is complete. Go to Deploy a sample proxy.
Replace BACKEND_SERVICE_NAME with the name of the backend service.
External routing (PSC)
This section describes how to configure external routing using Private Service Connect (PSC) to allow communication between Apigee and VPCs that you control. You must do this before you can send a request from an external client to your Apigee runtime instance.
Step 8b: Create a NEG and configure the load balancer
You can create a global or regional load balancer.
Global external LB
Configure a global
external HTTP(S) load balancer (load balancing
scheme set to EXTERNAL_MANAGED
).
Although the Private Service Connect NEG is regional, all other load balancing components in this configuration are global.
- Make sure you have set the environment variables in Define environment variables.
- Get the service attachment from the instance you created previously:
No data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
Data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
In the following sample output, the
serviceAttachment
value is shown in bold type:{ "instances": [ { "name": "us-west1", "location": "us-west1", "host": "10.82.192.2", "port": "443", "createdAt": "1645731488019", "lastModifiedAt": "1646504754219", "diskEncryptionKeyName": "projects/my-project/locations/us-west1/keyRings/us-west1/cryptoKeys/dek", "state": "ACTIVE", "peeringCidrRange": "SLASH_22", "runtimeVersion": "1-7-0-20220228-190814", "ipRange": "10.82.192.0/22,10.82.196.0/28", "consumerAcceptList": [ "875609189304" ], "serviceAttachment": "projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7" } ] }
Create a Private Service Connect NEG that points to the service attachment that you obtained from the instance response body in the previous step.
gcloud compute network-endpoint-groups create NEG_NAME \ --network-endpoint-type=private-service-connect \ --psc-target-service=TARGET_SERVICE \ --region=$RUNTIME_LOCATION \ --network=NETWORK_NAME \ --subnet=SUBNET_NAME \ --project=$PROJECT_ID
Replace the following:
- NEG_NAME: a name for the network endpoint group.
- TARGET_SERVICE: the service attachment that you want to
connect to. Use the service attachment value returned by the previous
command. For example:
projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7
- NETWORK_NAME: (Optional) Name of the network in which the NEG is created. If you omit
this parameter, the
default
project network is used. - SUBNET_NAME: Name of the subnet used for private connectivity to the producer. The subnet size can be small: the PSC NEG only needs one IP from the subnet. For Apigee, only one PSC NEG is needed per region. The subnet can be shared and used by VMs or other entities. If a subnet is not specified, network endpoints may belong to any subnetwork in the region where the network endpoint group is created.
- $PROJECT_ID The Cloud project that is already associated
with your Apigee organization, or a Cloud project included
in the
consumerAcceptlist
when the Apigee runtime instance was created. If you haven't already, create an environment variable to hold the project ID, because it is used in most of the following commands.
- Reserve a global external IPv4 address for the load balancer.
gcloud compute addresses create ADDRESS_NAME \ --ip-version=IPV4 --global --project=$PROJECT_ID
Replace ADDRESS_NAME with a name for the IP address resource.
Run this command to view the reserved IP address:
gcloud compute addresses describe ADDRESS_NAME \ --format="get(address)" --global --project=$PROJECT_ID
- Create a backend service for the NEG.
gcloud compute backend-services create BACKEND_SERVICE_NAME \ --load-balancing-scheme=EXTERNAL_MANAGED \ --protocol=HTTPS \ --global --project=$PROJECT_ID
- Add the backend service to the NEG.
gcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --network-endpoint-group=NEG_NAME \ --network-endpoint-group-region=REGION \ --global --project=$PROJECT_ID
Replace the following:
- BACKEND_SERVICE_NAME: the name of the backend service.
- NEG_NAME: the name of the network endpoint group.
- REGION: the region of the network endpoint group.
Create a URL map for the load balancer.
A URL map must reference a default backend service. Set the backend service you just created as the default.
gcloud compute url-maps create URL_MAP_NAME \ --default-service=DEFAULT_BACKEND_SERVICE_NAME \ --global --project=$PROJECT_ID
Replace the following:
- URL_MAP_NAME: a name for the URL map.
- DEFAULT_BACKEND_SERVICE_NAME: the name of the load balancer's default backend service. The default is used when no host rule matches the requested hostname.
Create the target HTTPS proxy.
To create an HTTPS load balancer, you must have an SSL certificate resource to use in the HTTPS target proxy. You can create an SSL certificate resource using either a Google-managed SSL certificate or a self-managed SSL certificate. Using Google-managed certificates is recommended because Google Cloud obtains, manages, and renews these certificates automatically.
To create a Google-managed certificate, you must have a domain.
Use this command to create a Google-managed SSL certificate resource:
gcloud compute ssl-certificates create CERTIFICATE \ --domains DOMAIN --project=$PROJECT_ID
Replace the following:
- CERTIFICATE: a name for the certificate.
- DOMAIN: the domain name of your load balancer.
Use this command to create a self-managed SSL certificate resource. To create a self-managed SSL certificate, you need a local private key file and a local certificate file. If you need to create these files, see step 1 of using self-managed SSL certificates.
gcloud compute ssl-certificates create CERTIFICATE \ --certificate LB_CERT \ --private-key LB_PRIVATE_KEY --project=$PROJECT_ID
Replace the following:
- CERTIFICATE: a name for the certificate.
- LB_CERT: the path to the PEM-formatted certificate file for your self-managed certificate.
- LB_PRIVATE_KEY: the path to the PEM-formatted private key file for your self-managed certificate.
Use the SSL certificate resource to create a target HTTPS proxy.
gcloud compute target-https-proxies create PROXY_NAME \ --url-map=URL_MAP_NAME \ --ssl-certificates=CERTIFICATE --project=$PROJECT_ID
Replace the following:
- PROXY_NAME: a name for the target HTTPS proxy.
- URL_MAP_NAME: the name of the URL map.
- CERTIFICATE: the name of the certificate resource.
- Create the forwarding rule.
gcloud compute forwarding-rules create FWD_RULE \ --load-balancing-scheme=EXTERNAL_MANAGED \ --network-tier=PREMIUM \ --address=ADDRESS_NAME \ --target-https-proxy=PROXY_NAME \ --ports=443 \ --global --project=$PROJECT_ID
Replace the following:
- FWD_RULE: a name for the forwarding rule.
- ADDRESS_NAME: the IP address resource that you reserved to use for the forwarding rule.
- PROXY_NAME: the name of the target HTTPS proxy.
Replace BACKEND_SERVICE_NAME with the name of the backend service.
Regional external LB
Configure a regional external HTTP(S) load balancer. See also External HTTP(S) load balancer overview.
- Be sure you have set the variables in Define environment variables.
- Create a proxy-only subnet:
gcloud compute networks subnets create SUBNET_NAME \ --purpose=REGIONAL_MANAGED_PROXY --role=ACTIVE \ --region=$RUNTIME_LOCATION --network=NETWORK_NAME \ --range=100.0.0.0/24 --project=$PROJECT_ID
Replace the following:
- SUBNET_NAME: the name of the subnet.
- (Optional) NETWORK_NAME: Name of the network in which the subnet is created. If you omit this parameter, the default project network is used.
- Get the service attachment from the instance you created previously:
No data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
Data residency
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
In the following sample output, the
serviceAttachment
value is shown in bold type:{ "instances": [ { "name": "us-west1", "location": "us-west1", "host": "10.82.192.2", "port": "443", "createdAt": "1645731488019", "lastModifiedAt": "1646504754219", "diskEncryptionKeyName": "projects/my-project/locations/us-west1/keyRings/us-west1/cryptoKeys/dek", "state": "ACTIVE", "peeringCidrRange": "SLASH_22", "runtimeVersion": "1-7-0-20220228-190814", "ipRange": "10.82.192.0/22,10.82.196.0/28", "consumerAcceptList": [ "875609189304" ], "serviceAttachment": "projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7" } ] }
- Create a network endpoint group.
gcloud compute network-endpoint-groups create NEG_NAME \ --network-endpoint-type=private-service-connect \ --psc-target-service=TARGET_SERVICE \ --region=$RUNTIME_LOCATION --project=$PROJECT_ID
Replace the following:
- NEG_NAME: the name of the network endpoint group.
- TARGET_SERVICE: the name of the service attachment that you want to connect to.
For example:
projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7
- Create a backend service for the NEG.
gcloud compute backend-services create BACKEND_SERVICE_NAME \ --load-balancing-scheme=EXTERNAL_MANAGED \ --protocol=HTTPS \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
- Add the backend service to the NEG.
gcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --network-endpoint-group=NEG_NAME \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace the following:
- BACKEND_SERVICE_NAME: the name of the backend service.
- NEG_NAME: the name of the network endpoint group.
Create a URL map for the load balancer.
A URL map must reference a default backend service. Set the backend service you just created as the default.
gcloud compute url-maps create URL_MAP_NAME \ --default-service=DEFAULT_BACKEND_SERVICE_NAME \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace the following:
- URL_MAP_NAME: a name for the URL map.
- DEFAULT_BACKEND_SERVICE_NAME: the name of the load balancer's default backend service. The default is used when no host rule matches the requested hostname.
Create the target HTTPS proxy.
To create an HTTPS load balancer, you must have an SSL certificate resource to use in the HTTPS target proxy.
Use this command to create a self-managed SSL certificate resource. To create a self-managed SSL certificate, you need a local private key file and a local certificate file. If you need to create these files, see step 1 of using self-managed SSL certificates.
gcloud compute ssl-certificates create CERTIFICATE \ --certificate LB_CERT \ --private-key LB_PRIVATE_KEY --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace the following:
- CERTIFICATE: a name for the certificate.
- LB_CERT: the path to the PEM-formatted certificate file for your self-managed certificate.
- LB_PRIVATE_KEY: the path to the PEM-formatted private key file for your self-managed certificate.
Use the SSL certificate resource to create a target HTTPS proxy.
gcloud compute target-https-proxies create PROXY_NAME \ --url-map=URL_MAP_NAME --region=$RUNTIME_LOCATION \ --ssl-certificates=CERTIFICATE --project=$PROJECT_ID
Replace the following:
- PROXY_NAME: a name for the target HTTPS proxy.
- URL_MAP_NAME: the name of the URL map.
- CERTIFICATE: the name of the certificate resource.
- Reserve a regional external address for the load balancer. Note that the network tier must
be set to
STANDARD
.gcloud compute addresses create ADDRESS_NAME \ --region=$RUNTIME_LOCATION --network-tier=STANDARD \ --project=$PROJECT_ID
Replace ADDRESS_NAME with a name for the IP address resource.
Run this command to view the reserved IP address:
gcloud compute addresses describe ADDRESS_NAME \ --format="get(address)" --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
- Create the forwarding rule.
gcloud compute forwarding-rules create FWD_RULE \ --load-balancing-scheme=EXTERNAL_MANAGED \ --network-tier=STANDARD \ --address=ADDRESS_NAME \ --target-https-proxy=PROXY_NAME \ --ports=443 --region=$RUNTIME_LOCATION \ --target-https-proxy-region=$RUNTIME_LOCATION --project=$PROJECT_ID
Replace the following:
- FWD_RULE: a name for the forwarding rule.
- ADDRESS_NAME: the IP address resource that you reserved to use for the forwarding rule.
- PROXY_NAME: the name of the target HTTPS proxy.
Replace BACKEND_SERVICE_NAME with the name of the backend service.
Apigee provisioning is complete. Go to Deploy a sample proxy.
Step 9: Deploy a sample proxy
- Download the sample proxy from GitHub. The target of the proxy is the httpbin.org service, which is a commonly used public request and response service.
- Upload the API proxy bundle to the runtime using the Apigee
apis
API:No data residency
curl -i -X POST -H "Authorization: Bearer $AUTH" \ -H "Content-Type:multipart/form-data" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/apis?name=httpbin&action=import" \ -F 'file=@PATH_TO_ZIP_FILE/httpbin_rev1_2020_02_02.zip'
Data residency
curl -i -X POST -H "Authorization: Bearer $AUTH" \ -H "Content-Type:multipart/form-data" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/apis?name=httpbin&action=import" \ -F 'file=@PATH_TO_ZIP_FILE/httpbin_rev1_2020_02_02.zip'
Where PATH_TO_ZIP_FILE is the path to the directory containing the downloaded ZIP file.
-
Deploy the API Proxy to the environment you created previously:
No data residency
curl -i -H "Authorization: Bearer $AUTH" -X POST \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/$ENVIRONMENT_NAME/apis/httpbin/revisions/1/deployments"
Data residency
curl -i -H "Authorization: Bearer $AUTH" -X POST \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/$ENVIRONMENT_NAME/apis/httpbin/revisions/1/deployments"
- Confirm the deployment completed successfully with this API call:
No data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/$ENVIRONMENT_NAME/apis/httpbin/revisions/1/deployments"
Data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/$ENVIRONMENT_NAME/apis/httpbin/revisions/1/deployments"
Call the API proxy:
Send a request to the API proxy from any network-enabled machine by executing the following command:
curl -i -H "Host: ENV_GROUP_HOSTNAME" \ "https://ENV_GROUP_HOSTNAME/httpbin/headers"
If needed, you can use this API to get the ENV_GROUP_HOSTNAME value:
No data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups"
Data residency
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups"
If you get an error like this:
CONNECT_CR_SRVR_HELLO:sslv3 alert handshake failure
, check to be sure the SSL certificate you created previously has been provisioned. Use this command to check the provisioning status. When the cert is provisioned, its status isACTIVE
.gcloud compute ssl-certificates describe CERTIFICATE \ --global \ --format="get(name,managed.status, managed.Status)"
Upon success, the sample API proxy returns a response similar to this:
{ "headers": { "Accept": "*/*", "Grpc-Trace-Bin": "AAD/8WC/I4AUSrMEch0E9yj+AYck1x9afwckAgA", "Host": "httpbin.org", "Traceparent": "00-fff160bf2380144ab304721d04f728fe-8724d71f5a7f0724-00", "User-Agent": "curl/7.77.0", "X-Amzn-Trace-Id": "Root=1-61d785ef-7613aa8a7fde7a910441fab9", "X-B3-Sampled": "0", "X-B3-Spanid": "8724d71f5a7f0724", "X-B3-Traceid": "fff160bf2380144ab304721d04f728fe", "X-Cloud-Trace-Context": "fff160bf2380144ab304721d04f728fe/9738144823944087332;o=0", "X-Envoy-Attempt-Count": "1" } }
For more information about deploying proxies, including additional troubleshooting information, see Deploying an API proxy.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2024-08-13 UTC.