How to route www to non-www URL using Google App Engine - google-app-engine

I have a custom domain "domain.tld". I followed the instructions via the "custom domains" tab in Google App Engine to configure everything. I had to add a secure handler to my app.yaml file to direct all http to https but I would also like to direct all www.domain.tld to domain.tld and I can't figure out how to do that.

You can use dispatch.yml as per app engine wildcard documentation
dispatch:
# Default service serves the typical web resources and all static resources.
- url: "www.domain.tld/*"
service: default

Related

Custom domains / catch all hostnames on Google App Engine

I'm trying to configure my Google App Engine instance with Cloudflare for Saas, and more precisely Cloudflare's SSL for SaaS offering. The objective being that I can provide to my customer a "custom domain" (also known as "vanity domain"), such that they don't go to dashboard.mywebsite.com, but instead app.customerwebsite.com.
Configuration part
To make sure that my App Engine instance is correctly serving content on dashboard.mywebsite.com, I've made the following:
On Google Cloud side:
I've configured the custom domain dashboard.mywebsite.com.
I've let Google manage the SSL configuration (no custom key/certificate)
Here is my app.yaml configuration file:
runtime: nodejs14
env_variables:
NODE_ENV: 'production'
basic_scaling:
max_instances: 10
idle_timeout: 5m
On Cloudflare side:
I've updated the DNS records so that dashboard.mywebsite.com is perfectly working
I've configured the SSL on the Full mode (while I've tried with Flexible as well - both work)
I waited for a few hours and I confirm that dashboard.mywebsite.com resolves correctly and serves my content (from Google App Engine).
Next, custom domains
According to Cloudflare documentation, I had to register the fallback origin (i.e. dashboard.website.com) and then configure a custom hostname (e.g. app.customerwebsite.com). Which I did.
Now, according to Cloudflare documentation again, my customer has to create a CNAME record. Which I did with a domain of mine:
app.customerwebsite.com CNAME dashboard.mycompany.com
The issue
I waited a few hours again. Then, when I open app.customerwebsite.com in my browser, it shows a Google 404 error page instead of my dashboard. Which makes me think that Cloudflare successfully "redirects" the traffic to Google, but App Engine refuses to serve it. Probably because it doesn't know app.customerwebsite.com?
Any thoughts that would help?
As you noticed, the issue is not related to Cloudflare, but App Engine. The problem with your configuration is that, when App Engine receives a request, based on the Host header, it forwards the request to the right instance.
App Engine lets you map any custom domains that has been previously validated by Google. But in your situation, that would mean you have to register each custom domain of your customers on your App Engine instance. That's too cumbersome (if even possible).
What you need to do instead is the following:
enable a static IP address with Google Cloud
change your DNS record from dashboard CNAME ghs.googlehosted.com to dashboard A YOUR_IP_ADDRESS
configure a Google Cloud Load Balancer to map requests received on that IP address to your App Engine instance.
Google's documentation has a great guide on how to setup a load balancer with Cloud Run. By changing a few settings it works great with App Engine. As an extra help, below is the configuration details of our load balancer that allows us to provide vanity domains / custom domains to our customers through Google Cloud:
Again, the load balancer is here responsible to map all requests received by your IP address (no matter the Host header) straight to your App Engine instance.
As a best practice, it might be useful to push a dispatch.yaml file to your instance:
dispatch:
- url: '*/*'
service: default
Which tells App Engine to send all requests to the default service. It works a bit like a wildcard virtual hosts on an Apache server.

AppEngine flexible static index.html

I am trying to set up a AppEngine flexible (go) backend/api server together with a static frontend.
Ideally i would like to completely decouple the api server from the frontend so was planning to serve all the static files from cloud storage. I have managed to set this up by serving the static files on a subdomain from cloud storage - however, this means that users have to visit the subdomain to retrieve the index.html file.
Does anyone know if it is possible (in e.g. app.yml - but couldnt find anything in the docs here) to get fetch index.html from cloud storage?
I.e. such that:
https://example.com would return index.html from cloud storage
https://example.com/api is routed to my appengine service?
Simply set the "www" subdomain to be your index.html, then let your App Engine handle the request routing. Look into how dispatch.yaml works and you will see how to do it.
Basically, let App Engine route all your default traffic to your index.html and then do the routine specific subdomains to whatever API handlers you have setup.

Serve static SPA from Google Cloud Storage and API from Google App Engine

