Microsoft and MTI conducted a joint Hackfest to introduce DevOps practices into Dev and Ops team of MTI’s software ‘Life Ranger’. The DevOps practices we implemented are:

  • Basic DevOps practices
    • Continuous Integration/Continuous Delivery (CI/CD) with Visual Studio Team Services
    • Test Driven Development
    • Automated Testing
  • Advanced DevOps technologies
    • Azure Service Fabric
    • Spring Circuit Breaker
    • Azure Container Service

Core team:

Hackfest member

  • MTI
    • Team1: Automated Build
      • Tomoaki Kaneko
      • Yoshihiro Sato
      • Yumi Takeda
    • Team 2: Service Fabric
      • Shuichi Kaneko
      • Manami Yanase
      • Yuuki Shirakawa
    • Team 3: Front-end Java web page
      • Tetsuro Yamada
      • Akihito Takahashi
      • Tatsuo Mochiduki
      • Koei Ri
  • Microsoft
    • Tsuyoshi Ushio
    • Yoshio Terada
    • Miho Yamamoto
    • Junichi Anno

Each team was responsible for each technical investigation, and all did the implementation.

Customer profile

MTI Ltd., is a company engaged in mobile content business for mobile phones, headquartered in Shinjuku-ku, Tokyo. MTI provides a range of services through mobile sites and apps that make user’s life more fun and convenient, covering music, healthcare-related, e-books, lifestyle-related information, entertainment and more. The number of paid members of MTI reaches 5,569 people in 2016. The profit of MTI has significantly expanded (operating income of 5,355 million yen in 1996, +1,110 million yen of the previous term).

Their representative services are:

  1. Music.jp, music site for users of smartphones and other devices. It offers downloads of a huge range of tunes, for listening to the latest in J-pop and overseas hits, through to golden oldies.
  2. Luna-luna, health information site for women, and is just one example of the healthcare-related support provided by MTI. Numerous free health devices and data are freely downloadable to users of all sexes and ages.
  3. Life Ranger, a service specialized in providing information that affects the lifestyle of users. For example, suppose a user moves from home to a company. The necessary information at that time will be traffic information, car navigation, weather forecast, and so on. The value of Life Ranger is not to provide these pieces of information alone but to correlate with each other, to be confirmed at one time on one site.When a user uses a train, it not only provides a transfer guide but also provides delay information, etc. at the same time. It is the weather information that they are putting particular emphasis on them. Weather information has a great influence on activities of the day. It is possible to easily check not only wide-area weather forecast but also local weather information of the place where the user stands now, change of weather and temperature at each time, radar information of rain cloud, various warnings and disaster information. Also, they are also devised to provide a lifestyle fan element to their service, such as enjoying a mini-game in the train waiting for time and processing photographs taken while traveling on the spot.

MTI’s services

“Life Ranger” is the target service of this Hackfest.

Life Ranger screenshot1

Life Ranger screenshot2

Introduction

Since its establishment in 1996, MTI has continued its content distribution business. Their business has expanded with the mobile market. With the diversification of needs, content has diversified, and systems and networks that support the business have gradually become bloated. The structure of the system has reached the present without substantially changing from the original design, and as a result, it is a system which is commonly called “monolithic” system. Early members who know the internal structure in detail do not already exist, and new members formed several years ago are transitioning gradually to the new system. However, the server structure of the old system and the complex intertwined program structure are hindering dramatic progress.

Other companies also hold the same troubles. Their theme is how to keep changing the monolithic system that has been accumulated, built, and has been growing for many years, with speed.

At the beginning of this Hack Fest, the team was thinking of trying to improve efficiency by applying basic DevOps practices to the current system. However, in the long run, there was concern that the current vast and complicated system structure would hinder the introduction of DevOps. Therefore, we aimed not only to introduce basic DevOps practice but also to divide service by application of micro service and simplify system structure.

Overview of their service

The system architecture of “Life Ranger” is shown below.

system overview

