Skip to content

Commit

Permalink
Merge pull request #159 from baskaran-md/apigee-disable-vpc-peering
Browse files Browse the repository at this point in the history
Add sample module for Apigee Provisioning without VPC Peering
  • Loading branch information
danistrebel authored Oct 31, 2024
2 parents 9f36915 + 5813898 commit f6f78a5
Show file tree
Hide file tree
Showing 13 changed files with 469 additions and 42 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ To deploy the sample, first create a copy of the example variables and edit acco
* [X with Shared VPC](samples/x-shared-vpc) for an Apigee X setup in a Shared VPC that is exposed via a global external L7 load balancer.
* [X with Multi Region](samples/x-multi-region) for an Apigee X setup in a Shared VPC exposed in multiple GCP Regions via a global L7 load balancer. Note that the sample uses an EVAL Apigee X Organization and hence a single Apigee X Instance only. In case you have a PROD Apigee X Organization then you will be able to easily extend the sample accordingly.
* [X with IaC Automation Pipeline](samples/x-iac-pipeline) for an IaC Automation Pipeline Apigee X setup in a Shared VPC exposed in multiple GCP Regions via a global L7 load balancer. Note that the sample uses an EVAL Apigee X Organization and hence a single Apigee X Instance only. In case you have a PROD Apigee X Organization then you will be able to easily extend the sample accordingly.
* [X with Non VPC Peering with external L7 LB and northbound PSC](samples/x-non-vpc-peering) for a basic Apigee X setup without VPC Peering requirements and expose northbound via global external L7 load balancer and a Private Service Connect (PSC) Network Endpoint Group (NEG) to connect to an Apigee instance's service attachment.

## Reusable Modules

