Google Cloud: Storage and App Engine - node.js

I have a web application that has frontend (React) and backend(Express) separately, so in my local environment, frontend is running on localhost:8080 while backend is running on localhost:3000.
I could deploy backend server to App Engine running on https://[app_name].appspot.com.
and then I also deployed frontend to Google Cloud Storage by referencing this. However, the frontend application is also running on https://[app_name].appspot.com.
When I open the app, it is showing frontend but api call is not working.
I do not have custom domain yet, and I am also using postgresql.
Is there any way to set different url for frontend and backend? or Am I doing something wrong in the structure to set an application?

Mapping to a domain name (either the default appspot.com one or a custom one) is done at the application level, not at the service level. Your both services, being part of the same app, would thus be mapped to the same domain.
Side note here: I assume you chose different service/module names for your services (in the respective .yaml files), otherwise they overwrite each-other at deployment time.
Routing a request to one service or another is done based on pattern matching on the filepath portion in the URL, not on the host/domain portion. First match wins and no match always goes to the default service.
Because of this typically the frontent is the default service (you can also leave it unnamed). An any other, more dedicated service, have an identifying pattern in their URL path which is used for routing with a dispatch.yaml file. In your case, for example, the backend service would be the specialized one and could serve, let's say, URLs starting with /backend/, thus could have a dispatch.file like this:
dispatch:
- url: "*/backend/*"
module: <backend-service-name>
More or less related:
Configuring two services on the same domain in dispatch.yaml
GCP Point Custom Domain to Specific App Engine Service
Running multiple services using dev_appserver.py on different ports
Note: You have to account for the specific pattern inside the specialized services as well. If, for example, your backend service currently serves a request for /index.html you'll have to adjust it to serve /backend/index.html instead.
It might be possible to make both services work side by side without a dispatch file, using other routing methods (see the entire How Requests are Routed section), but IMHO it's more difficult to set up and more fragile. Especially when trying to also use custom domains.

Related

Azure Container App single hostname for replicas