“Life Ranger” is one of the representative services of MTI and began in 2005. Although this service was initially developed to distribute weather information, it has continued to incorporate finely-tuned, regionally rooted functions according to market needs. As of 2017, more than 100 kinds of services are released. Developers are feeling a vague concern about the current huge project. Because there are no engineers, who have an accurate grasp of the overall picture of assets accumulated over ten years. To solve this problem, they continue to renovate the source code little by little and renew the environment. However, they felt uneasy about whether the current work is the correct direction for completely revamping a complexly intertwined system like spaghetti.

Currently, their services are provided by dozens of virtual machines. Each virtual machine is made up of CentOS + Java, and SQL database exists as an information store in the back end of each. Both are built on Azure.

Components they are using are as below.

  • Azure Virtual Machine(Cent OS/Windows Server)
  • Apache Maven V2
  • Zabbix
  • SQl Database
  • C#、Java V7、Perl
  • Visual Studio Team Services

Value Stream Mapping

MTI’s Life Ranger Division is a very active company for process reform. At the time of the first visit, the Value Stream Mapping by themselves has already been completed, and it is in a state that it can see some problems. The challenges presented by them are as follows.

  • They practice Scrum, but members are not very enthusiastic. The reason is that they can not understand Agile’s intention correctly. Also, because the planning department’s voice has a big voice, even if it is a testing process, an addition of functions may be forced, so in fact, the goodness of the scrum can not be fully utilized.
  • CI has not been realized. Manual integration.
  • Both unit test and integration test are performed manually
  • There is a difference in cultural differences from offshore and communication.
  • Because it is used for many years, the system configuration is considerably complicated, and it is not easy to modify. Therefore, the environment can not be changed. Java patches can not be applied either.
  • Because the development environment is prepared each time manually, incompatibility may occur.
  • Windows Update of the production environment is done by infrastructure team manually.

Based on the above, the result of implementing Value Stream Mapping again is as follows.

VSM by MS & MTI VSM result

  • Step1 Design & Coding
    • LT 6.5 Days, PT 6.5 Days
  • Step2 Unit Test
    • LT 3 Days, PT 2.8 Days
    • manual testing
  • Step3 Integration Test
    • LT 10.1 Days, PT 4.7 Days
    • manual integration, manual testing
    • At this stage, the sales side participates in the road test. Therefore, rework due to the design change of the UI or the like often occurs.
  • Step4 Release
    • LT 0.1 Days, PT 0.1 Days
    • manual release work
  • Total
    • LT 20 Days, PT 15 Days( work efficiency 75% )

The overall work efficiency is 75%, and it can be said that there is little waste regarding this point. However, if we check the process of work in detail, there are some points to be improved.

First of all is automated testing. Since all the tests are performed manually, it is possible to shorten the work time by about seven days only by automating the test.

Secondly, it is reducing integration test time. There are two reasons other than the manual test for causing the integration test working hours to prolong. The first one is a “monolithic” system. Since one service is tremendous, conflicts between functions are likely to occur, and it takes much time to adjust and create integration tests. The second problem is intervention in the testing of the sales/planning department. In the current release process, it can not be released unless approval from the sales/planning department is obtained. If communication is not successful beforehand, corrections will be made by the sales department pointed out immediately before release. When correction occurs, the “monolithic” mentioned earlier produces a vicious circle that further reduces efficiency.

According to the MTI side story, the most stressful thing currently is enormous and black boxed system. Even if they introduce automatic testing and automatic release mechanism, it seems that it ‘s hard to implement a reliable pipeline due to the influence of the current monolithic system.

Based on the above, we decided to include not only the automated pipeline but also the redesign of the existing system using microservices in this Hackfest.

Another point, there was a problem they wanted to solve in this Hackfest. That’s Seasor 2.

They had been providing mobile application service for a long time. In this application, they had been developing Java Web Application which used the Japanese Web Framework as Seasor2. Recently the Framework had finished their lifetime support. So the company must consider to migrate or transfer other technologies like C# or another Java framework. In fact, they are considering to migrate C# instead of Java. However, they already have a lot of Java libraries wrote by Java.

So at first, they would like to provide the combined services both C# and Java. After that, they would like to migrate all of the services to C#.

Thus they need to try to DevOps, Microservices with C# and Java modern framework.

Scenario of this Hackfest

