How to manager multiple components in CD - continuous-deployment

We have a use-case where we have multiple components which get deployed. Most of the components are independent of each other and can have there own CD pipelines. But some of the component are dependent and is there any best practice to handle these situations.
My use case is that I have a API service which can be deployed independently. Now there is a front end application which consumes that API. There is a new change in both the API and front end application. Hence they need to be deployed togather and if required rolled back togather. How to define the CD process for such changes. Are there some best practices or ways to handle such situations.

I would suggest the following strategy. Let's suppose you need to develop and deploy a new feature that requires changes in the service and in the frontend.
You develop the feature in the service first in a backward compatible way. It means that you can add a new API, but not introduce any breaking change. Then you deploy that backend service using your CD pipeline.
Then you develop the feature in the frontend component. At this stage you may test it against your production service. Then you can deploy your frontend using your CD pipeline.
Following this flow you can continuously deploy any feature in your components.

Related

Is there a way to dynamically inject sensitive environment variables into a serverless React frontend application using Azure/Github Actions?

I'm sort of restricted to Azure since that is what the client is already using.
But basically, we have this React website which is your typical react-scripts no server website, which means that there's nowhere in Azure Static Webapps to set environment variables for a frontend application.
I saw this on Azure Static Webapps Configuration, but subject to the following restrictions, won't work for my use case because there is no backend API for my frontend application - the backend associated with the frontend is published separately to Azure App services. And I need the secrets on the frontend to use some npm packages that require them, which I would prefer to do on frontend instead of backend.
Are available as environment variables to the backend API of a static web app
Can be used to store secrets used in authentication configuration
Are encrypted at rest
Are copied to staging and production environments
May only be alphanumeric characters, ., and _
I was doing some more research, and this seems to sort of be up the alley of what I'm looking for:
https://learn.microsoft.com/en-us/answers/questions/249842/inject-environment-variables-from-pipeline-to-azur.html
Essentially, I really want to avoid hardcoding secrets into the React code because that's bad practice.
I personally see a few different (potential) options:
Create an endpoint on the backend Spring Boot api that simply serves all environment variables
This is the most trivial to implement but I have concerns about security with this approach. As my frontend has no access to any kind of secrets, there's no way for it to pass a secure token to the backend or anything to authenticate the request, so someone could conceivably have chrome network inspect element tab open, see that I'm making a request to /getEnvironmentVariables, and recreate the request. The only way I can see to prevent this is to have IP restrictions enacted on the backend API, so it only accepts incoming requests from the IP address of my frontend website, but honestly that just sounds like so much overhead to worry about. Especially because we're building the product as more of a POC, so we don't have access to their production environments and can't just test it like that.
Have the Azure Static Webapps Github Actions workflow somehow inject environment variables
So I've actually done something similar with GCP before. In order to login to a GCP service account to deploy the app during continuous build, the workaround was to encode a publicly viewable file that could be freely uploaded to whatever public repo, which could only (realistically) be decrypted using secrets set on the CI/CD pipeline, which would be travis-ci, or in my case, Github Actions. And I know how to set secrets on Github Actions but I'm not sure how realistic a solution like that would be for my use case because decrypting a file is not enough, it has to be formatted or rewritten in such a way that React is able to read it, and I know React is a nightmare working with fs and whatnot, so I'm really worried about the viability of going down a path like that. Maybe a more rudimentary approach might be writing some kind of bash script that could run in the github actions, and using the github actions secrets to store the environment variables I want to inject, run a rudimentary file edit on a small React file that is responsible for just disbursing environment variabless, before packaging with npm and deploying to Azure?
TLDR: I have a window in github actions when I have access to a linux environment and any environment variables I want, in which I want to somehow inject into React during ci/cd before deployment.

Should I develop a separate express server, or handle all API calls in my next.js app?

My website will perform CRUD operations and will work with MongoDB and Firebase storage+auth.
What are the reasons / advantages to developing a separate Express server instead of integrating everything in my next.js app?
As far as I have seen, it can all be done in my next.js app, but I still see many projects working with a separate server.
Depends on what your app does and how you are hosting it.
Running Next.Js on a standard server will be of little difference whether you are using nextjs's /api or expressjs.
However if you are hosting on serverless (e.g. Vercel), I would recommend using a separate express server if you have alot of CRUD operations because the warming up of serverless is really bad user experience.
Build and Deployment
Next/JS - If you want to edit something on the backend, and push the changes, it will require you to build the entire JS app, and depending on how big is your app, it can take alot of time (especially if alot of static generated pages).
Express - If you running express separately, you can build and deploy front end and backend separately. It's time saving, and you can also better organise your codes frontend/backend.
Choice of deployment
I have a choice to take advantage of Vercel to host my frontend, with static generated pages and some server side generated pages (automatic scaling, caching, CDN etc), and host my backend with a separate cluster of servers.
PS: I moved from single Next.JS app to NextJs+Express
I can think of a few things why they would have a different server from the one NextJS provides:
Familiarity with Express, Koa, etc. All next-connect helps with this
There is an already existing API in PHP, Express, Flask, etc.
It is literally based on what you would want to do, the extra interactions with MongoDB & Firebase would be same on both the technologies, unless you want to isolate respective things separately, I don't see any harm in doing everything together on next.
Given that the idea of using next.js, as per my understanding would be to utilise server side rendering.
I've been using Next.js with Typescript for quite a while now and I, as of now, have found one reason not to include express.js in my project. And the reason is Vercel.
Since I use Vercel for continuous deployment of my projects, and Vercel Not supporting any custom server as of there Docs here, I refrain from using Express or any other custom servers.
I didn't face any problem performing CRUD operations with MongoDB, can't say about firebase.
On Next.js Docs, I found these points to be considered:
A custom server can not be deployed on Vercel, the platform Next.js was made for.
A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.
But at the end of the day it very personal opinion weather to use a custom server or not. It might depend on a very specific use case you might be looking for.
Personally, I try to keep it to just NextJS, but if I have to manage real-time data with Socket.io, I get a separate server because other than WebSockets, serverless functions can do everything else.

