Recently I started blog series regarding FlexDeploy support of container native technologies. This is the second article in the series on what makes FlexDeploy a perfect fit for these modern trends in the industry:

Want to follow along in FlexDeploy? Check out our JumpStart Demo Lab configured with Oracle E-Business Suite. This is a pre-configured, friction-free environment in the cloud for you to try FlexDeploy with no set up, installation, or configuration.

Try the FlexDeploy Demo Lab

So, it’s time to follow up.  In this post I am going to show how FlexDeploy can enrich a very cool new product from Redwood Shores, CA.

Oracle guys are working nowadays on Container Native Application Development Platform. This is a set of cloud services to build, deploy, and operate container-native microservices and serverless applications. From the CI/CD perspective it provides the following services:

  • Oracle Container Pipelines. Basically this is a CI/CD tool which is called Wercker. It is available on the cloud, and the goal of this component is to fetch source code from a source management system. Let’s say GitHub, build the code, create a Docker image, push it to the Docker registry and deploy it to the Kubernetes platform.
  • Oracle provides its own registry which is called Container Registry. It plays the same role as Docker Hub,  just powered by Oracle.
  • The third component is Oracle Container Engine. This is a cloud based Kubernetes platform, where you can create clusters and deploy containers over there.

 

 

 

 

 

 

 

 

 

These components can be used all together as it is shown on the diagram or they can be used separately in combination with other products or Docker registries in order to build you own development platform. This is what I am going to do in this post.

I can live with Wercker as a building approach and I am totally fine with Oracle Container Registry, but I would like to enrich the deployment part. I want to leverage the full power of FlexDeploy Pipelines providing approval gates, test automation, scheduled events, manual steps and many other features that automate a complicated deployment process across environments. Having said that, we are going to implement the following scenario:

 

 

 

 

 

 

 

We will take a simple AngularJS application storing its source code in GitHub. Wercker is going to fetch the code, build a Docker image and push it to the Oracle Container Registry. Having done that Wercker is going to invoke FlexDeploy via REST API to create a snapshot referring to the new Docker image and deploy it with a pipeline across environments represented by K8s clusters hosted in different clouds. Actually, we are going to use the same FlexDeploy Pipeline as in the previous post.

 

 

 

 

 

 

 

 

Let’s have a look at the Wercker configuration. I have created an application and defined a workflow for it:

 

 

 

 

 

 

 

 

 

 

So, the workflow builds an image, pushes it to the registry and creates a snapshot with FlexDeploy. Once a snapshot is created, FlexDeploy automatically propagates it across environments. In Wercker terminology each part of this workflow is called a “pipeline” (that’s why Oracle Container Pipelines). Don’t mix it up with FlexDeploy pipelines. These “pipelines” are referring to sections in a yaml file which contains instructions on what actually should be done:

 

 

 

 

 

 

 

The yaml file has the following content:

box: node:6.10
build:
  steps:
    - script:
        name: A step that executes `npm install` command
        code: npm install  

push-to-releases:
  steps:
    # Push to public docker repo Container Registry (CR)
    - internal/docker-push:
        tag: $WERCKER_GIT_BRANCH-$WERCKER_GIT_COMMIT
        cmd: node /pipeline/source/app.js
       

deploy-with-flexdeploy:
  steps:
  - script:
        name: Create a snapshot
        code: |
              curl -d '{"environmentCode":$BLD_ENV, "qualifiedProjectName":$FLEXDEPLO_PROJECT, "streamName": $STREAM_NAME, "releaseName": $RELEASE_NAME, "authentication": { "userId":$FLEXDEPLOY_USER_NAME, "password":$FLEXDEPLOY_PWD }}' -H "Content-Type: application/json" -X POST $FLEX_DEPLOY_URL/rest/workflow/buildProject

Once the source code is changed in GitHub, Wercker executes its workflow and eventually invokes FlexDeploy REST API to create a snapshot.

 

 

 

 

FlexDeploy will take care of the rest from here. I have created a Release definition in FlexDeploy referring to a pipeline which is going to be used to deploy Docker image across environments.

 

 

 

 

 

 

The release contains a single project jscreditscore. The purpose of this project is to build a K8s deployment profile (*.yaml file) referring to a Docker image in Oracle Container Registry. This yaml file, which is actually a project’s build artifact, is going to be used by a deployment workflow to deploy the Docker image to the target K8s environment. The jscreditscore project uses a simple build workflow to create the yaml file:

The key role is played by the propertyReplacement step. It uses  propertyReplacement operation of the File plugin to replace placeholders in the yaml template file:

The name of the yaml template file is provided by a project-scoped workflow property DEPLOYMENT_TEMPLATE. This template contains a reference to a Docker image constructed with placeholders:

...   
spec:
      containers:
      - image: ${{DOCKER_IMAGE}}:${{FDBLD_GIT_SOURCE1_BRANCH}}-${{FDBLD_GIT_SOURCE1_REVISION}}
        imagePullPolicy: Always
        name: rest-jscreditscore-flex
        ports:
        - containerPort: 3000
          protocol: TCP
      imagePullSecrets:
      - name: wrelease
      restartPolicy: Always
...

After processing the file by the propertyReplacement step it will contain the exact reference to the image. E.g. :

...   
spec:
      containers:
      - image: docker pull wcr.io/efedorenko/jscreditscore:master-08e3421b5691119f3f326cb8955b2494c40929db
        imagePullPolicy: Always
        name: rest-jscreditscore-flex
        ports:
        - containerPort: 3000
          protocol: TCP
      imagePullSecrets:
      - name: wrelease
      restartPolicy: Always
...

The final step of the build workflow saveArtifact does what it is named for, it saves that yaml file as a build artifact, which can be consumed by the deploy workflow. So, when Wercker invokes FlexDeploy REST API it actually says “build jscreditscore project, create a snapshot for CreditScore Container Native release containing the build artifact (yaml file) and run a pipeline associated with the release”.  The pipeline uses totally same deploy workflow as in the previous post. The beauty of it is that it just needs a yaml file and a K8s context (environment-instance  property) where to apply this yaml file.

Summary

Having done that we have built a container native CI/CD pipeline on top of two solutions demonstrating how they can work together and enrich each other with their strong features.

That’s it!

Previous Post: FlexDeploy Loves Containers: Build and Deploy Microservices to Kubernetes clusters in the Cloud

Next Post: FlexDeploy loves Functions: Deploy Docker Containers with Fn Functions

Eugene Fedorenko

I have over 16 years of progressive experience in information technology with software design and development, testing and deployment of enterprise banking software. Graduated from Kharkiv Aviation Institute (Ukraine) in 1999 with a master's degree in computer science. I previously worked for CS Integra in Ukraine and for eProseed in the Netherlands, focusing on building enterprise solutions with Oracle ADF. Recently, I joined Flexagon and hold a position of Senior Architect. I have been recognized as an Oracle Certified Professional (OCP) and I am considered to be an expert in Oracle Fusion Middleware. I have been a speaker at various local and international IT conferences such as Oracle Day, Oracle OpenWorld, ODTUG Kscope, RMOUG Training Days, UKOUG and DOAG. I am an author at the ADF practice blog and a member of ADF Enterprise Methodology Group.

More posts by Eugene Fedorenko
  

Leave a Reply

Your email address will not be published. Required fields are marked *