In starting Hackfest, they picked up two functions from Life Ranger. Each service is to encourage users to go out for leisure.

  • Flower information service(Flower blooming information service)
    • This service provides flower type and blooming information for each area.
  • Festival information service
    • This service provides festival information throughout Japan.

The goal of this Hackfest is to make these into microservices using the Azure Service Fabric.

The Introduction of TDD and implementation with MSTest project

At the first of Hackfest, we introduced Test-Driven Development and had a mini hands-on session. We used This contents posted on SlideShare. They can learn test-driven development based on program development to calculate the score of bowling by this contents. Bowling is a game everyone knows; rules are well known. The most difficult thing for beginners in test-driven development is to make future predictions and test code creation at the same time. The skill of “predicting the future of the code” is gradually acquired and is to be polished. I wanted to focus on “writing test code” this time, so I wanted to save as much as possible the “predict future of code” part. On that point, this content motif is familiar boring; you can easily predict the appearance of future code, you can concentrate on writing test code.

Through this mini hands-on, they could understand “Test code and function code can be developed at the same time.”

mini TDD hands-on

DDD modeling session for Microservices

They had no idea which part they can decompose into microservices. We discuss which parts is separated from other services. We analyze their current website and find out two candidates for that.It was “Festival” information and “Flower” information pages.

Studying the structure of ddd modeling

Then we analyze it using Domain Driven Design (DDD) related technique. We model the domain structure and relationship among them. We read the legacy code and database schema. We modeled it using sticky note then draw a line if they have relationships.

We identify “Festival” related domains and “Flower” related domains. They didn’t have many dependencies outside this domain. We draw the boundary context using a marker and decide the granularity of Microservices. This process is quite simple. However, this technique is used for legacy migration from COBOL to Java. We arrange this for microservices.

To adopt Microservices

To move and transfer to the Microservices, they need to understand the Microservices architecture. So during this Hackfest, Yoshio explained the design pattern of the Microservices at the Java Application point of view.

Yoshio lectures about Microservices

Divide the current architecture to Microservices

The current design architecture was monolithic and tight to services to services. To create the Microservices. We used Front-End for Backend design pattern to create the system. In fact, we could divide front end and back end services. For Front End Service which is called “Matsuri (Festival)” and “Kaika (Blooming).” For Back End Service which is called “API Service.”

And we decided to implement as follows:
Front End Services: Java Spring Boot Framework
Back End Services: C#.Net Framework

system architecture

For Front End Service

To create Front End Microservices by Java, we had done following.

  1. Create Spring Boot Application
  2. Create Docker Image on local machine
  3. Create Azure Container Registry
  4. Push the Image to Azure Container Registry
  5. Build and run the Docker Image on Azure WebApp Linux (Preview)
  6. Implement Circuit Breaker by using Netflix Hystrix
  7. Create Azure Container Services

1. Create Spring Boot Application

To run the Java Application on Docker, we created very simple Spring-Boot Application.

@RestController
@EnableAutoConfiguration
public class MainApp {
    @RequestMapping("/")
    public String home(){
        return "Hello, World !";
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SpringApplication.run(MainApp.class, args);
    }
}

After creating the source code, we build and run the Application as follows.

$ mvn spring-boot:run
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building SpringBoot-Sample 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:1.1.8.RELEASE:run (default-cli) > test-compile @ SpringBoot-Sample >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ SpringBoot-Sample ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ SpringBoot-Sample ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/tyoshio2002/NetBeansProjects/SpringBoot-Sample/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ SpringBoot-Sample ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/tyoshio2002/NetBeansProjects/SpringBoot-Sample/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ SpringBoot-Sample ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< spring-boot-maven-plugin:1.1.8.RELEASE:run (default-cli) < test-compile @ SpringBoot-Sample <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:1.1.8.RELEASE:run (default-cli) @ SpringBoot-Sample ---
[INFO] Attaching agents: []
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.8.RELEASE)