I have a static web client SPA serviced by a REST API. I'm trying to figure out the best way to host these apps on Google's Cloud Platform using App Engine to host the API, and Cloud Storage to host the static web client.
If I were doing this from scratch, a simple reverse proxy could manage routing traffic between the API and the client assets. To do the equivalent with GCP, I've looked at the following:
Google's Compute Engine supports content-based load balancing: though no equivalent for App Engine
the API on App Engine could proxy requests to Cloud Storage, though at the expense of unnecessary load on the API service
simply host the API and client on separate domains (App Engine and Cloud Storage respectively), and properly configure cross origin issues
Use Google Cloud Endpoints as a reverse proxy to route traffic appropriately between App Engine and Cloud Storage: haven't fully explored this option, though as of writing, Cloud Endpoints does not support routing to multiple hosts (which is defined only in v3 of the OpenAPI spec).
All of the above have limitations. What i'm trying to do seems fairly conventional, but I'm not sure what the path of least resistance is on GCP.
Google Cloud storage allow you to host a static website :
https://cloud.google.com/storage/docs/hosting-static-website
You don't need to use Endpoint or AppEngine as a reverse proxy
If you need to setup a load balancer based on route or if you need to setup ssl certificates you could use storage bucket as a service backend :
https://cloud.google.com/compute/docs/load-balancing/http/backend-bucket
Let's talk about serving SPA static files from Google App Engine.
The SPAs need to serve many routes to a single index.html, normally called rewrite rules.
App Engine can do that with a proper configured app.yaml handlers section.
For the real files part, you serve the real path:
- url: /assets/
static_dir: path/to/real/files
For these fake routes, serve the entrypoint index.html:
- url: /
static_file: path/to/index.html
upload: path/to/index.html
- url: /.*
static_file: path/to/index.html
upload: path/to/index.html
By this configuration, Google Frontend will serve the static files without hitting your backend.
Here's one Angular application and I deployed to App Engine, as an example:
Other stuff about securing APIs and CORS policies, you can consider using dispatch.yaml to avoid cross domain problem. Or serve from different domain with cloud endpoints (with IAP jwk configured).
As you have rightly observed, there are a number of complications that might come into play with your setup. The Google Cloud Storage is simply a Storage, which might not necessarily manage requests to GAE as well as you desire. Perhaps, using Endpoints would be a more viable solution in this case (considering your listed options), where you can use simple Javascripts to call Endpoints in your GAE applications from your Application Files in Google Cloud Storage. However, that being said, I think the better option is to move your static files into App Engine as described here. This will ease the complication of managing resources between two different technologies

Adding a SSL App engine with custom subdomain pointing to Google Storage bucket

Current App:
Goole App Engine on a custom domain: myapp.com
Google Cloud Storage bucket on a custom subdomain (it uses DNS): images.myapp.com
I have SSL certificate with the images subdomain
My question is: Is possible to have this configuration with SSL?
Things I have tried:
Load balancer. I cannot figure out how to redirect everything that is not /images/* to the GAE (it seems it only works with backends)
dispatch.yaml. I think it only works for the services you deploy
In App Engine Settings I have added images.myapp.com, but as the redirection of images.myapp.com is done at DNS level, the secure layer is lost
Any suggestion or idea is more than welcome.
Thank you!
The limitation comes from the Cloud Storage bucket presented as a website under a custom domain - you can't use SSL with that. From You want your content served through HTTPS:
SSL is not currently supported by the Cloud Storage webservers; thus,
you can only use a CNAME redirect with HTTP and not with HTTPS. If you
wish to serve content through HTTPS from your bucket, we recommend you
use a third-party Content Delivery Network with Cloud Storage.
Alternatively, you can serve your static website content from
Firebase Hosting instead of Google Cloud Storage.
If the content of your site meets the Code and static data storage quota you can serve your website through GAE, as static content (through a google CDN), which can be mapped to a custom domain and use SSL. See:
Serving Static Files
Hosting a static website on Google App Engine
If your content exceeds the mentioned quota then you can still serve it through your app, but dynamically, with your app accessing the content stored on GCS and serving it - more expensive as you'll be using instance hours for it.

Deploy cloud endpoints on custom domain

I'm testing with Google Cloud Endpoints on App Engine and I've mapped my app to a custom domain. It appears that this is not possible. I've tried accessing the endpoint url, changing the host but this gives me a 404.
I've also tried to change the root url and backend url for the service, but then I get this error after deployment:
Endpoints: https://test.neenbedankt.com/_ah/api/myapi#v1 Error: API root https://test.neenbedankt.com/_ah/api not allowed on host version.myappid.appspot.com
Can somebody confirm this is a limitation? For my current project this would be a showstopper.
Correct, you can not map to a custom domain at current.
edit: Google CloudEndpoints 2.0 will support this, which is now BETA. As explained by Google in the link below.
Google has now announced this "will be supported" but has not given an ETA.
https://code.google.com/p/googleappengine/issues/detail?id=9384#c44

Resources