How to Design a Stable Application Delivery Process

stable application delivery process

How to design a stable application delivery process? Provides the possibility to normalize the process of continuous delivery, but also to introduce the trouble of people burying themselves in the hills of configuration files from time to time. We might as well start with a slightly twisted and hidden integration deployment case to see how to design a more stable application delivery process.

AppStack for cloud effect application delivery . Deploying applications to various environments, performing integration testing step by step, and finally releasing them to the production environment is an indispensable part of the programmer's work; while the containerization and IaC (Infrastructure as Code, Infrastructure as Code ) introduced by cloud native technology Code) and other technologies and concepts provide the possibility of standardization for the process of continuous delivery, but it also introduces the trouble of people burying themselves in the hills of configuration files from time to time. We might as well start with a slightly twisted and hidden integration deployment case to see how to design a more stable application delivery process.

stable application delivery process.A twisted deployment


After many iterations, facing the crunching assembly line with the fans, programmer Awei would recall the not-so-distant afternoon when the system was deployed to the pre-release environment, submitted for the final round of acceptance, and then called back. At that time, he had a cool Java SpringBoot application to be launched, and implemented the cool interface of "sending business messages with environment routing labels in different deployment environments":

The image construction, deployment, and acceptance testing of the daily environment were all OK, but after building and deploying to the pre-release environment again, Awei found that the message was lost: the consumer in the pre-release environment did not consume the message. After a series of investigations, regardless of whether the screen is black or white, it is a good screen. It is found that the problem originates from the missing routing.env property in the SpringBoot configuration file application -staging.yaml used in the pre-release environment, and the missing attribute is used when the application is started. Provincial configuration of the bottom value in application.yaml causes the message tag to be wrong.
The specific problem has been solved, but it will leave some concerns: when writing configuration items in the future, it is inevitable to repeat the diff to see if there is something missing, and will it cause the products in each environment to have subtle structural differences and cause bugs... …
Potential problems with old delivery methods
Still taking SpringBoot applications as an example, some developers use ideas like the following when migrating applications from traditional virtual machine deployment to containerized deployment on Kubernetes :

framework provides a mechanism to write different application.yaml configuration files for different environments to achieve the effect of differentiated deployment of environments. It is not difficult for us to frame the protagonist of the short story, Awei, who also uses a similar idea:
● Use application.yaml to provide the common (and part of the bottom line) configuration of all environments;
● The differentiated configuration of each environment is given by a separate application -xxx.yaml , covering the bottom line configuration; each differentiated configuration does not require special specification requirements, allowing Attribute values are different, and it is also allowed to introduce attribute values unique to a certain environment;
● Write different Dockerfiles for images in different environments. The difference in environment configuration is mainly in the parameters specified when starting the application.
A typical project directory looks like this:

It looks neat, but it actually introduces some problems:
● The differentiated configuration of the environment needs to be checked manually to reduce errors and omissions. When writing a benchmark configuration such as application.yaml , it is also necessary to carefully consider what kind of bottom-line value to provide. Once there is an error, the troubleshooting cost is relatively
high ; Differences, but the built products are strongly bound to the specific environment and cannot be reused; multiple compilations may cause some hidden dangers (the most typical example, such as the dependency version is not strict), resulting in inconsistent delivery content in different environments. The risk of introducing bugs and incurring online issues.
○ For example, after the construction is completed in a daily environment, a (possibly indirectly) dependent snapshot package is updated (it may be an irregular snapshot package update, or a security package and other choices tend to make the access party feel indifferent. upgrade and use the snapshot version as release); when deploying to the pre-release environment, the build refers to the new version of the dependency package, which reduces the credibility of the test acceptance conclusion in the daily environment.
Considerations for a single-application environment-by-environment upgrade plan
We can help Awei's application release plan to list the following considerations :
● The product is neutral to the environment: the differentiated configuration of the environment is injected during deployment, and one image can be used for deployment in all environments.
● Unified environment configuration: All environments use the same format of configuration templates and differentiated value injection to avoid the differences in configuration templates introduced by "background + coverage".
Specifically, in the entire integrated release process of "daily-pre-release-production", only one mirror and orchestration are used; in the SpringBoot application in the mirror, only application.yaml is used , and no other differentiation is introduced. configuration.
This seems to limit some flexibility, but the core consideration is: it is usually difficult to standardize the specific format of configuration files and layout; once there is a situation of "one configuration bottom + multiple differential adjustments", understand the application code logic And the cost of deployment details will become higher, and the content required to maintain and verify the application logic will increase linearly with the increase of configuration files. Even the designer or owner of the application will inevitably forget some details (“Why did I add this environment variable at that time”) over time, not to mention other developers who are involved in the feature iteration in the middle.