Is it possible to configure React application to use container's environment variables in Kubernetes?

To begin with - let us suppose we have a React application. We want to build it and deploy to 3 environments - dev, test and production. As every front-end app it needs to call some APIs. API addresses will vary between the environments. So they should be stored as environment variables.
As every modern, progressive developer we want to use containers. In particular Kubernetes.
We want to build our web application and deploy it on K8S cluster. The container image should be built and kind of sealed for changes, then before deployment to each particular environment the variables should be injected.
But it seems there's one great impossibility here. When it comes to .NET apps for example, when we have .dll compiled, it reads a config file in the runtime. It's not a case with React. After we generate build we have just static files. The variables are changed to static values in the process of building React app. It seems there's no way to update it after that point - or is it?
The way you are trying to solve your problem is not correct.
You don't need to know anything about the addresses of the backend services in your react app. Only the frontend server/gateway that is serving your react app needs to know about the backend services. Any request from the react app should be proxied via the gateway.
See API gateway pattern - https://microservices.io/patterns/apigateway.html
You can use config map to store the API endpoint address and refer it as environment variable in the pod.
If you want to change some values while the pod is running you can mount the config map and any change to it will be synced in the pod

Moving Instances Across Projects in Google App Engine Projects

How do I move instances from one project to the next?
Problem: I have frontend production instance and backend production instance in 2 separate project. I would like to have my production instances (both frontend and backend) in the same project.
How do I move instances from one project to the next within Google App Engine?
You could have the 2 apps run as 2 separate services inside the same project. To do that you'd have to deploy the app from the project that will disappear as another service in the project that will remain. Some code changes might be required, depending on how the app is coded. Typically they're small changes, though.
IMHO it would be simpler to keep the project currently hosting the frontend and move the backend over from the project to be retired. The reason is that the frontend is typically better fitted to play the default service role and it is already setup as such, changes should be smaller. Performing the move in the other direction would mean both services would need to changed.
You might need a dispatch.yaml file to route incoming packets, unless the URL mappings of the services are really well done. Not a big deal.
If you're using custom domains, with a bit of care it is possible to make the move (almost) transparent - by having the new service up and running before retiring the old project. DNS propagation time becomes rather irrelevant - both old and new services being simultaneously ready during the transition.
Note: technically you wouldn't be "moving" instances, you'd just stop the ones serving the project to be retired and start new ones for the service added to the project to be kept.
More or less related:
Change runtime from Python to Go in App Engine standard environment
Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

.net core, angular and application settings

We currently have our API set up in azure and use deployment slots which each have their own app settings. For example, on our live slot we set our connection string to the live database. On our dev slot we set the connection string to the test database.
So, I have been tasked with doing something similar with our SPA. I created it using .net core and angular. Currently it has a constant set up:
.constant('apiUrl', 'https://ourlive.api.com')
I have a few set up and I just comment out the ones I am not using. What I have been tasked with, is putting these into the application settings and using deployment slots for different URLs. For example, the live slot will use the Live URL and the Dev slot will use the Dev URL.
I read that you can do this using npm but this isn't an option for us because we are using .net and the npm doesn't seem to work like that. Is there another way we can read the application settings?
Per my understanding, your scenario is a purely HTML + angularjs SPA, although they are running in a .NET core runtime. And your requirement is that you want to get the slot application settings in your SPA application. If I have any misunderstanding about your structure, please feel free to let me know.
You can try to leverage the .net core runtime to get the application settings in slot, and expose as an RESTful API for your SPA application.
And in your SPA application, you can create a server, to call your .net core's API, and you can inject this server and call this api when your SPA bootstrap in and keep the settings in $rootscope for your entire SPA application.
For slot application settings, you can refer to https://learn.microsoft.com/en-us/azure/app-service-web/web-sites-staged-publishing#configuration-for-deployment-slots for more info.

Resources