Devops Workflow

Devops Workflow

DevOps is a set of practices that combines software development (Dev) and IT operations (Ops) to shorten the development lifecycle and deliver high-quality software continuously. In this article, we’ll explore the flow of DevOps for a Java-based project in Azure, making it simple and beginner-friendly.

What is DevOps?

DevOps aims to improve collaboration between development and operations teams, automate workflows, and continuously deliver software. The main components of DevOps include Continuous Integration (CI), Continuous Deployment (CD), and Continuous Monitoring.

The DevOps Flow in Azure

Let’s walk through the essential steps to set up a DevOps pipeline for a Java-based project in Azure, focusing on the end-to-end flow from coding to deployment.

Devops flow

1. Development

Coding

Developers: Write the application code locally on their machines.

Local Testing

Testing Locally: After writing the code, developers test it locally to ensure it works as expected.

2. GitHub

Code Upload

Upload to GitHub: Once the code is tested locally, developers push the code to a shared repository on GitHub.

Writing a Dockerfile: Before pushing the code, developers also write a Dockerfile, which is a script containing a series of instructions on how to build a Docker image for the application.

  • Purpose of a Dockerfile for a Java Project

    A Dockerfile serves the purpose of automating the creation of a Docker image, which contains everything needed to run an application. Specifically, it allows you to:

    1. Choose the Base OS:

    • The base image determines the operating system and its version that the container will use. This is critical because it ensures that your application runs in a consistent environment regardless of where the container is deployed.

    2. Add Dependencies:

    • Dependencies include everything your application needs to run, such as runtime environments, libraries, and other binaries. By specifying these in the Dockerfile, you ensure that the application has all required dependencies within the container, making it portable and consistent.

# Use an official OpenJDK runtime as the base image
FROM openjdk:11-jre-slim

# Set the working directory inside the container
WORKDIR /app

# Copy the JAR file from the host machine to the container
COPY target/myapp.jar /app/myapp.jar

# Expose the port on which the application will run
EXPOSE 8080

# Define the command to run the application
CMD ["java", "-jar", "myapp.jar"]

Webhook Trigger

Webhook: As soon as the code is merged into the main branch on GitHub, a webhook is triggered to start the CI pipeline.

3. Continuous Integration (CI)

3.1 Build

Gradle Build: The CI pipeline initiates a build process using Gradle.

Purpose: Gradle is a build automation tool that compiles the source code, runs tests, and packages the application into a deployable format, such as a JAR file (Java ARchive).

Outcome: A JAR file is created, containing the compiled code and any dependencies required for the application to run.

3.2 Push

Push to Container Registry: The created JAR file is then used to build a Docker image.

Container Registry (ACR): The Docker image is pushed to Azure Container Registry (ACR), where it is stored along with other images.

4. Continuous Deployment (CD)

4.1 Pull

Pull Image from ACR: The CD pipeline pulls the Docker image from the ACR.

4.2 Apply Kubernetes Manifests

Kubernetes: The CD pipeline then applies the necessary Kubernetes manifests to deploy the application.

Deployment:

Definition: A Deployment in Kubernetes manages a set of identical pods, ensuring that a specified number of replicas of an application are running at all times.

Function: It handles rolling updates, scaling, and monitoring the health of the application pods.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
  labels:
    app: my-app
spec:
  replicas: 3 # Number of replicas (pods) to run
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: nginx:latest # Docker image to use
        ports:
        - containerPort: 80 # Port the container listens on

Service:

Definition: A Service in Kubernetes defines a logical set of pods and a policy to access them.

Function: It provides a stable IP address and DNS name to access the application, enabling communication within the cluster and with external clients.

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80 # Port on which the service is exposed
      targetPort: 80 # Port on the pod to forward traffic to
  type: ClusterIP # Type of service (ClusterIP, NodePort, LoadBalancer)

Ingress:

Definition: An Ingress in Kubernetes manages external access to services within the cluster, typically HTTP and HTTPS.

Function: It provides load balancing, SSL termination, and name-based virtual hosting, directing external traffic to the appropriate services based on URL paths and hostnames.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: my-app.example.com # Hostname for the ingress
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service # Name of the service to route traffic to
            port:
              number: 80 # Port on the service

5. Live

Application Goes Live

Live Environment: After the Kubernetes manifests are applied, the application is deployed and available in the live environment.

Access: Users can now access the application through the configured Ingress, and the application is fully operational.

Conclusion

Implementing DevOps for a Java-based project in Azure can significantly streamline your development process, enhance collaboration, and improve the quality of your software. By setting up Continuous Integration, Continuous Deployment, and using Docker and Kubernetes, you ensure that your application is always in a deployable state and any issues are quickly identified and resolved.

Key Takeaways

Continuous Integration (CI): Automates the process of testing and building code changes.

Continuous Deployment (CD): Ensures code is automatically deployed to various environments after a successful build.

Docker and ACR: Containers provide a consistent runtime environment, and ACR is used to store Docker images.

Kubernetes: Orchestrates the deployment, scaling, and management of containerized applications.