{"id":24233605,"url":"https://github.com/memes/f5-google-bigip-isolated-vpcs","last_synced_at":"2026-02-17T05:01:56.604Z","repository":{"id":56201501,"uuid":"296448468","full_name":"memes/f5-google-bigip-isolated-vpcs","owner":"memes","description":"Provision BIG-IP in VPCs that do not have access to the internet","archived":false,"fork":false,"pushed_at":"2020-11-20T20:12:00.000Z","size":887,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-07T23:36:49.781Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/memes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-17T21:41:19.000Z","updated_at":"2020-11-20T20:12:00.000Z","dependencies_parsed_at":"2022-08-15T14:31:44.936Z","dependency_job_id":null,"html_url":"https://github.com/memes/f5-google-bigip-isolated-vpcs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/memes/f5-google-bigip-isolated-vpcs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/memes%2Ff5-google-bigip-isolated-vpcs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/memes%2Ff5-google-bigip-isolated-vpcs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/memes%2Ff5-google-bigip-isolated-vpcs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/memes%2Ff5-google-bigip-isolated-vpcs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/memes","download_url":"https://codeload.github.com/memes/f5-google-bigip-isolated-vpcs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/memes%2Ff5-google-bigip-isolated-vpcs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29534446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T05:00:25.817Z","status":"ssl_error","status_checked_at":"2026-02-17T04:57:16.126Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-14T16:01:22.805Z","updated_at":"2026-02-17T05:01:56.389Z","avatar_url":"https://github.com/memes.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deploy BIG-IP in GCP without internet access\n\n![pre-commit](https://github.com/memes/f5-google-bigip-isolated-vpcs/workflows/pre-commit/badge.svg)\n\nThis repo contains sample Terraform to provision a BIG-IP HA cluster with CFE on\nGCP where internet access is prohibited. The files will create a Cloud DNS\nprivate zone to shadow `*.googleapis.com` with `restricted.googleapis.com`\nendpoints, and install run-time libraries from a GCS bucket.\n\n![High-level architecture](images/isolated-vpcs-private-access-route.png)\n\n1. BIG-IP (and bastion) instances attempt to connect to Storage APIs.\n2. Cloud DNS private zone for `googleapis.com` has been injected into each VPC\n   network; DNS returns a CNAME alias for `restricted.googleapis.com` for all\n   `googleapis.com` lookups.\n3. A custom route provides a way to reach Google API endpoints from VMs to GCP\n   services that does not traverse the public internet.\n4. GCS API endpoints in Google's private VPC respond.\n\n## Dependencies\n\n1. GCP project with APIs enabled\n   * Compute Engine - compute.googleapis.com\n   * IAP - iap.googleapis.com\n   * OS Login - oslogin.googleapis.com\n   * Secret Manager - secretmanager.googleapis.com\n   * Storage JSON API - storage-api.googleapis.com\n   * Cloud DNS - dns.googleapis.com\n\n2. User account (or Terraform service account) with permissions to create\n   resources, assign roles, and manage networks.\n\n3. GCS bucket or other HTTP(S)/FTP site accessible from the BIG-IP VMs to host\n   software packages\n\n## Steps to execute\n\n1. Create or prepare a GCS bucket, or other HTTP host on the private network that\n   can supply Cloud Libraries and supporting files as needed by BIG-IP and bastion\n   host.\n\n2. Prepare Terraform config and variables setting files; you can make a copy of\n   `env/emes` folder and modify the `base.config` and `base.tfvars` files to\n   match your environment.\n\n   * This repo assumes you have setup and enabled IAM impersonation for a\n     Terraform service account; set `tf_sa_email` variable to empty string (\"\")\n     to use your own credentials or a service account via application-default\n     credentials.\n\n   * If you are using a GCS bucket to host RPMs, etc, use the scheme for encoding\n     HTTP download requests as described at\n     [Encoding URI path parts](https://cloud.google.com/storage/docs/request-endpoints#encoding)\n     and set `cloud_libs_bucket` variable to the name of the GCS bucket. Terraform\n     will ensure the BIG-IP and bastion service accounts have read-only access\n     to the bucket.\n\n     E.g using `automation-factory-f5-gcs-4138-sales-cloud-sales` bucket as a software repository:-\n\n     ```hcl\n     install_cloud_libs = [\n        \"https://storage.googleapis.com/storage/v1/b/automation-factory-f5-gcs-4138-sales-cloud-sales/o/misc%2Ff5-cloud-libs.tar.gz?alt=media\",\n        \"https://storage.googleapis.com/storage/v1/b/automation-factory-f5-gcs-4138-sales-cloud-sales/o/misc%2Ff5-cloud-libs-gce.tar.gz?alt=media\",\n        \"https://storage.googleapis.com/storage/v1/b/automation-factory-f5-gcs-4138-sales-cloud-sales/o/misc%2Ff5-appsvcs-3.22.1-1.noarch.rpm?alt=media\",\n        \"https://storage.googleapis.com/storage/v1/b/automation-factory-f5-gcs-4138-sales-cloud-sales/o/misc%2Ff5-declarative-onboarding-1.15.0-3.noarch.rpm?alt=media\",\n        \"https://storage.googleapis.com/storage/v1/b/automation-factory-f5-gcs-4138-sales-cloud-sales/o/misc%2Ff5-cloud-failover-1.5.0-0.noarch.rpm?alt=media\"\n     ]\n     install_tinyproxy_url = \"https://storage.googleapis.com/storage/v1/b/automation-factory-f5-gcs-4138-sales-cloud-sales/o/misc%2Ftinyproxy-1.8.3-2.el7.x86_64.rpm?alt=media\"\n     cloud_libs_bucket = \"automation-factory-f5-gcs-4138-sales-cloud-sales\"\n     ```\n\n3. Initialise and execute Terraform\n\n   Using `emes` configuration as an example.\n\n   ```shell\n   terraform init -backend-config env/emes/base.config\n   terraform apply -var-file env/emes/base.tfvars -auto-approve\n   ```\n\n   ```shell\n   Apply complete! Resources: 52 added, 0 changed, 0 destroyed.\n\n   Outputs:\n\n   admin_password_key = projects/f5-gcs-4138-sales-cloud-sales/secrets/isolated-vpcs-bigip-admin-passwd-key\n   bastion_name = isolated-vpcs-bastion\n   bigip_addresses = {\n     \"isolated-vpcs-bigip-0\" = {\n       \"external\" = [\n         \"172.16.0.3\",\n         \"172.16.0.4/32\",\n       ]\n       \"internal\" = [\n         \"172.18.0.2\",\n       ]\n       \"management\" = [\n         \"172.17.0.2\",\n       ]\n       \"vips\" = [\n         \"172.16.0.4/32\",\n       ]\n     }\n     \"isolated-vpcs-bigip-1\" = {\n       \"external\" = [\n         \"172.16.0.2\",\n       ]\n       \"internal\" = [\n         \"172.18.0.3\",\n       ]\n       \"management\" = [\n         \"172.17.0.3\",\n       ]\n       \"vips\" = []\n     }\n   }\n   cfe_label_value = isolated-vpcs\n   ```\n\n4. Wait for BIG-IPs to complete initialisation\n\n   You can check initialisation status by viewing the serial console output of\n   instances and verifying that the CFE declaration has been applied, as this is\n   the final step in initialisation.\n\n   ```shell\n   gcloud compute instances get-serial-port-output --project f5-gcs-4138-sales-cloud-sales --zone us-central1-c isolated-vpcs-bigip-1 2\u003e/dev/null | grep '/config/cloud/gce'\n   ```\n\n   ```shell\n   2020-09-17T15:54:25.447-0700: /config/cloud/gce/initialSetup.sh: Info: Initialisation starting\n   2020-09-17T15:54:25.451-0700: /config/cloud/gce/initialSetup.sh: Info: Generating /config/cloud/gce/network.config\n   2020-09-17T15:54:25.610-0700: /config/cloud/gce/initialSetup.sh: Info: Waiting for mcpd to be ready\n   2020-09-17T15:55:14.543-0700: /config/cloud/gce/multiNicMgmtSwap.sh: Rebooting for multi-nic management interface swap\n   2020-09-17T15:56:00.021-0700: /config/cloud/gce/initialSetup.sh: Info: Initialisation starting\n   2020-09-17T15:56:00.025-0700: /config/cloud/gce/initialSetup.sh: Info: Generating /config/cloud/gce/network.config\n   2020-09-17T15:56:00.037-0700: /config/cloud/gce/initialSetup.sh: Info: Waiting for mcpd to be ready\n   2020-09-17T15:56:27.580-0700: /config/cloud/gce/multiNicMgmtSwap.sh: Nothing to do\n   2020-09-17T15:56:27.587-0700: /config/cloud/gce/initialNetworking.sh: Info: Waiting for mcpd to be ready\n   2020-09-17T15:56:27.841-0700: /config/cloud/gce/initialNetworking.sh: Info: Resetting management settings\n   ...\n   2020-09-17T22:59:08.234+0000: /config/cloud/gce/customConfig.sh: Info: waiting for mcpd to be ready\n   2020-09-17T22:59:08.959+0000: /config/cloud/gce/customConfig.sh: Info: Applying CFE payload\n   2020-09-17T22:59:26.609+0000: /config/cloud/gce/customConfig.sh: Info: CFE declaration is applied\n   2020-09-17T22:59:26.614+0000: /config/cloud/gce/initialSetup.sh: Info: Initialisation complete\n   2020-09-17T22:59:26.620+0000: /config/cloud/gce/resetManagementRoute.sh: waiting for mcpd to be ready\n   2020-09-17T22:59:27.051+0000: /config/cloud/gce/resetManagementRoute.sh: complete\n   ```\n\n5. Login and configure BIG-IP as needed\n\n   In this demo, accessing the BIG-IP requires the use of the bastion host.\n   Create an SSH tunnel through the bastion host and use tinyproxy to access\n   instances.\n\n   1. Create an IAP session for SSH to the bastion and tunnel between port 8888\n   on local computer and bastion. Tinyproxy has been configured to be active on\n   port 8888 too.\n\n      ```shell\n      gcloud compute ssh --project f5-gcs-4138-sales-cloud-sales --zone us-central1-f isolated-vpcs-bastion --tunnel-through-iap -- -A -L8888:127.0.0.1:8888\n      ```\n\n      This command will ensure that your key is forwarded to the bastion so\n      you can SSH to a BIG-IP instance on it's management IP address\n\n   2. Set your browser to proxy HTTP and HTTPS traffic through localhost:8888\n\n      ![Proxy Config](images/firefox_proxy_settings.png)\n\n   3. Retrieve the random admin password from Secret Manager\n\n     ![Secret Manager](images/secret_manager.png)\n\n   4. Login to a BIG-IP instance using `admin` account and password from step 3\n\n      ![BIG-IP Device List](images/cfe_pair.png)\n\n## Clean up resources\n\n1. Tear down the resources created in this demo\n\n   ```shell\n   terraform destroy -var-file env/emes/base.tfvars -auto-approve\n   ```\n\n2. Destroy any supporting GCS buckets or other reosources that were created\n   outside of this repo\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003c!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| terraform | ~\u003e 0.12, \u003c 0.13 |\n| google | ~\u003e3.44 |\n| google | ~\u003e3.44 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| google | ~\u003e3.44 ~\u003e3.44 |\n| google.executor | ~\u003e3.44 ~\u003e3.44 |\n| random | n/a |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| bastion\\_zone | The GCE zone to deploy the bastion host. Default is 'us-central1-f'. | `string` | `\"us-central1-f\"` | no |\n| bigip\\_zones | The GCE zones to deploy the BIG-IP instances. Default is 'us-central1-f' and\u003cbr\u003e'us-central1-c'. | `list(string)` | \u003cpre\u003e[\u003cbr\u003e  \"us-central1-f\",\u003cbr\u003e  \"us-central1-c\"\u003cbr\u003e]\u003c/pre\u003e | no |\n| cfe\\_label\\_key | The CFE label key to assign to resources that are going to be managed by CFE.\u003cbr\u003eDefault value is 'f5\\_cloud\\_failover\\_label'. | `string` | `\"f5_cloud_failover_label\"` | no |\n| cfe\\_label\\_value | The CFE label value to assign to resources that are going to be managed by this\u003cbr\u003eBIG-IP deployment. If left empty, a value will be generated for this deployment. | `string` | `\"\"` | no |\n| cloud\\_libs\\_bucket | An optional GCS bucket name to which the BIG-IP service account will be granted\u003cbr\u003eread-only access. Default is empty string.\u003cbr\u003e\u003cbr\u003eSee `install_cloud_libs`. | `string` | `\"\"` | no |\n| image | The GCE image to use as the base for BIG-IP instances; default is latest BIG-IP v15 payg good 25mbs. | `string` | `\"projects/f5-7626-networks-public/global/images/f5-bigip-15-1-0-4-0-0-6-payg-good-25mbps-200618231522\"` | no |\n| install\\_cloud\\_libs | Contains the URLs for F5's Cloud Libs required for BIG-IP w/CFE on-boarding,\u003cbr\u003eoverriding the default download patch from cdn.f5.com and github.com. | `list(string)` | n/a | yes |\n| install\\_tinyproxy\\_url | Contains the URL for tinyproxy RPM to install on bastion host. | `string` | n/a | yes |\n| labels | An optional map of label key-values to apply to all resources. Default is an\u003cbr\u003eempty map. | `map(string)` | `{}` | no |\n| prefix | An optional prefix to use when naming resources; default is 'isolated-vpcs'.\u003cbr\u003eOverride this value if you are deploying in a shared environment. | `string` | `\"isolated-vpcs\"` | no |\n| project\\_id | The existing project id that will host the BIG-IP resources. | `string` | n/a | yes |\n| tf\\_sa\\_email | The fully-qualified email address of the Terraform service account to use for\u003cbr\u003eresource creation. E.g.\u003cbr\u003etf\\_sa\\_email = \"terraform@PROJECT\\_ID.iam.gserviceaccount.com\" | `string` | `null` | no |\n| tf\\_sa\\_token\\_lifetime\\_secs | The expiration duration for the service account token, in seconds. This value\u003cbr\u003eshould be high enough to prevent token timeout issues during resource creation,\u003cbr\u003ebut short enough that the token is useless replayed later. Default value is 1200. | `number` | `1200` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| admin\\_password\\_key | The name of the Secret Manager key that contains the generated admin password. |\n| bastion\\_name | The name of the bastion VM. |\n| bigip\\_addresses | The set of IPv4 addresses and CIDRs assigned to the BIG-IP instances. |\n| cfe\\_label\\_value | The CFE-specific label that has been applied to CFE related resources. |\n\n\u003c!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmemes%2Ff5-google-bigip-isolated-vpcs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmemes%2Ff5-google-bigip-isolated-vpcs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmemes%2Ff5-google-bigip-isolated-vpcs/lists"}