This document describes how to install and configure Apigee from the command line without VPC peering. These steps apply to both Subscription and Pay-as-you-go pricing models for paid organizations with or without data residency enabled.
See also Provisioning options.The non-VPC peering installation option described in this document has some limitations:
For a complete list of features and networking approaches that are and are not supported for non-VPC peering, see How to choose a networking option.
The provisioning steps are as follows:
gcloud
and define environment variables. The Google Cloud CLI manages authentication, local configuration, developer workflow,and interactions with the Google Cloud APIs. Set up gcloud
and define environment variables for use in later steps:
gcloud
. 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:
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. 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.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:
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. 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.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.echo $AUTHecho $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
echo $AUTHecho $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
Apigee requires you to enable several Google Cloud APIs. Enable them by executing the following services enable
command:
gcloud services enable apigee.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.
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
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 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 configurations: Choose from the supported multi-regional locations (such as us
or europe
) 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, use nam4
.
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_NAMERUNTIMEDB_KEY_NAME=YOUR_DB_KEY_NAME
echo $RUNTIMEDBKEY_LOCATIONecho $RUNTIMEDB_KEY_RING_NAME
echo $RUNTIMEDB_KEY_NAME
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.
Perform the following steps to create a control plane encryption key ring and key.
CONTROL_PLANE_LOCATION=YOUR_CONTROL_PLANE_LOCATIONCONSUMER_DATA_REGION=YOUR_CONSUMER_DATA_REGION
Where:
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_NAMECONTROL_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:
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
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
CONTROL_PLANE_KEY_ID=YOUR_CONTROL_PLANE_KEY_ID
CONSUMER_DATA_KEY_ID=YOUR_CONSUMER_DATA_KEY_ID
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:
UpdatedIAMpolicyforkey[runtime].bindings:-members:-serviceAccount:service-1234567890@gcp-sa-apigee.iam.gserviceaccount.com role:roles/cloudkms.cryptoKeyEncrypterDecrypteretag:BwWqgEuCuwk=version:1
If you get an error like the following:
INVALID_ARGUMENT:Roleroles/cloudkms.cryptokms.cryptoKeyEncrypterDecrypterisnotsupportedforthisresource.
Be sure that you used the project number and not the project name in the service account email address.
See also: CMEK troubleshooting.
Create the organization by sending the following request to the Apigee organizations API:
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"'", "disableVpcPeering":"true", "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 to CLOUD
.billingType
: Specifies the billing type of the organization created.disableVpcPeering
: Set to true
if you do not want to use VPC peering. Default: false
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
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"'", "disableVpcPeering":"true", "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 to CLOUD
.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.disableVpcPeering
: Set to true
if you do not want to use VPC peering. Default: false
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", ... }'
GET
request to the Apigee List organizations API, as the following example shows: curl -H "Authorization: Bearer $AUTH" "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID"
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" } }
On success, the response object will indicate "state": "ACTIVE"
, and you can go on to the next step.
If Apigee returns an HTTP error response, then see Creating an Apigee organization.
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:
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID"
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.
INSTANCE_NAME=YOUR_INSTANCE_NAMERUNTIME_LOCATION=YOUR_RUNTIME_LOCATION
DISK_KEY_RING_NAME=YOUR_DISK_KEY_RING_NAME
DISK_KEY_NAME=YOUR_DISK_KEY_NAME
Where:
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. us-west1
.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.
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.
POST
request to the Apigee Instances API: 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"'"] }'
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.
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME"
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME"
To create an environment and attach it to the runtime on the command line:
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
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
, or COMPREHENSIVE
. 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
For a new subscription environment, use the following command:
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"'" }'
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.
For a new Pay-as-you-go environment, use the following command:
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"'" }'
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.
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments"
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" ]
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"'" }'
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:
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances/$INSTANCE_NAME/attachments"
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" } ] }
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"'"] }'
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"'"] }'
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME"
curl -i -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME"
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"'" }'
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"'" }'
curl -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME/attachments"
curl -H "Authorization: Bearer $AUTH" \ "https://$CONTROL_PLANE_LOCATION-apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups/$ENV_GROUP_NAME/attachments"
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 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.
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:
Select the tab below for your configuration choice and follow the steps:
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
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", "createdAt": "1645731488019", "lastModifiedAt": "1646504754219", "diskEncryptionKeyName": "projects/my-project/locations/us-west1/keyRings/us-west1/cryptoKeys/dek", "state": "ACTIVE", "runtimeVersion": "1-7-0-20220228-190814", "consumerAcceptList": [ "my-project" ], "serviceAttachment": "projects/bfac74a67a320c43a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw1" } ] }
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:
projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7
default
project network is used.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
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
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", "createdAt": "1645731488019", "lastModifiedAt": "1646504754219", "diskEncryptionKeyName": "projects/my-project/locations/us-west1/keyRings/us-west1/cryptoKeys/dek", "state": "ACTIVE", "runtimeVersion": "1-7-0-20220228-190814", "consumerAcceptList": [ "my-project" ], "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.
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
gcloud compute backend-services create BACKEND_SERVICE_NAME \ --load-balancing-scheme=INTERNAL_MANAGED \ --protocol=HTTPS \ --region=$RUNTIME_REGION \ --project=$PROJECT_ID
Replace BACKEND_SERVICE_NAME with the name of the backend service.
gcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --network-endpoint-group=$NEG_NAME \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace the following:
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:
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_REGION \ --project=$PROJECT_ID
Replace the following:
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:
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 \ --network=$NETWORK_NAME \ --subnet=$SUBNET_NAME
Replace the following:
default
project network is used.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.
You can create a global or regional load balancer.
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.
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
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:
projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7
default
project network is used.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. 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
gcloud compute backend-services create BACKEND_SERVICE_NAME \ --load-balancing-scheme=EXTERNAL_MANAGED \ --protocol=HTTPS \ --global --project=$PROJECT_ID
Replace BACKEND_SERVICE_NAME with the name of the backend service.
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:
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:
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:
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:
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:
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:
Configure a regional external HTTP(S) load balancer. See also External HTTP(S) load balancer overview.
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:
curl -i -X GET -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances"
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"}]}
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:
projects/bfac7497a40c32a12p-tp/regions/us-west1/serviceAttachments/apigee-us-west1-crw7
gcloud compute backend-services create BACKEND_SERVICE_NAME \ --load-balancing-scheme=EXTERNAL_MANAGED \ --protocol=HTTPS \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace BACKEND_SERVICE_NAME with the name of the backend service.
gcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --network-endpoint-group=NEG_NAME \ --region=$RUNTIME_LOCATION \ --project=$PROJECT_ID
Replace the following:
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:
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:
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:
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
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:
Apigee provisioning is complete. Go to Deploy a sample proxy.
apis
API: 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'
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.
curl -i -H "Authorization: Bearer $AUTH" -X POST \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/$ENVIRONMENT_NAME/apis/httpbin/revisions/1/deployments"
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"
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/$ENVIRONMENT_NAME/apis/httpbin/revisions/1/deployments"
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:
curl -i -H "Authorization: Bearer $AUTH" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/envgroups"
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 is ACTIVE
.
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 2025-04-24 UTC.