I successfully created the Azure Container App named my-app-name to host the Python Flask App.
The hostname for my app uses FQDN, so it looks like my-app-name.grayocean-1r2fd430h.centralus.azurecontainerapps.io.
I would like the hostname to be more user-friendly, for example my-app-name.azurecontainerapps.io (similar to the App Service, where it's named my-app-name.azurewebsites.net by default)
What should I do to make my custom hostname point to the Container App?
Unlike app service, in container apps there is a concept of an environment that groups all your apps that might need to communicate together whether it's for microservices or other designs you might have. the grayocean-1r2fd430h.centralus part is the unique part for your particular environment in this case.
However, From Container Apps you have 2 options here to give your app a custom domain:
1- You can use a different suffix for all the apps on your environment. i.e: replacing .grayocean-1r2fd430h.centralus.azurecontainerapps.io with some domain you might have, like .cornisto.io for example See https://learn.microsoft.com/en-us/azure/container-apps/environment-custom-dns-suffix for how to configure that.
2- You can assign custom domains per container app where each application can have its own set of custom domains that route to it. See this doc for how to set that up https://learn.microsoft.com/en-us/azure/container-apps/custom-domains-certificates
You could also use a service like Azure Front Door or API Management to proxy traffic to your application and the configuration of a custom domain would be on that end instead.

Hosting a separate app service as a website directory

Is it possible to include a separate Azure App Service as part of another App Service?
For example lets say that I have a website called www.mycompany.com hosted in its own Azure App Service. I have another Azure App Service that I want to make it accessible by going to a specific URL in the first App Service.
So in other words when a request comes to www.mycompany.com/eu/ I want the content of this endpoint (/eu) to be served from the other app service. Would a load balancer work? The reason I want to do this is because the /eu endpoint has grown too big and I would like to separate that from the main site and host it on a separate app service. I hope my question is clear.
Thanks in advance.
For this purpose you could use Application Gateway.
In a certain sense it resembles a load balancer (it is a L7 LB indeed) as you indicated, but the product provides many additional features.
The following image, extracted from the product documentation, explains how it works:
Basically, as outlined in the aforementioned docs, when describing how an Application Gateway accepts a request (note they mention WAF in the explanation, an optional security threat prevention system):
Before a client sends a request to an application gateway, it
resolves the domain name of the application gateway by using a Domain
Name System (DNS) server. Azure controls the DNS entry because all
application gateways are in the azure.com domain.
The Azure DNS returns the IP address to the client, which is the
frontend IP address of the application gateway.
The application gateway accepts incoming traffic on one or more
listeners. A listener is a logical entity that checks for
connection requests. It's configured with a frontend IP address,
protocol, and port number for connections from clients to the
application gateway.
If a web application firewall (WAF) is in use, the application
gateway checks the request headers and the body, if present,
against WAF rules. This action determines if the request is valid
request or a security threat. If the request is valid, it's routed
to the backend. If the request isn't valid and WAF is in Prevention
mode, it's blocked as a security threat. If it's in Detection mode,
the request is evaluated and logged, but still forwarded to the
backend server.
The routing to one backend or another can be based on URL Paths:
You can find an example of this configuration in this related Microsoft article.
In your use case, you will need to define two backends, one for every App Service, and define routing rules as appropriate.
As indicated before, your DNS should point to the Application Gateway: it will handle the routing to one or other App Service based on the route, /eu/* or /*, provided by the client.
The order of the routes is important: once a rule is matched, it will be the one processed.
Application Gateway is a regional service: Azure Front Door leverages a similar functionality (and much more) globally.
Please, consider review the associated costs of these services.
I am answering my own question to hopefully help others in the same situation. This was simply done using a reverse proxy. This article explains everything you need to set it up - https://ruslany.net/2014/05/using-azure-web-site-as-a-reverse-proxy/

How to choose a specific backend VM using Azure Application Gateway path based routing rule

In a web application deployed on several Azure VMs, load is balanced using Application Gateway. The selection of Application Gateway is mainly because the application requires cookie-based session affinity.
For a function in the application, a specific VM in the Backend Pool needs to be chosen. So I think giving the user a different login page URL could help me route things properly.
I've tried using different rules, but since a listener can have only one rule this doesn't work in my case.
What I want to achieve is:
https://myapplication/mycontext
Balanced between all the VMs
While https://myapplication/mycontext/process
Directed to a specific VM
Path rewritten to https://myapplication/mycontext
What should the configuration of a Path-Based Rule be to achieve this behavior?
You would need to create 2 backend pool, one to server all content (A) and one specific pool for /process requests (B).
Create a path based rule, a default rule to forward /mycontext/* to the backend pool A
another rule to forward /mycontext/process/* to another backend pool B.

Azure Application Gateway, Azure App Service and Form Based Authentication

I'm migrating a complete infrastructure over to Azure; it's been slow going as there's so much to learn and for every two steps forward, there seems to be one step back.
After what seems like an eternity, I think I've got it all sorted with one exception.
The architecture is as follows:
Azure Traffic Manager ==> 2 Azure Application Gateways (geo separated) ==> Azure App Service
A custom domain is used for the traffic manager and the gateways are listening for the same domain and, when the route matches, passing on the requests down to the app service.
The actual app itself is a ASP.NET MVC application and it uses forms authentication; and this is where the challenge happens.
When navigating to the public address: client.domain.com and hitting the website, it determines that the user is not authenticated and sends the browser to the login page... so far so good but, rather than using client.domain.com/login it uses the web-server dns name, so client.azurewebsites.com/login
How do I go about changing the behaviour so that it uses the external DNS name rather than the website name?
I can't setup custom domains on the app service as the only route into the site is via the gateway as this is also the firewall.
Is there some Web Config setting I can make? I'm looking at the outbound rewrite rules but these seem to only work on tags rather than 302 redirects.
Any thoughts would be most welcome.
You need to setup custom dns names on your webapp (you can use TXT record to verify dns name, so i dont see a reason why you can add it to the webapp). or you can alter the code.
In order to solve this problem, I had to make a code change to the web app itself. Not ideal but it worked.
What I had to do was to extend the code that redirects an unauthenticated request to the login page by sniffing for the X-Original-Host HTTP Header that the App Gateway forwards on. This contains the public facing DNS name. If the header is present and it is on a pre-approved white-list (so as to prevent any hijacking), then redirect the user to the login page for this domain, rather than the one the server is listening on directly (so use client.domain.com rather than client.azurewebsites.com)

Cloud foundy - Discovering backend application without public route

I'd like to implement micro service architecture on CF (run.pivotal.io) and have problems with creating my private backend services.
As I see I have to options at deployment: with and without route.
With route my services becomes public which is ok for my public site and my public REST API, but I don't want it for my backend services.
Without route I don't see how should I do service discovery.
What I found already:
Use VCAP_APPLICATION env variable and create my own service discovery (or use something like Eureka) based on that. Does this give me always a valid IP:PORT? No matter what DEA my app is running it is reachable on this IP:PORT by other apps on other DEAs?
Register my backend app as a service and bind it, than use VCAP_SERVICES. I'd like to do this but only found documentation about registering services outside CF. Is there a simple way to bind my own app as a service?
So what would be really nice is to be able to mark an app as private but still assign a host and domain to it, so (only) my other apps could call it though CF load balancers but it would be protected from the public.
Answers inline...
As I see I have to options at deployment: with and without route.
This depends on the Cloud Foundry installation and how it's configured. On PWS, you cannot talk directly between application instances. It's a security restriction. You have to go through the router.
With route my services becomes public which is ok for my public site and my public REST API, but I don't want it for my backend services.
The best you can do here is to add application level (or container level, if you prefer) security to prevent unauthorized access.
If you don't want to do password based authentication, you could do IP based filtering. On PWS, we just added a service with Statica. You can use that to send your outbound traffic through a proxy which will assign a static IP to that traffic. You could then restrict access to your app to only the Statica IPs.
Without route I don't see how should I do service discovery.
If you remove the route, you can't sent traffic to the app.
Use VCAP_APPLICATION env variable and create my own service discovery (or use something like Eureka) based on that. Does this give me always a valid IP:PORT? No matter what DEA my app is running it is reachable on this IP:PORT by other apps on other DEAs?
You'd probably need to use this enhancement. It was added to support this type of deployment. However this will only work on Cloud Foundry installation where the networking restrictions between application instances have been relaxed. Normally you cannot talk directly between instances.
Register my backend app as a service and bind it, than use VCAP_SERVICES. I'd like to do this but only found documentation about registering services outside CF. Is there a simple way to bind my own app as a service?
You can create a "user provided" service. Look at the cf cups command. It lets you create a service with an arbitrary set of parameters and data. This could contain the URLs for your services. Once you create the service, you can bind it to any number of apps.

Resources