Expand Down
5 changes: 3 additions & 2 deletions modules/apigee-x-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
|------|-------------|------|---------|:--------:|
| <a name="input_apigee_envgroups"></a> [apigee\_envgroups](#input\_apigee\_envgroups) | Apigee Environment Groups. | <pre>map(object({<br> hostnames = list(string)<br> }))</pre> | `{}` | no |
| <a name="input_apigee_environments"></a> [apigee\_environments](#input\_apigee\_environments) | Apigee Environments. | <pre>map(object({<br> display_name = optional(string)<br> description = optional(string, "Terraform-managed")<br> node_config = optional(object({<br> min_node_count = optional(number)<br> max_node_count = optional(number)<br> }))<br> iam = optional(map(list(string)))<br> type = optional(string)<br> envgroups = list(string)<br> }))</pre> | `null` | no |
| <a name="input_apigee_instances"></a> [apigee\_instances](#input\_apigee\_instances) | Apigee Instances (only one instance for EVAL). | <pre>map(object({<br> region = string<br> ip_range = string<br> environments = list(string)<br> keyring_create = optional(bool, true)<br> keyring_name = optional(string, null)<br> keyring_location = optional(string, null)<br> key_name = optional(string, "inst-disk")<br> key_rotation_period = optional(string, "2592000s")<br> key_labels = optional(map(string), null)<br> consumer_accept_list = optional(list(string), null)<br> }))</pre> | `{}` | no |
| <a name="input_apigee_instances"></a> [apigee\_instances](#input\_apigee\_instances) | Apigee Instances (only one instance for EVAL). | <pre>map(object({<br> region = string<br> ip_range = optional(string, null)<br> environments = list(string)<br> keyring_create = optional(bool, true)<br> keyring_name = optional(string, null)<br> keyring_location = optional(string, null)<br> key_name = optional(string, "inst-disk")<br> key_rotation_period = optional(string, "2592000s")<br> key_labels = optional(map(string), null)<br> consumer_accept_list = optional(list(string), null)<br> }))</pre> | `{}` | no |
| <a name="input_ax_region"></a> [ax\_region](#input\_ax\_region) | GCP region for storing Apigee analytics data (see https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli). | `string` | n/a | yes |
| <a name="input_billing_type"></a> [billing\_type](#input\_billing\_type) | Billing type of the Apigee organization. | `string` | `null` | no |
| <a name="input_network"></a> [network](#input\_network) | Network (self-link) to peer with the Apigee tennant project. | `string` | n/a | yes |
| <a name="input_disable_vpc_peering"></a> [disable\_vpc\_peering](#input\_disable\_vpc\_peering) | Flag that specifies whether the VPC Peering through Private Service Access (Service Networking) should be disabled between the consumer network and Apigee. | `bool` | `false` | no |
| <a name="input_network"></a> [network](#input\_network) | Network (self-link) to peer with the Apigee tennant project. This is required only for VPC peering based setup through Private Service Access. | `string` | `null` | no |
| <a name="input_org_description"></a> [org\_description](#input\_org\_description) | Apigee org description | `string` | `"Apigee org created in TF"` | no |
| <a name="input_org_display_name"></a> [org\_display\_name](#input\_org\_display\_name) | Apigee org display name | `string` | `null` | no |
| <a name="input_org_key_rotation_period"></a> [org\_key\_rotation\_period](#input\_org\_key\_rotation\_period) | Rotaton period for the organization DB encryption key | `string` | `"2592000s"` | no |
Expand Down
1 change: 1 addition & 0 deletions modules/apigee-x-core/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ module "apigee" {
billing_type = var.billing_type
database_encryption_key = module.kms-org-db.key_ids["org-db"]
analytics_region = var.ax_region
disable_vpc_peering = var.disable_vpc_peering
}
envgroups = local.envgroups
environments = var.apigee_environments
Expand Down
11 changes: 9 additions & 2 deletions modules/apigee-x-core/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@ variable "ax_region" {
type = string
}

variable "disable_vpc_peering" {
description = "Flag that specifies whether the VPC Peering through Private Service Access (Service Networking) should be disabled between the consumer network and Apigee."
type = bool
default = false
}

variable "network" {
description = "Network (self-link) to peer with the Apigee tennant project."
description = "Network (self-link) to peer with the Apigee tennant project. This is required only for VPC peering based setup through Private Service Access."
type = string
default = null
}

variable "billing_type" {
Expand Down Expand Up @@ -75,7 +82,7 @@ variable "apigee_instances" {
description = "Apigee Instances (only one instance for EVAL)."
type = map(object({
region = string
ip_range = string
ip_range = optional(string, null)
environments = list(string)
keyring_create = optional(bool, true)
keyring_name = optional(string, null)
Expand Down
16 changes: 8 additions & 8 deletions modules/mig-l7xlb/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ resource "google_compute_health_check" "mig_lb_hc" {
}

resource "google_compute_backend_service" "mig_backend" {
project = var.project_id
name = "${var.name}-backend"
port_name = "https"
protocol = "HTTPS"
timeout_sec = var.backend_timeout
health_checks = [google_compute_health_check.mig_lb_hc.id]
security_policy = var.security_policy
edge_security_policy = var.edge_security_policy
project = var.project_id
name = "${var.name}-backend"
port_name = "https"
protocol = "HTTPS"
timeout_sec = var.backend_timeout
health_checks = [google_compute_health_check.mig_lb_hc.id]
security_policy = var.security_policy
edge_security_policy = var.edge_security_policy
dynamic "backend" {
for_each = var.backend_migs
content {
Expand Down
24 changes: 12 additions & 12 deletions samples/x-nb-psc-mig-l7xlb/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ locals {
subnet_region_name = { for subnet in var.exposure_subnets :
subnet.region => "${subnet.region}/${subnet.name}"
}
psc_subnets = { for psc in var.psc_subnets :
psc.name => psc
psc_subnets = { for psc in var.psc_subnets :
psc.name => psc
}
region_psc_map = {for psc in var.psc_subnets :
psc.region => psc.name
region_psc_map = { for psc in var.psc_subnets :
psc.region => psc.name
}

}
Expand All @@ -40,7 +40,7 @@ module "vpc" {
source = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/net-vpc?ref=v28.0.0"
project_id = module.project.project_id
name = var.vpc_name
subnets = [
subnets = [
for subnet in concat(var.exposure_subnets, var.psc_subnets) :
{
"name" = subnet.name
Expand All @@ -51,9 +51,9 @@ module "vpc" {
]
psa_config = {
ranges = {
apigee-range = var.peering_range
apigee-range = var.peering_range
apigee-support-range1 = var.support_range1

#add_more_support_ranges_per_instance_region
}
}
Expand All @@ -72,7 +72,7 @@ module "apigee-x-core" {


resource "google_compute_address" "psc_endpoint_address" {
for_each = local.psc_subnets
for_each = local.psc_subnets
name = "psc-ip-${each.value.region}"
project = module.project.project_id
address_type = "INTERNAL"
Expand All @@ -81,7 +81,7 @@ resource "google_compute_address" "psc_endpoint_address" {
}
resource "google_compute_forwarding_rule" "psc_ilb_consumer" {
for_each = local.psc_subnets
for_each = local.psc_subnets
name = "psc-ea-${each.value.region}"
project = module.project.project_id
region = each.value.region
Expand All @@ -97,9 +97,9 @@ resource "google_compute_forwarding_rule" "psc_ilb_consumer" {

data "google_compute_address" "int_psc_ips" {
for_each = google_compute_address.psc_endpoint_address
name = each.value.name
region = each.value.region
project = module.project.project_id
name = each.value.name
region = each.value.region
project = module.project.project_id
}

module "apigee-x-bridge-mig" {
Expand Down
32 changes: 16 additions & 16 deletions samples/x-nb-psc-mig-l7xlb/x-demo.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
* limitations under the License.
*/

ax_region = "europe-west1"
billing_account = ""
billing_type = "EVAL"
project_parent = "organizations/406283053755"
vpc_name = "apigeexvpc"
peering_range = "10.1.0.0/16"
support_range1 = "10.2.0.0/28"

ax_region = "europe-west1"
billing_account = ""
billing_type = "EVAL"
project_parent = "organizations/406283053755"

vpc_name = "apigeexvpc"
peering_range = "10.1.0.0/16"
support_range1 = "10.2.0.0/28"

lb_name = "apigeexlb"
ssl_crt_domains = ["xyz.com"]
Expand All @@ -37,19 +37,19 @@ apigee_envgroups = {

apigee_instances = {
"euw1-instance" = {
region = "europe-west1"
ip_range = "10.1.4.0/22"
environments = ["test"]
region = "europe-west1"
ip_range = "10.1.4.0/22"
environments = ["test"]
},

}

apigee_environments = {
"test" = {
display_name = "TEST"
description = ""
display_name = "TEST"
description = ""
iam = null
envgroups = ["testgroup"]
envgroups = ["testgroup"]

}
# Add more environments if needed
Expand All @@ -68,7 +68,7 @@ exposure_subnets = [
]

psc_subnets = [
{
{
name = "psc-subnet-1"
ip_cidr_range = "10.100.255.240/29"
region = "europe-west1"
Expand Down
95 changes: 95 additions & 0 deletions samples/x-non-vpc-peering/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Basic Apigee X Setup without VPC Peering

A minimal Apigee X setup without using VPC Peering. It also configures the northbound routing through
L7 External LoadBalancer and Private Service Connect's - Network Endpoint Group (PSC NEG).

Refer to below docs for more information.

- [Apigee Networking - Non-VPC Peering Option](https://cloud.google.com/apigee/docs/api-platform/get-started/networking-options#non-vpc-peering-architecture-overview)
- [Release Notes](https://cloud.google.com/apigee/docs/release-notes#August_26_2024)

<!-- BEGIN_SAMPLES_DEFAULT_SETUP_INSTRUCTIONS -->
## Setup Instructions

Set the project ID where you want your Apigee Organization to be deployed to:

```sh
PROJECT_ID=my-project-id
```

```sh
cd samples/... # Sample from above
cp ./x-demo.tfvars ./my-config.tfvars
```

Decide on a [backend](https://www.terraform.io/language/settings/backends) and create the necessary config. To use a backend on Google Cloud Storage (GCS) use:

```sh
gsutil mb "gs://$PROJECT_ID-tf"

cat <<EOF >terraform.tf
terraform {
backend "gcs" {
bucket = "$PROJECT_ID-tf"
prefix = "terraform/state"
}
}
EOF
```

Validate your config:

```sh
terraform init
terraform plan --var-file=./my-config.tfvars -var "project_id=$PROJECT_ID"
```

and provision everything (takes roughly 25min):

```sh
terraform apply --var-file=./my-config.tfvars -var "project_id=$PROJECT_ID"
```
<!-- END_SAMPLES_DEFAULT_SETUP_INSTRUCTIONS -->

<!-- BEGIN_TF_DOCS -->
## Providers

| Name | Version |
|------|---------|
| <a name="provider_google"></a> [google](#provider\_google) | n/a |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_apigee-x-core"></a> [apigee-x-core](#module\_apigee-x-core) | ../../modules/apigee-x-core | n/a |
| <a name="module_nb-psc-l7xlb"></a> [nb-psc-l7xlb](#module\_nb-psc-l7xlb) | ../../modules/nb-psc-l7xlb | n/a |
| <a name="module_nip-development-hostname"></a> [nip-development-hostname](#module\_nip-development-hostname) | ../../modules/nip-development-hostname | n/a |
| <a name="module_project"></a> [project](#module\_project) | github.com/terraform-google-modules/cloud-foundation-fabric//modules/project | v28.0.0 |
| <a name="module_psc-ingress-vpc"></a> [psc-ingress-vpc](#module\_psc-ingress-vpc) | github.com/terraform-google-modules/cloud-foundation-fabric//modules/net-vpc | v28.0.0 |

## Resources

| Name | Type |
|------|------|
| [google_compute_region_network_endpoint_group.psc_neg](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_region_network_endpoint_group) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_apigee_envgroups"></a> [apigee\_envgroups](#input\_apigee\_envgroups) | Apigee Environment Groups. | <pre>map(object({<br> hostnames = list(string)<br> }))</pre> | `null` | no |
| <a name="input_apigee_environments"></a> [apigee\_environments](#input\_apigee\_environments) | Apigee Environments. | <pre>map(object({<br> display_name = optional(string)<br> description = optional(string)<br> node_config = optional(object({<br> min_node_count = optional(number)<br> max_node_count = optional(number)<br> }))<br> iam = optional(map(list(string)))<br> envgroups = list(string)<br> type = optional(string)<br> }))</pre> | `null` | no |
| <a name="input_apigee_instances"></a> [apigee\_instances](#input\_apigee\_instances) | Apigee Instances (only one instance for EVAL orgs). | <pre>map(object({<br> region = string<br> environments = list(string)<br> }))</pre> | `null` | no |
| <a name="input_ax_region"></a> [ax\_region](#input\_ax\_region) | GCP region for storing Apigee analytics data (see https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli). | `string` | n/a | yes |
| <a name="input_billing_account"></a> [billing\_account](#input\_billing\_account) | Billing account id. | `string` | `null` | no |
| <a name="input_project_create"></a> [project\_create](#input\_project\_create) | Create project. When set to false, uses a data source to reference existing project. | `bool` | `false` | no |
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | Project id (also used for the Apigee Organization). | `string` | n/a | yes |
| <a name="input_project_parent"></a> [project\_parent](#input\_project\_parent) | Parent folder or organization in 'folders/folder\_id' or 'organizations/org\_id' format. | `string` | `null` | no |
| <a name="input_psc_ingress_network"></a> [psc\_ingress\_network](#input\_psc\_ingress\_network) | PSC ingress VPC name. | `string` | n/a | yes |
| <a name="input_psc_ingress_subnets"></a> [psc\_ingress\_subnets](#input\_psc\_ingress\_subnets) | Subnets for exposing Apigee services via PSC | <pre>list(object({<br> name = string<br> ip_cidr_range = string<br> region = string<br> secondary_ip_range = map(string)<br> }))</pre> | `[]` | no |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
90 changes: 90 additions & 0 deletions samples/x-non-vpc-peering/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module "project" {
source = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/project?ref=v28.0.0"
name = var.project_id
parent = var.project_parent
billing_account = var.billing_account
project_create = var.project_create
services = [
"apigee.googleapis.com",
"cloudkms.googleapis.com",
"compute.googleapis.com"
]
}

module "apigee-x-core" {
source = "../../modules/apigee-x-core"
project_id = module.project.project_id
apigee_environments = var.apigee_environments
ax_region = var.ax_region
apigee_envgroups = {
for name, env_group in var.apigee_envgroups : name => {
hostnames = concat(env_group.hostnames, ["${name}.${module.nip-development-hostname.hostname}"])
}
}
apigee_instances = var.apigee_instances
disable_vpc_peering = true
}

/**
* Below are the modules required for creating XLB + PSC NEG.
*/

locals {
psc_subnet_region_name = { for subnet in var.psc_ingress_subnets :
subnet.region => "${subnet.region}/${subnet.name}"
}
}

module "nip-development-hostname" {
source = "../../modules/nip-development-hostname"
project_id = module.project.project_id
address_name = "apigee-external"
subdomain_prefixes = [for name, _ in var.apigee_envgroups : name]
}

module "psc-ingress-vpc" {
source = "github.com/terraform-google-modules/cloud-foundation-fabric//modules/net-vpc?ref=v28.0.0"
project_id = module.project.project_id
name = var.psc_ingress_network
auto_create_subnetworks = false
subnets = var.psc_ingress_subnets
}

resource "google_compute_region_network_endpoint_group" "psc_neg" {
project = var.project_id
for_each = var.apigee_instances
name = "psc-neg-${each.value.region}"
region = each.value.region
network = module.psc-ingress-vpc.network.id
subnetwork = module.psc-ingress-vpc.subnet_self_links[local.psc_subnet_region_name[each.value.region]]
network_endpoint_type = "PRIVATE_SERVICE_CONNECT"
psc_target_service = module.apigee-x-core.instance_service_attachments[each.value.region]
lifecycle {
create_before_destroy = true
}
}

module "nb-psc-l7xlb" {
source = "../../modules/nb-psc-l7xlb"
project_id = module.project.project_id
name = "apigee-xlb-psc"
ssl_certificate = [module.nip-development-hostname.ssl_certificate]
external_ip = module.nip-development-hostname.ip_address
psc_negs = [for _, psc_neg in google_compute_region_network_endpoint_group.psc_neg : psc_neg.id]
}
Loading

0 comments on commit f6f78a5

Please sign in to comment.