2017-05-29 14:47:01.384  INFO 64803 --- [           main] com.yoshio3.MainApp                      : Starting MainApp on Yoshio-no-MBP.guest.corp.microsoft.com with PID 64803 (/Users/tyoshio2002/NetBeansProjects/SpringBoot-Sample/target/classes started by yoterada in /Users/tyoshio2002/NetBeansProjects/SpringBoot-Sample)
2017-05-29 14:47:01.416  INFO 64803 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@33b37288: startup date [Mon May 29 14:47:01 JST 2017]; root of context hierarchy
2017-05-29 14:47:01.893  INFO 64803 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2017-05-29 14:47:02.509  INFO 64803 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2017-05-29 14:47:02.707  INFO 64803 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2017-05-29 14:47:02.708  INFO 64803 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.55
2017-05-29 14:47:02.801  INFO 64803 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-05-29 14:47:02.801  INFO 64803 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1387 ms
2017-05-29 14:47:03.295  INFO 64803 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2017-05-29 14:47:03.297  INFO 64803 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-05-29 14:47:03.426  INFO 64803 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-05-29 14:47:03.583  INFO 64803 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.yoshio3.MainApp.home()
2017-05-29 14:47:03.585  INFO 64803 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-05-29 14:47:03.585  INFO 64803 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2017-05-29 14:47:03.597  INFO 64803 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-05-29 14:47:03.598  INFO 64803 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-05-29 14:47:03.700  INFO 64803 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-05-29 14:47:03.763  INFO 64803 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2017-05-29 14:47:03.764  INFO 64803 --- [           main] com.yoshio3.MainApp                      : Started MainApp in 2.874 seconds (JVM running for 3.364)

After executing the above, we can access to the Application by using REST invocation as follows.

$ curl localhost:8080
Hello, World!

2. Create Docker Image on local machine

To run the Application on Docker, we created Docker image from Dockerfile as follows.

Dockerfile:

FROM FROM java:8-jdk-alpine
VOLUME /tmp
ADD ./target/front-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

After creating the Dockerfile, we build and tags to the images as follows.

Docker build, tag, push to Azure Container Registry

$ docker build -t mti/spring-backsvc:1.0 .
$ docker tag mti/spring-backsvc:1.0 privateregistrymti-on.azurecr.io/mti/spring-backsvc:1.0
$ docker run -d  -it -p 8080:8080 mti/spring-backsvc:1.0
$ curl http://localhost:8080/
Hello, World !

3. Create Azure Container Registry

After created the Docker Image on a local machine, they created the Azure Container Registry.

Azure Container Registry

4. Push the Image to Azure Container Registry

After created the Docker Container Registry, they uploaded the local Docker imaged to the private registry as follows.

Docker login to Azure Container Registry

$ docker login -u privateregistrymti -p =/++x+D+H=A/O==J/M/O+=nuxDYH9q=1 privateregistrymti-on.azurecr.io

Docker push to Azure Container Registry

$ docker push privateregistrymti-on.azurecr.io/mti/spring-backsvc:1.0

5. Create and Run the Docker Image on Azure WebApp Linux (Preview)

After uploaded the image, they created the Azure Web App Linux (Preview) and configured the images for deployed application.

Azure Web App Linux(Preview)

6. Implement Circuit Breaker by using Netflix Hystrix

After evaluation of Docker running on the Azure Web App Linux (Preview), they implemented the “Circuit Breaker” to invoke the backend services. After implement it, even though backend service down, continuously they could provide the services.

As a result, they noticed that it was very good opportunities for them to proceed the business even though some trouble had happened.

package jp.liferanger;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;

/**
 * Created by yoterada on 2017/03/03.
 */
@Service
public class CallBackEndService {

    //private final static String TARGET_URI = "http://springboot-docker.azurewebsites.net/";
    //private final static String TARGET_URI = "http://localhost:8081/";
    private final static String TARGET_URI = "http://liferangercluster.japanwest.cloudapp.azure.com:8241/";

    private final RestTemplate restTemplate;

    public CallBackEndService() {
        this.restTemplate = new RestTemplate();
    }

    @HystrixCommand(fallbackMethod = "failedInvokeBackEndService",
            commandProperties = {
                @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")
            }
    )
    public String invokeBackEndService() {
        URI uri = URI.create(TARGET_URI);
        return this.restTemplate.getForObject(uri, String.class);
    }

    public String failedInvokeBackEndService() {
        return "Cloud Connect to Backend Service";
    }

