My main goal is to deploy a R Shiny app on GCP and make it subject to authorization so that only certain users can access it.
To start simple, I am not trying to deploy my docker container with my Shiny app, but rather I am trying to deploy the GCP demo container, called 'hello'.
I am following this post (https://hodo.dev/posts/post-30-gcp-cloudrun-iap/), as suggested in here (https://stackoverflow.com/a/70533626), with a slight modification for what regards the SSL certificate. I am going to describe all steps I am taking anyway.
- Log in to the project
gcloud auth login
gcloud auth list
gcloud projects list
gcloud config set project `PROJECT ID`
gcloud config configurations list
- Deploy the demo container
- In GCP console, from within my project, click CREATE SERVICE
- In Container image URL, select Demo containers -> hello, then click SELECT
- Service name: cloud-run-iap
- Leave region on us-central1
- Authentication: Require authentication
- Ingress control: select Internal and tick the box 'Allow traffic from external application load balancers'
- Leave the container port as default 8080
- Then, click CREATE
- Set project and region environment variables
PROJECT_ID=$(gcloud config list project --format='value(core.project)')
REGION=us-central1
- Configure IAP
Configure the OAuth consent screen
- Go to the OAuth consent screen in the “APIs & Services” section
- Choose “External” and then hit “Create”
- Under Support email, select the email address you want to display as a public contact. This email address must be your email address, or a Google Group you own.
- Enter the Application name you want to display.
- Click Save.
- Navigate again to the OAuth consent screen and add your user to the list of the test users.
Configure OAuth credentials
Go to the Credentials page in the “APIs & Services” section
On the Create credentials drop-down list, select *OAuth client ID.
Under Application type, select Web application.
Add a Name for your OAuth client ID.
Click Create. Your OAuth client ID and client secret are generated and displayed on the OAuth client window.
Click OK.
Select the client that you created.
Copy the client ID to the clipboard.
Add the universal redirect URL to the authorized redirect URIs field in the following format: https://iap.googleapis.com/v1/oauth/clientIds/CLIENT_ID:handleRedirect
Then, store CLIENT_ID and CLIENT_SECRET to be used in the following commands.
- Configure Load Balancer
Create the Network Endpoint Group (NEG)
gcloud compute network-endpoint-groups create cloud-run-iap-neg \
--project $PROJECT_ID \
--region=$REGION \
--network-endpoint-type=serverless \
--cloud-run-service=cloud-run-iap
Create the backend service
gcloud compute backend-services create cloud-run-iap-backend \
--load-balancing-scheme=EXTERNAL \
--global \
--iap=enabled,oauth2-client-id=$CLIENT_ID,oauth2-client-secret=$CLIENT_SECRET
Add the serverless NEG as a backend to the backend service
gcloud compute backend-services add-backend cloud-run-iap-backend \
--global \
--network-endpoint-group=cloud-run-iap-neg \
--network-endpoint-group-region=$REGION
Create the url map
gcloud compute url-maps create cloud-run-iap-url-map \
--default-service cloud-run-iap-backend
- Reserve an IP address
gcloud compute addresses create cloud-run-iap-ip \
--network-tier=PREMIUM \
--ip-version=IPV4 \
--global
Then, copy the ip address to clipboard.
Next, update my DNS records creating an A record having this ip address as its value.
Store the domain name as environment variable:
DOMAIN_ADDRESS=my-domain-address.com
- Add a Google Managed Certificate
- Go to Certificate Manager API (enable it if not yet enabled)
- Go to Classic Certificates https://cloud.google.com/load-balancing/docs/ssl-certificates/google-managed-certs
- Add Certificate
- Give it a name (e.g. mysslcert)
- Select ‘Create Google-managed certificate’
- Hit CREATE
Store the certificate name to use it in the following commands:
CERTIFICATE_NAME=mysslcert
Create the https proxy
gcloud compute target-https-proxies create cloud-run-iap-http-proxy \
--ssl-certificates $CERTIFICATE_NAME \
--url-map cloud-run-iap-url-map
Create the global forwarding rule
gcloud compute forwarding-rules create cloud-run-iap-forwarding-rule \
--load-balancing-scheme=EXTERNAL \
--network-tier=PREMIUM \
--address=cloud-run-iap-ip \
--global \
--ports 443 \
--target-https-proxy cloud-run-iap-http-proxy
At this point, if I navigate to the domain, I am asked to login and then I get this error page as described in the original tutorial, suggesting that the IAP is working.
- Grant the role IAP-secured Web App User
BACKEND_SERVICE=$(gcloud compute backend-services list --filter="name~'cloud-run-iap-backend'" --format="value(name)")
USER_EMAIL=$(gcloud config list account --format "value(core.account)")
gcloud iap web add-iam-policy-binding \
--resource-type=backend-services \
--service $BACKEND_SERVICE \
--member=user:$USER_EMAIL \
--role='roles/iap.httpsResourceAccessor'
Now, if I go to the domain, I get this error:
The IAP service account is not provisioned. Please follow the instructions to create service account and rectify IAP and Cloud Run setup: https://cloud.google.com/iap/docs/enabling-cloud-run
Therefore, as per troubleshoot instructions at https://cloud.google.com/iap/docs/enabling-cloud-run I add:
gcloud beta services identity create --service=iap.googleapis.com --project=[PROJECT_ID]
But then if I go again to the domain I get:
Error: Forbidden Your client does not have permission to get URL / from this server.
I am stuck at this point and I do not understand what I am missing.