In this tenth post in my CloudFoundryFun series, we will reuse an application that we build previously. But this time, we only deploy selected modules and resources of the application to Cloud Foundry.
Mono-repo vs Multi-repo
If you are coming from “vanilla” Cloud Foundry, you might be more familiar with
cf push than with
cf deploy. The first command uses a
manifest.yaml descriptor as a source for information about the project. This descriptor defines the runtime of the applications and the service bindings, but not the service instance definitions. This means the service instances need to be created manually. If you’ve been following this series, you might have noticed that I’m a big fan of the
mta.yaml project descriptor. Besides the runtime definition, this descriptor can be used to define build tasks. Besides, it contains all definitions of your modules (aka microservices) and resources (aka backing services). Overall, this descriptor makes it very easy to use the Mono-repo source control pattern for your project.
The mono-repo pattern means that your entire codebase lives in one single repository. Multi-repo, on the other hand, means that each module is being managed in a single source control repository. In this latter approach, all models can be referenced by a “master repo”. I don’t want to go deeper into the advantages and disadvantages of either approach as this would be enough content for another post. If you’re interested in this, I recommend this 8-minute long video from Uber Engineering on their experience with mono-/multi-repos.
Sometimes less is more
A possible downside to this
mta.yaml approach is that the build process outputs a single file (the
.mtar archive). This meant that we had to deploy all modules and resources for every single update. It’s no surprise that this takes more time than redeploying only one module.
Sometimes, you might just want to update a single module because you already know the other did not change. For a long time, I thought that I had to bite the bullet, but then someone pointed me to this comment on GitHub. It turns out that there already is an option in the cf deploy command which allows us to do partial deployments. 💪
In this post, I want to show you how partial deployments work.
This application exposes a list of sample entities that represent cities. Each entity contains several properties, like name, region, and an image. The user can navigate to a Fiori Object Page and replace the default image with a newly uploaded file. This file will be stored in an Azure storage account and the URL that references the image will then be stored in a table within HANA.
The project contains the following modules:
Application router module The entry point of the application which redirects all incoming traffic to the following two microservices. This module also contains the source code of the Fiori Elements user interface.
Server module Connects to the HDI container and exposes the annotated OData service via HTTP
Uploader module Service to upload files to the Azure storage account that returns the URL to access the created resource.
Database module A Cloud Foundry tasks that will run once to set up the schema in the HDI container and to import the sample data. Once these steps are completed, the app will shut down and stop consuming memory and CPU quota.
Besides the modules, this sample app leverages two backing services:
SAP HANA service SAP Cloud Platform provides HDI containers to allow apps to efficiently store business data in a state-of-the-art in-memory database. This datastore is used for structured data.
Azure Storage Account This service is provided by Microsoft to store large files (also called Blobs). We will use this store for unstructured data. During deployment, this service will be provisioned by the Azure Service Broker.
Let’s assume we want to run this application in a Cloud Foundry environment where there’s no Azure service broker set up. E.g. we won’t be able to provision a storage account during deployment.
In this situation, we only want to deploy the components that we can test in any Cloud Foundry environment. Therefore, we not only skip the creating of the backing service but also skip the Uploader app (as its sole purpose is to connect to the Storage account):
This is the shortest hands-on of this series so far.
- Clone the repository.
git clone https://github.com/SAP-samples/cloud-foundry-cap-azure-cities
- Build the .mtar archive that contains all modules and resources.
npm run build:mta
- Only deploy the modules we need.
cf deploy mta_archives/city-explorer-demo-app_1.3.5.mtar \ -m city-cap-router \ -m city-cap-db \ -m city-cap-srv \ -r city-hdi-container #For Windows users cf deploy mta_archives/city-explorer-demo-app_1.3.5.mtar ^ -m city-cap-router ^ -m city-cap-db ^ -m city-cap-srv ^ -r city-hdi-container
- Test the application. (Please keep in mind that the image upload feature will fail as the upload app is missing)
Are you looking for more samples? The GitHub repo might also be very interesting to you!
In this edition you have learned:
- What a mono-repo is
- What differentiates a
manifest.yamlfile from a
- What benefits partials deployments bring
- How do a partial deployment to Cloud Foundry
About this series
|This was the tenth blog post of my monthly new series #CloudFoundryFun. The name already says all there is to it, this series won’t necessarily be about building enterprise apps on Cloud Foundry. I think there are already plenty of great posts about those aspects out there. This series rather thinks outside the box and demonstrates unconventional or novel Cloud Foundry use-cases 🙃.|