1. Overview
In this lab, you will deploy the employee portal that allows employees to view, update and delete orders from the Cymbal Eats app. You will use Identity Aware Proxy (IAP) to secure portal access without using a Virtual Private Network (VPN). IAP simplifies implementing a zero-trust access model and takes less time than a VPN for remote workers both on-premises and in cloud environments with a single point of control for managing access to your apps.
What is Identity-Aware Proxy?
Identity-Aware Proxy (IAP) is a Google Cloud service that intercepts requests sent to your application, authenticates the user making the request using the Google Identity Service, and only lets the requests through if they come from a user authorized to access the application. In addition, it can modify the request headers to include information about the authenticated user.
What you will learn
- How to configure a Serverless Network Endpoint Group (NEG)
- How to configure a load balancer
- How to enable IAP to restrict access
- How to restrict access using IAP
2. Setup and Requirements
Self-paced environment setup
- Sign-in to the Google Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one.
- The Project name is the display name for this project's participants. It is a character string not used by Google APIs. You can update it at any time.
- The Project ID is unique across all Google Cloud projects and is immutable (cannot be changed after it has been set). The Cloud Console auto-generates a unique string; usually you don't care what it is. In most codelabs, you'll need to reference the Project ID (it is typically identified as
PROJECT_ID
). If you don't like the generated ID, you may generate another random one. Alternatively, you can try your own and see if it's available. It cannot be changed after this step and will remain for the duration of the project. - For your information, there is a third value, a Project Number which some APIs use. Learn more about all three of these values in the documentation.
- Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab shouldn't cost much, if anything at all. To shut down resources so you don't incur billing beyond this tutorial, you can delete the resources you created or delete the whole project. New users of Google Cloud are eligible for the $300 USD Free Trial program.
Environment Setup
- Create project and resource related environment variables
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export REGION=us-east1
export ORDER_SERVICE_URL=order-service
export INVENTORY_SERVICE_URL=inventory-service
export MENU_SERVICE_URL=menu-service
- Enable the IAP and Cloud resource manager service APIs
gcloud services enable \
iap.googleapis.com \
cloudresourcemanager.googleapis.com \
cloudidentity.googleapis.com \
compute.googleapis.com
- Clone the sample app repository and navigate to the directory
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/employee-ui
- Deploy the Employee portal using the setup script. Wait for the script to complete before moving to the next step
./setup.sh
Example output
... Done. Service [employee-ui-service] revision [employee-ui-service-00001-quw] has been deployed and is serving 100 percent of traffic. Service URL: https://employee-ui-service-gbtuuy5eda-uk.a.run.app
- Click on the Service URL link
3. Configuring a Serverless Network Endpoint Group (NEG)
You will create a Serverless Network Endpoint Group( Serverless NEG) for the employee UI Cloud Run service. Serverless NEGs allow you to use Google Cloud serverless apps with external HTTP(S) Load Balancing.
- Create a network endpoint group for the employee UI service.
gcloud compute network-endpoint-groups create employee-ui-iap-neg \
--project $PROJECT_ID \
--region=$REGION \
--network-endpoint-type=serverless \
--cloud-run-service=employee-ui-service
Example Output
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/regions/us-east1/networkEndpointGroups/employee-ui-iap-neg]. Created network endpoint group [employee-ui-iap-neg].
Create a backend service and add the serverless NEG
A backend service defines how Cloud Load Balancing distributes traffic. The backend service configuration contains a set of values, such as the protocol used to connect to backends, various distribution and session settings, health checks, and timeouts. These settings provide fine-grained control over how your load balancer behaves.
- Create a backend service
gcloud compute backend-services create employee-ui-iap-backend \
--global
Example Output
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/backendServices/employee-ui-iap-backend]. NAME: employee-ui-iap-backend BACKENDS: PROTOCOL: HTTP
- Add the serverless NEG as a backend to the backend service
gcloud compute backend-services add-backend employee-ui-iap-backend \
--global \
--network-endpoint-group=employee-ui-iap-neg \
--network-endpoint-group-region=$REGION
Example Output
Updated [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/backendServices/employee-ui-iap-backend].
- Create a URL map to route incoming requests to the backend service
gcloud compute url-maps create employee-ui-iap-url-map \
--default-service employee-ui-iap-backend
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/urlMaps/employee-ui-iap-url-map]. NAME: employee-ui-iap-url-map DEFAULT_SERVICE: backendServices/employee-ui-iap-backend
4. Configuring the Load Balancer Components
The following diagram shows the load balancer uses a serverless NEG backend to direct requests to a serverless Cloud Run service.
Reserve a static IP address
- Reserve an static IPv4 address and store the domain
gcloud compute addresses create employee-ui-iap-ip \
--network-tier=PREMIUM \
--ip-version=IPV4 \
--global
Example Output
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/addresses/employee-ui-iap-ip].
- Store the nip.io domain
export DOMAIN=$(gcloud compute addresses list --filter employee-ui-iap-ip --format='value(ADDRESS)').nip.io
Create a Google-managed SSL certificate resource
- Create a Google-managed SSL certificate resource
gcloud compute ssl-certificates create employee-ui-iap-cert \
--description=employee-ui-iap-cert \
--domains=$DOMAIN \
--global
Example Output
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/sslCertificates/employee-ui-iap-cert]. NAME: employee-ui-iap-cert TYPE: MANAGED CREATION_TIMESTAMP: 2022-04-18T06:39:37.474-07:00 EXPIRE_TIME: MANAGED_STATUS: PROVISIONING 34.102.234.98.nip.io: PROVISIONING
Create a target HTTPS proxy
- Create the target HTTPS proxy to route requests to your URL map
gcloud compute target-https-proxies create employee-ui-iap-http-proxy \
--ssl-certificates employee-ui-iap-cert \
--url-map employee-ui-iap-url-map
Example Output
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/targetHttpsProxies/employee-ui-iap-http-proxy]. NAME: employee-ui-iap-http-proxy SSL_CERTIFICATES: employee-ui-iap-cert URL_MAP: employee-ui-iap-url-map CERTIFICATE_MAP:
Configure forwarding rules
- Create a forwarding rule to route incoming requests to the proxy
gcloud compute forwarding-rules create employee-ui-iap-forwarding-rule \
--load-balancing-scheme=EXTERNAL \
--network-tier=PREMIUM \
--address=employee-ui-iap-ip \
--global \
--ports=443 \
--target-https-proxy employee-ui-iap-http-proxy
Example output
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/forwardingRules/employee-ui-iap-forwarding-rule].
Restricting ingress to the Cloud Run service
Restrict the ingress traffic to only accept internal requests and requests coming through HTTP(S) Load Balancing.
- Update the service to only allow ingress traffic from internal requests and requests through HTTP(S) Load Balancer
gcloud run services update employee-ui-service \
--ingress internal-and-cloud-load-balancing \
--region $REGION
Example output
OK Deploying... Done. OK Creating Revision... OK Routing traffic... Done. Service [employee-ui-service] revision [employee-ui-service-00001-quw] has been deployed and is serving 100 percent of traffic. Service URL: https://employee-ui-service-gbtuuy5eda-uk.a.run.app
- Click on the Service URL link
Access to the Cloud Run service URL now shows as forbidden.
5. Enabling Cloud Identity-Aware Proxy (IAP) on the Load Balancer
IAP lets you establish a central authorization layer for applications accessed by HTTPS. You can use an application-level access control model instead of network-level firewalls.
Configuring the OAuth consent screen
A brand is the OAuth consent screen that contains branding information for users. Brands might be restricted to internal or public users. An internal brand allows the OAuth flow to be accessed by a member of the same Google Workspace organization as the project. A public brand makes the OAuth flow accessible to anyone with access to the internet.
- Create a brand
export USER_EMAIL=$(gcloud config list account --format "value(core.account)")
gcloud alpha iap oauth-brands create \
--application_title="Cymbal Eats" \
--support_email=$USER_EMAIL
Example Output
Created [462858740426]. applicationTitle: Cymbal Eats name: projects/462858740426/brands/462858740426 orgInternalOnly: true
Creating an IAP OAuth Client
- Create a client using the brand name from the previous step
gcloud alpha iap oauth-clients create \
projects/$PROJECT_ID/brands/$PROJECT_NUMBER \
--display_name=cymbal-eats-employee-ui
Example Output
Created [462858740426-tkpv8n03opijg7erd3s9ccued2pfllsd.apps.googleusercontent.com]. displayName: cymbal-eats-employee-ui name: projects/462858740426/brands/462858740426/identityAwareProxyClients/462858740426-tkpv8n03opijg7erd3s9ccued2pfllsd.apps.googleusercontent.com secret: [secret-removed]
- Store the client name, ID and secret
export CLIENT_NAME=$(gcloud alpha iap oauth-clients list \
projects/$PROJECT_NUMBER/brands/$PROJECT_NUMBER --format='value(name)' \
--filter="displayName:cymbal-eats-employee-ui")
export CLIENT_ID=${CLIENT_NAME##*/}
export CLIENT_SECRET=$(gcloud alpha iap oauth-clients describe $CLIENT_NAME --format='value(secret)')
- In the Cloud Console, select the project from the drop-down project selection menu
- Navigate to the OAuth consent screen in the Cloud Console
- Click MAKE EXTERNAL under User Type
- Select Testing as the Publishing status
- Click CONFIRM
6. Restricting Access with IAP
Restrict access to the backend service using IAP then verify the application is inaccessible.
- Enable IAP on the backend service
gcloud iap web enable --resource-type=backend-services \
--oauth2-client-id=$CLIENT_ID \
--oauth2-client-secret=$CLIENT_SECRET \
--service=employee-ui-iap-backend
Verify IAP configuration
- Verify the SSL certificate is ACTIVE
gcloud compute ssl-certificates list --format='value(MANAGED_STATUS)'
- Get service URL
echo https://$DOMAIN
Example output
https://34.102.234.98.nip.io
- Click on the service URL to open the employee portal.
- Login using your lab credentials.
- Close the browser
Grant user access to the employee portal
- Add an IAM policy binding for the role of
'roles/iap.httpsResourceAccessor'
for the user created in the previous step
gcloud iap web add-iam-policy-binding \
--resource-type=backend-services \
--service=employee-ui-iap-backend \
--member=user:$USER_EMAIL \
--role='roles/iap.httpsResourceAccessor'
Example output
Updated IAM policy for backend service [projects/462858740426/iap_web/compute/services/employee-ui-iap-backend].
Testing service access
Confirm access to the employee portal has been granted
- Get service URL
echo https://$DOMAIN
Example output
https://34.102.234.98.nip.io
- Click on the service URL to open the employee portal.
You should now have access to the employee portal.
(Optional) Deploy all dependencies, deploying these microservices may take ~20 minutes.
unset ORDER_SERVICE_URL
unset INVENTORY_SERVICE_URL
unset MENU_SERVICE_URL
cd ~/cymbal-eats
./setup.sh
./get-site-urls.sh
7. Congratulations!
Congratulations, you finished the codelab!
What's next:
Explore other Cymbal Eats codelabs:
- Triggering Cloud Workflows with Eventarc
- Triggering Event Processing from Cloud Storage
- Connecting to Private CloudSQL from Cloud Run
- Connecting to Fully Managed Databases from Cloud Run
- Triggering Cloud Run Jobs with Cloud Scheduler
- Securely Deploying to Cloud Run
- Securing Cloud Run Ingress Traffic
- Connecting to private AlloyDB from GKE Autopilot
Clean up
To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.
Deleting the project
The easiest way to eliminate billing is to delete the project that you created for the tutorial.