    @HystrixCommand(fallbackMethod = "failedInvokeBackEndFlowerService",
            commandProperties = {
                @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")
            }
    )
    public String invokeBackEndFlowerService(String flowerId, String spotId) {
        URI uri = URI.create(TARGET_URI + "api/flowerinfo/" + flowerId + "/" + spotId);
        return this.restTemplate.getForObject(uri, String.class);
    }

    public String failedInvokeBackEndFlowerService(String flowerId, String spotId) {
        return "Cloud Connect to Backend Flower Service";
    }

}

flower service with circuit breaker

7. Create Azure Container Services

After the evaluation both Azure Web App Linux (Preview) and Azure Container Service, they noticed that Azure Web App Linux is currently unable to restrict external access by IP Address and so on.

They want to make these services accessible by the user clicking the menu on the top page.

Therefore, this time, they decided to adopt Azure Container Service which can control access restriction flexibly.

azure container services

Back End Service (C#)

1. Service Fabric Cluster deployment

We deploy a Service Fabric Cluster from Azure portal.

The procedure is described in detail here and there were no special difficulties. As for the linkage with KeyVault, since the GUI of KeyVault was published at this time, it was easier to implement than the procedure by commandline written on this site.

KeyVault GUI

If you do not know well about Azure Key Vault, we recommend you to read the “Set up Key Vault” section of the site below.

Create a Service Fabric cluster in Azure using the Azure portal

The following is a quote from the above site.

Service Fabric uses X.509 certificates to secure a cluster. Azure Key Vault is used to manage certificates for Service Fabric clusters in Azure. When a cluster is deployed in Azure, the Azure resource provider responsible for creating Service Fabric clusters pulls certificates from Key Vault and installs them on the cluster VMs.

The following diagram illustrates the relationship between Key Vault, a Service Fabric cluster, and the Azure resource provider that uses certificates stored in Key Vault when it creates a cluster:

Diagram of certificate installation

2. VSTS CI/CD pipeline

We develop two services. “Festival Service” and “Flower Service.” Festival and Flower CI/CD is the same structure. I’ll show you the Flower pipeline.

2.1. Flower Front CI pipeline

We build the app and pack into the Docker images. Then push to the Azure Container Registry.

Flower Front CI pipeline

This is the container image names. We also check “Include the latest tag.” This setting enables us to increment the image version according to the BuildId of VSTS.

privateregistrymti-on.azurecr.io/mti/front:$(Build.BuildId)

2.2. Flower Backend CI pipeline

We try to follow the template of Service Fabric. However, it didn’t work. According to the message, I add “Delete files” to remove *.pdb file. It caused the error when we first try the Service Fabric template. Now it works.

Flower Backend CI pipeline

We also share PublicProfile related XML file via drop folder.

Flower Backend CI pipeline:Copy Files

2.3. Flower Backend CD pipeline

Then things easy. I just follow the Service Fabric template and deploy it.

Flower Backend CD pipeline

flower service on azure service fabric

Summary of Hack Fest

As a PoC, we can successfully develop three services include Java on Kubernetes and Service Fabric.

release architecture overview

Although it is just the first step, it works and mutually connected. We can separate git repo and CI/CD repositories using VSTS. We didn’t develop a lot. However, they try several resilient features of Service Fabric. They are excited about the Service Fabric cutting edge feature. Since this Hackfest is just three days, we are going to have the second Hackfest.

They enjoys developing service fabric

After the Hackfest

The first things they said after Hackfest are as follows.

“To be honest, we thought that Microservices are too difficult to introduce for us, but as a result of actually supporting Microsoft Evangelists, we could introduce microservices only in 2 days. We understood that Microservice is not an impossible option. Concerning the thought process and transition process as done in Hackfest, we saw a way to shift to the new system gradually. However, we seem to need to repeat trial and error a bit more about how to divide the service. In addition to the ease of maintenance and function expansion, I would like to devise ways to divide services, including those when our market needs to be changed.”

In this Hackfest, several practices could not be handled due to the reason of time. These will be implemented in future Hackfests.

  • AB testing
    • One of the issues that they have is “request for correction by sales department immediately before release.” As a means to eliminate such rework, AB test and other methods are considered.
  • Infrastructure as Code
    • Automate server maintenance such as Windows Update

after the fackfest

Resources