When actually deployed to the Kubernetes cluster, the environment variables are injected through the environment variables of the container in the orchestration. The next step is to unify Deployment orchestration - using multiple orchestration files for different environments will still introduce meaningless duplication. Here we can use the form of Helm charts, such as images, environment variables, etc. that can only be determined when building and deploying differentiated configurations, which can be injected through the values configuration:

The part that needs to be customized is the script that dynamically generates the Values.yaml configuration in the CICD system. The complexity of this part is relatively easy to control, and the specific implementation varies slightly depending on the CICD tool used, we will see a rough example later.
Scheme modification example
Now it's time to go back to Ah Wei's service for a makeover.
Step 1: Unify application.yaml and Dockerfile
First, we need to compress the SpringBoot application yaml configuration in the service, leaving only one copy:

The placeholder ${DEPLOY_ENV} is used here , and the environment variable is required to provide the value of routing.env .
Dockerfile can remove all environment variable definitions for environmental differences, unify them into one configuration, and assume that the environment variables have been injected correctly.
Step 2: Write a Helm chart
Start by creating an empty helm chart:

Next, you can simply rewrite the original arrangement file according to the format of the helm template and place it in the cool-service-chart/templates/ directory. Take Deployment as an example:

We use the helm placeholder .Values.image to inject the image into the container. There are many ways to inject environment variables - when there are few variables, you can directly define the name and value in the pod template; however, if you consider the longer-term scalability, you can also use the separation of concerns to define a separate one. A ConfigMap is used to define environment variables; the advantage of this is that developers who add environment variables do not need to understand the specific structure of the Deployment, and even only need to understand " Write a key-value pair in the data definition of ConfigMap to achieve environment variable injection. "That's it.
Based on these considerations, we define the container to provide key-value pairs and inject environment variables using the following ConfigMap :

After the template in Chart is written, remember to push it to a git repository for later use.
Step 3: Write the Values.yaml generation script
After preparing the static template part of the Helm chart, you need to script the deployment-time generation of Values.yaml for the CICD tool . Let's assume that Awei's team chooses to use Jenkins to build the CICD pipeline:

Here we mainly focus on chart-complete.sh, which needs to complete the following tasks:
● Clone the trunk of the chart library from the git repository;
● From the environment variables, generate values.yaml .

If the helm warehouse has been built, you can also choose to push the generated chart to the warehouse.

stable application delivery process.Summarize


In the process of upgrading and deploying a single application environment by environment , differentiated configurations customized for the environment are often involved; in order to avoid the governance costs and bug hidden dangers caused by redundancy such as Dockerfile and configuration files, we can take advantage of cloud-native IaC . Based on a unified artifact and orchestration definition, the differentiated configuration items of the environment are delayed to be injected at deployment time. In this way, the code deployed in each environment is completely consistent, which improves the integration reliability and testing efficiency.
Of course, building a CICD system from scratch often requires a certain amount of trial and error; cloud effect application delivery AppStack provides orchestration management, environmental governance and differentiated configuration capabilities in line with the aforementioned practices, and can quickly build an entire upgrade by integrating the cloud effect pipeline Flow process, you are welcome to try it. If you get something, give it a like !




Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00