Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Apigee X Organization Provisioning with Google Terraform Modules

Edit (December 2022): Please note that the cloud foundation fabric modules introduced a new consolidated Apigee module. The code in this post will still work since the versions are pinned but you might want to check out the new Apigee module with additional capabilities. 

There are a number of ways to provision an Apigee X (trial) organization. The official documentation describes how to provision an Apigee instance through an interactive wizard, by following a number of CLI commands or by using the provisioning script from the Apigee devrel community repository.

In this short post we introduce a terraform-based option that makes use of the google terraform provider as well as new Apigee cloud foundation terraform modules.

Note: The dependencies to the cloud foundation fabric resources are pinned to a specific release tag. Please check the upstream repository for the latest tags.

 

Apigee X - Evaluation Org Provisioning

To prepare your GCP project for running the terraform script, you’ll have to enable the following Google APIs:

  • apigee.googleapis.com
  • compute.googleapis.com
  • servicenetworking.googleapis.com

You can do this by running the following command:

 

 

PROJECT_ID=my-project-id

gcloud services enable compute.googleapis.com apigee.googleapis.com servicenetworking.googleapis.com --project $PROJECT_ID

 

 

Once the APIs are enabled, we can start preparing our script.

 

The core of the script is represented by the invocation of the two Apigee terraform modules as well as the terraform module to prepare your service networking that is used to peer your tenant project with your own VPC. To do this we can create our own main.tf file and add the following content:

 

 

// main.tf

module "vpc" {
  source     = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/net-vpc?ref=v14.0.0"
  project_id = var.project_id
  name       = var.network
  psa_ranges = {
   apigee-range = var.peering_range
  }
}

module "apigee" {
  source              = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/apigee-organization?ref=v14.0.0"
  project_id          = var.project_id
  analytics_region    = var.analytics_region
  runtime_type        = "CLOUD"
  authorized_network  = module.vpc.network.id
  apigee_environments = var.apigee_environments
  apigee_envgroups    = var.apigee_envgroups
}

module "apigee-x-instance" {
  source              = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/apigee-x-instance?ref=v14.0.0"
  apigee_org_id       = module.apigee.org_id
  name                = "my-eval-instance"
  region              = var.runtime_region
  ip_range            = var.instance_cidr
  apigee_environments = var.apigee_environments
}

 

 

For reusability, we decided to make use of a few terraform variables which we need to declare in a separate variables.tf file:

 

 

// variables.tf

variable "analytics_region" {
  description = "Analytics Region for the Apigee Organization (immutable). See https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli."
  type = string
}

variable "apigee_envgroups" {
  description = "Apigee Environment Groups."
  type = map(object({
    environments = list(string)
    hostnames    = list(string)
  }))
  default = {}
}

variable "apigee_environments" {
  description = "Apigee Environment Names."
  type        = list(string)
  default     = []
}

variable "network" {
  description = "Name of the VPC network to be created."
  type        = string
}

variable "peering_range" {
  description = "RFC CIDR range for service network peering."
  type        = string
}

variable "project_id" {
  description = "Project ID to host this Apigee organization (will also become the Apigee Org name)."
  type        = string
}

variable "runtime_region" {
  description = "Apigee Runtime Instance Region."
  type        = string
}

variable "instance_cidr" {
  description = "CIDR Block to be used by the Apigee instance."
  type        = string
}

 

 

With these we can declare all our configuration values in a my-x-eval.tfvars file:

 

 

// my-x-eval.tfvars

peering_range = "10.0.0.0/21"
instance_cidr = "10.0.0.0/22
network = "apigee-vpc"
analytics_region = "europe-west1"
runtime_region = "europe-west6"
apigee_environments = ["eval1", "eval2"]
apigee_envgroups = {
  eval = {
    environments = ["eval1", "eval2"]
    hostnames    = ["eval.api.example.com"]
  }
}

 

 

Within the folder where you created the three files above you can then initialize your terraform module and inspect the generated plan:

 

 

terraform init
terraform plan --var-file="my-x-eval.tfvars" -var=project_id=$PROJECT_ID

 

 

This should display the full plan and the total resources that should be created:

...
Plan
: 12 to add, 0 to change, 0 to destroy.

If you are happy with the plan, you can provision your org like this:

 

 

terraform apply --var-file="my-x-eval.tfvars" -var=project_id=$PROJECT_ID

 

 

Please note that the instance creation itself can take anywhere between 15-25 min plus the time to provision the environments for the first time.
Once the deployment is completed you should see a message saying:

Apply complete! Resources: 12 added, 0 changed, 0 destroyed.

 

To find out the private endpoint for your Apigee instance you can either check the Admin > Instances page in the Apigee UI. Or run the following command:

 

 

TOKEN=$(gcloud auth print-access-token) 
curl -H "Authorization: Bearer $TOKEN" \ 
  https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/instances

 

 

 

Apigee X - Paid Org Provisioning

The modules described above can also be used to provision paid Apigee X organizations. To create a paid organization you will have to adjust the peering CIDR mask to be of size 16 or 20 and add your KMS keys as described in the module documentation.

 

(Bonus) Apigee hybrid - Control Plane Provisioning

The apigee-organization terraform module can also be used to create an Apigee hybrid organization and its associated environments. Note that the terraform module only covers the installation of the control plane. For installing the runtime we suggest you follow the official runtime installation instructions. For this we enable the required google services:

 

 

PROJECT_ID=my-project-id
gcloud services enable apigee.googleapis.com --project $PROJECT_ID

 

 

create the following resources similar to the previous Apigee X example:

 

 

// main.tf

module "apigee" {
  source              = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/apigee-organization?ref=v14.0.0"
  project_id          = var.project_id
  analytics_region    = var.analytics_region
  runtime_type        = "HYBRID"
  apigee_environments = var.apigee_environments
  apigee_envgroups    = var.apigee_envgroups
}
// variables.tf

variable "analytics_region" {
  description = "Analytics Region for the Apigee Organization (immutable). See https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli."
  type = string
}

variable "apigee_envgroups" {
  description = "Apigee Environment Groups."
  type = map(object({
    environments = list(string)
    hostnames    = list(string)
  }))
  default = {}
}

variable "apigee_environments" {
  description = "Apigee Environment Names."
  type        = list(string)
  default     = []
}

variable "project_id" {
  description = "Project ID to host this Apigee organization (will also become the Apigee Org name)."
  type        = string
}
​
// my-hybrid-eval.tfvars

analytics_region = "us-central1"
apigee_environments = ["eval1", "eval2"]
apigee_envgroups = {
  eval = {
    environments = ["eval1", "eval2"]
    hostnames    = ["eval.api.example.com"]
  }
}

 

 

 

Similarly to the Apigee X example, we want to initialize, plan, and ultimately apply our terraform script.

 

 

terraform init
terraform plan --var-file="my-hybrid-eval.tfvars" -var=project_id=$PROJECT_ID
terraform apply --var-file="my-hybrid-eval.tfvars" -var=project_id=$PROJECT_ID

 

 

 

We can then create another terraform script to create the Kubernetes cluster in the desired provider and install the runtime accordingly. 

14 12 11.7K
12 REPLIES 12