How to complete GCP Docs/Tutorial When Your Organization policy blocks External IPs on VMs?
In this how-to you will be resolving a common Organization policy constraint of not allowing External IPs on VMs while completing the Google Docs Deploy a basic Flask web server. In this how-to you will use the Cloud Console to create resources. A follow up with be offered that uses Hashicorp Terraform
Attention: You will encounter known contraints of IT's Organizational Policies in GCP, instructions will be provided to comply.
Assumptions & Prerequisites
- A GCP Organization with constraints/compute.vmExternalIpAccess Enabled
- A Project for learning, referred to as personal sandbox
Create a Virtual Machine (VM)
Google Cloud Platform calls their VMs Google Compute Engines (GCE)
Enable Service APIs
To use the GCE service the service must be enabled on the GCP Project
- Enable API & Services
- Search for Service by using the magnify class at top nav
- Search Enabled APIs
- Enable the necessary APIs with the button "+ Enabel APIS AND SERVICES"
- Enable Compute Engine
Create GCE VM
Search for the "compute engine" Service by using the magnify glass at the top of the page
Select "Create Instance"
Optionally Change Name
Leave Region / Zone (e.g. us-central1 and us-central1-b; note yours for later)
Change Machine Type to e2-micro (to save on spend during learning)
Read the message found under Advance options > Networking > Network interfaces > default > External IPv4
The "External IPs for VM instances" organization policy does not allow associating an external IP address with this instance. Contact your org policy admin to change. Learn more
!! This is important later
Add at Startup script here: Advance options > Management > Automation > Startup script
sudo apt-get update; sudo apt-get install -yq build-essential python3-pip rsync; pip3 install flask
Select "Create" at the bottom
Constraint - No External IP
Aha! Because of Organizational Policy, GCE VMs can not have an external IP. The result is the VM startup script will fail to connect to the external registries and will not be able to download the Python packages.
Skip ahead to next step for resolution OR validate lack of access with steps below
- Go Compute Engine page
- Next to the VM you created, select the text ssh (pic above)
- Authorize the pop-up ssh-in browser
- In the terminal type
pip3 list
, see error message- or try
curl example.com
, see no response
Cloud NAT
By deploying a Cloud NAT in the VPC Network that the VM is deployed in, outbound traffic will be able to access the internet without exposing an external IP address on the VM itself.
- Search for service Cloud NAT
- Select Create Cloud NAT
- Give it a name, e.g. "my-default-network-nat"
- Select Network "default" (must be the same network as the VMs created above)
- select region "us-central1" (must be the same region as the VMs created above)
- Cloud Router
- Create New Router
- Give it a name, e.g. "my-default-nat-router"
- Select Create
- Create New Router
- Select Create
- Make a new VM by following "Create GCE VM" and give the new VM a different name.
- Why? The previously deployed VM executed the start-up script one time (at start up) and will to have run the commands. Replacing VM, is much more aligned with cloud first methodolgies than modifying an existing VM.
Validate this by
- Go Compute Engine page
- Next to the VM you created above select the text ssh
- Authorize the pop-up ssh-in browser
- at the terminal type
pip3 list
, see that flask was installed
Install & Run Demo App
SSH into VM
- Go Compute Engine page
- Next to the VM you created above (the one with the NAT) select the text ssh
- Authorize the pop-up ssh-in browser
Create a file
app.py
with the following from shell prompt$ cat <<EOT > app.py from flask import Flask app = Flask(__name__) @app.route('/') def hello_cloud(): return 'Hello Cloud!' app.run(host='0.0.0.0') EOT
validate
$cat app.py
Execute at SSH prompt
$ python3 app.py
Validate App is Running
Open a second SSH and run $ curl localhost:5000
. Response will be "Hello Cloud!"
Jump to Clean Up Below OR continue with advanced material
Optional: Advance Port Forwarding to Local Browser
TL;DR; Two steps to allow Cloud Shell access to the VM port 5000 and port forward to your local browser
Create Firewall Rule
What are you going to do?
- You will allow Google IAP (Identity Aware Proxy) IP range to connect to any VM in the default VPC
- Search for servic Firewall: VPC Network
- Select "Create Firewall Rule"
- Give it a name
- Network, set to default
- Targets, set to "All instances in network"
- Source IPv4 ranges, set to
35.235.240.0/20
- Protocols & Ports
- TCP: 5000
- Create
Create IAP Tunnel
What are you doing?
- Using
gcloud
to create a IAP Tunnel from Cloud Shell, now shell has access to Port 5000 on your VM.
Why?
- IAP adds a level of verification, checks that you are authenticated and authorized to access this port
Open Cloud Console
Update following script with your VM name
$ gcloud compute start-iap-tunnel <your_vm_here> 5000 --local-host-port=localhost:5000 --zone=us-central1-a
Authorize Cloud Shell Session
Output > "...tunnel connection works"
Modify Web Preview in Cloud Shell
- Select Web Preview
- Modify Port
- Enter 5000
- Save & Preview
- New browser tab will open and display "Hello, Cloud!"
Clean Up
Deleting resources is the best way to minimize unintended spend.
- Delete VMs
- Delete Firewall Rule
- Delete Cloud Router & Cloud NAT
Summary & Review
- Because of Organizational Policy Contraints, such as No External IP, completed Google Trainings need to be modified
- For GCE VMs to have access to internet for installation of packages using Cloud NAT provides a secure way to permit VMs internet outbound access
- Using Cloud IAP creates a tunnel connection to VMs that do not external IP addresses