This sample provides a envoy-based managed instance group behind an external load balancer that can terminate mutual TLS (mTLS) to authenticate API clients.
This example assumes that you have TLS credentials for the server as well as the clients available and set their path in the .tfvars file.
To try it out you can create a set of self signed certs:
mkdir -p ./certs && cd ./certs
openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout server-ca.key -x509 -days 3650 -outform PEM -out server-ca.crt -subj "/CN=Test Server CA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=test.api.example.com"
openssl x509 -req -in server.csr -CA server-ca.crt -CAkey server-ca.key -set_serial 100 -days 365 -outform PEM -out server.crt
openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout client-ca.key -x509 -days 3650 -outform PEM -out client-ca.crt -subj "/CN=Test Client CA"
openssl genrsa -out example-client.key 2048
openssl req -new -key example-client.key -out example-client.csr -subj "/CN=Test Client"
openssl x509 -req -in example-client.csr -CA client-ca.crt -CAkey client-ca.key -set_serial 101 -days 365 -outform PEM -out example-client.crt
cd ..
And reference them in your tf.vars
ca_cert_path = "./certs/client-ca.crt"
tls_cert_path = "./certs/server.crt"
tls_key_path = "./certs/server.key"
Ensure that your tf variables file (.apigee_envgroups.test.hostnames[]) contains the same hostname as you used in the CN of your certificate.
Set the project ID where you want your Apigee Organization to be deployed to:
PROJECT_ID=my-project-id
cd samples/... # Sample from above
cp ./x-demo.tfvars ./my-config.tfvars
Decide on a backend and create the necessary config. To use a backend on Google Cloud Storage (GCS) use:
gsutil mb "gs://$PROJECT_ID-tf"
cat <<EOF >terraform.tf
terraform {
backend "gcs" {
bucket = "$PROJECT_ID-tf"
prefix = "terraform/state"
}
}
EOF
Validate your config:
terraform init
terraform plan --var-file=./my-config.tfvars -var "project_id=$PROJECT_ID"
and provision everything (takes roughly 25min):
terraform apply --var-file=./my-config.tfvars -var "project_id=$PROJECT_ID"
If you used a hostname for which you don't have a DNS entry you can use:
INGRESS_IP=$(gcloud compute addresses describe apigee-external --global --format="get(address)")
curl https://test.api.example.com/my-proxy --resolve test.api.example.com:443:$INGRESS_IP --cert ./certs/example-client.crt --key ./certs/example-client.key --cacert ./certs/server-ca.crt -v
Otherwise use:
curl https://my-domain.com/my-proxy --cert ./certs/example-client.crt --key ./certs/example-client.key --cacert ./certs/server-ca.crt -v
Name | Version |
---|---|
n/a |
Name | Source | Version |
---|---|---|
apigee-x-core | ../../modules/apigee-x-core | n/a |
apigee-x-mtls-mig | ../../modules/apigee-x-mtls-mig | n/a |
mig-l4xlb | ../../modules/l4xlb | n/a |
nip-development-hostname | ../../modules/nip-development-hostname | n/a |
project | github.com/terraform-google-modules/cloud-foundation-fabric//modules/project | v28.0.0 |
vpc | github.com/terraform-google-modules/cloud-foundation-fabric//modules/net-vpc | v28.0.0 |
Name | Type |
---|---|
google_compute_firewall.allow_xlb_hc | resource |
Name | Description | Type | Default | Required |
---|---|---|---|---|
apigee_envgroups | Apigee Environment Groups. | map(object({ |
null |
no |
apigee_environments | Apigee Environments. | map(object({ |
null |
no |
apigee_instances | Apigee Instances (only one instance for EVAL orgs). | map(object({ |
null |
no |
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 |
billing_account | Billing account id. | string |
null |
no |
ca_cert_path | Path to User CA Cert File (pem). | string |
n/a | yes |
exposure_subnets | Subnets for exposing Apigee services. | list(object({ |
[] |
no |
network | VPC name. | string |
n/a | yes |
network_tags | mTLS proxy network tags | list(string) |
[ |
no |
peering_range | Peering CIDR range | string |
n/a | yes |
project_create | Create project. When set to false, uses a data source to reference existing project. | bool |
false |
no |
project_id | Project id (also used for the Apigee Organization). | string |
n/a | yes |
project_parent | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string |
null |
no |
support_range | Support CIDR range of length /28 (required by Apigee for troubleshooting purposes). | string |
n/a | yes |
tls_cert_path | Path to Server Cert File (pem). | string |
n/a | yes |
tls_key_path | Path to Server Key File (pem). | string |
n/a | yes |
Name | Description |
---|---|
nip_hostnames | Map of envgroup name -> hostnames. |