Infrastructure as code (IaC) for Java-based apps on Azure

Infrastructure as code (IaC) for Java-based apps on Azure

The evolution of Java

Over the past several years, the Java ecosystem landscape has evolved, from monolith Java EE applications running on application servers and the Spring Framework to modern smaller-footprint Spring Boot, MicroProfile, and Jakarta EE microservices. Today, more and more Java developers are looking at how they can bring their existing Java applications to the cloud—or at how to build new cloud-native applications. Many organizations have significant investments in the migration of mission-critical Java applications running on-premises to fully supported environments to run these apps in the cloud.

💁🏻In this blog post, let's take a closer look at Java at Microsoft and on Azure and understand what Microsoft can offer to modernize existing Java-based apps or bring new ones with the well-known practice of Infrastructure as Code or IaC.

Java at Microsoft

We all know that Microsoft's evolution and main focus are on Windows with .NET mindset.

Well, I expect this comes as a surprise to some people as I was really surprised 😯 and had a ton of questions in my mind 😕 about how it came to be Java on Azure and why Microsoft’s choice is Java? Why not use other public clouds such as AWS? Because at that time, I was totally new to Azure as I got used to developing, building, and deploying apps in the AWS ecosystem. Maybe one of the reasons is that recent research has shown Java is in the top three languages among the world’s top start-ups and Java continues to gain more popularity according to RedMonk and PyPL ✊.

AWS and Azure have been persistent in the market for many years and have taken the top honors for a while now. However, we are not going to answer the question that bothers people most about which Cloud vendor to choose. In this article AWS vs Azure, you can learn more about the difference.

After making a small investigation, I found out that Microsoft actively supports Java community organizations to help promote the future of Java, including the ongoing development of the Java language and the JVM. Microsoft is contributing directly to the OpenJDK, and nowadays they are providing builds of the OpenJDK, starting with Java 11 and 16, and providing support for those binaries on Azure.

Microsoft supports Java

We can't forget about GitHub, which hosts millions of Java repositories and provides free CI/CD and vulnerability scans, not only for Java but other popular programming languages as well.

Microsoft also publishes plugins for popular Java IDEs and DevTools such as Maven, IntelliJ, and Eclipse to meet Java developers where they are and more easily integrate them into their development workflows.

Last but not least, there are over half a million JVMs running across production products and services at Microsoft. LinkedIn, for example, relies heavily on Java. The backend of Yammer is also written in Java. You can read more about tools for the Java developers on 👉 How Microsoft applies Java e-book.

Java is used widely across Microsoft

Java on Azure

Another surprise 😮 comes with Azure offerings for the Java ecosystem as it includes diverse technologies such as Java SE, Jakarta EE (successor to Java EE and J2EE), Spring, numerous application servers, and other frameworks. Whatever you’re doing with Java—building an app, using a framework, and running an application server—Azure supports your workload with plenty of choices and deployment options including infrastructure-as-a-service (IaaS) with no rearchitecting or code changes you can migrate existing apps, containers-as-a-service (CaaS), and fully managed platform-as-a-service (PaaS) for example, Azure Spring Cloud, which provides a managed platform for hosting Spring Boot microservice applications.

You can use virtual machines or virtual machine scale sets to host your Java applications. Scale sets, in particular, allow you to scale your applications across hundreds to thousands of VMs very rapidly. As we all probably know, virtual machines require a high level of management and configuration versus some other options out there.

If your organization leverages containers, you can use the Kubernetes service on Azure, known as AKS for Azure Kubernetes Service. Or you can use Azure Red Hat OpenShift, a jointly managed and supported offering from Red Hat and Azure. On the other hand, going even further up the spectrum, if your organization does not want to work with virtual machines or be in the business of orchestrating containers, service like App Service provide a managed platform for deploying code or Containers.

Migrate and Modernize your Java apps

Sometimes you don’t need an entire Java-based microservice. You can build serverless APIs with the help of Azure Functions. For example, Azure functions have a bunch of built-in connectors like Azure Event Hubs to process event-driven Java code and send the data to Azure Cosmos DB in real-time. FedEx and UBS projects are great examples of real-time, event-driven Java. I also recommend you to go through 👉 Code, Deploy, Scale Java your Way e-book to discover other ways of developing modern Java applications on Azure.

Infrastructure as code for cloud

After you decide to move your infrastructure to Azure Cloud and choose suitable a deployment strategy, next task you have to do is automatically provisioning your services. Of course, you can always deploy your services manually from Azure Portal or by using Azure CLI. However, these approaches do not provide much flexibility when it comes to creating release stages, deployment versioning, updating, deleting, and managing all your cloud resources.

Cloud applications usually have separate deployment environments for the stages of their release lifecycle. It’s common to have development, staging, and production environments. These environments are composed of many resources such as networking resources: Virtual Network(VNet), Network Security Groups (NSG) or secret resources, compute resources, load balancers, and databases.

Without Infrastructure as code (also referred to as IaC), managing all those resources can be a disorganized and delicate process. Because the DevOps team manually connects to remote cloud providers and uses API or web dashboards to provision new hardware and resources each time when a new release happens. Or they may manually make changes to one environment and forget to follow through on the other. This is how environment drift occurs. In this case, you may consider using the widely accepted practice of IaC.

Let’s briefly review the IaC definition:

Infrastructure as code is an IT practice that codifies and manages underlying IT infrastructure as software. The purpose of infrastructure as code is to enable developers or operations teams to automatically manage, monitor and provision resources, rather than manually configure discrete hardware devices and operating systems. Infrastructure as code is sometimes referred to as programmable or software-defined infrastructure.

Azure native support for IaC

Azure provides native support for IaC via the Azure Resource Manager model. Teams can define declarative ARM templates that specify the infrastructure required to deploy solutions.

Likewise, Terraform, Ansible, Chef, and Pulumi third-party platforms also support IaC to manage automated infrastructure.

Specifying your cloud infrastructure through ARM templates alone can be quite challenging. Especially, if your resources are frequently updated and the different environments use a diverse set of resources (customization of deployments per environment), and you would like to set custom runtime validation of your resources. In this case, there is a need for a new tool to greatly simplify how you specify infrastructure in higher-level Java code with the best software development practices and manage low-level ARM models via HTTP client APIs by hiding internal complexity. The solution can support parametrization and service developers only define parameters for the resource in code and offer observability feature by default.

Azure offers an open-source Azure SDK for Java that simplifies provisioning, managing, and using Azure resources from Java application code. To implement infrastructure as code in Java, you can use the management libraries of Azure Java SDK. With the management libraries, you can write configuration and deployment scripts to perform the same tasks that you can do through the Azure portal or the Azure CLI. There are plenty of samples available on how to use this library, you can check them on the ARM sample client library for the Java GitHub repo.

Java library can sync new changes automatically when ARM templates introduce new Azure features as soon as they are released without needing any code changes since the dedicated team is working on configuring them regularly to recognize the latest changes in Azure or if it is missing security-related updates.

Java client library IaC example

Let’s assume that you create your serverless function using Java then you can make automation of deployment via the library. Or use other deployment options through like CLI, IntelliJ Idea, Azure Portal, and VS Code.

Look at the following code example of how easy to create an Azure Function App in Java together with all required dependencies such as storage account and app service plan:

Creatable<StorageAccount> creatableStorageAccount = azure.storageAccounts()
    .define("<storage-account-name>")
    .withRegion(Region.US_EAST)
    .withExistingResourceGroup(rgName)
    .withGeneralPurposeAccountKindV2()
    .withSku(StorageAccountSkuType.STANDARD_LRS);
Creatable<AppServicePlan> creatableAppServicePlan = azure.appServicePlans()
    .define("<app-service-plan-name>")
    .withRegion(Region.US_EAST)
    .withExistingResourceGroup(rgName)
    .withPricingTier(PricingTier.STANDARD_S1)
    .withOperatingSystem(OperatingSystem.LINUX);
FunctionApp linuxFunctionApp = azure.functionApps().define("<function-app-name>")
    .withRegion(Region.US_EAST)
    .withExistingResourceGroup(rgName)
    .withNewLinuxAppServicePlan(creatableAppServicePlan)
    .withBuiltInImage(FunctionRuntimeStack.JAVA_8)
    .withNewStorageAccount(creatableStorageAccount)
    .withHttpsOnly(true)
    .withAppSetting("WEBSITE_RUN_FROM_PACKAGE", "<function-app-package-url>")
    .create();

Java library supports almost all Azure services. You can see the full list of them here. You can select to use the single-service package for each service and import it simply to your let’s say Maven POM file.

If you would like to leverage the Azure Active Directory for managing authentication flow, you can do it with Java code as well by simply adding the package.

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-identity</artifactId>
  <version>{LATEST_VERSION}</version>
</dependency>

Conclusion

With IaC, you automate platform provisioning. You essentially apply software engineering practices such as testing and versioning to your DevOps practices. Tools like Azure management client library for Java enable you to declaratively script the cloud infrastructure you require. On top of that, you can scale your Java applications smoothly and confidently on Azure including necessities such as security, supporting data and messaging services, caching, monitoring, and automation.

What is infrastructure as code (IaC)?.

Code, Deploy, Scale Java your Way.

How Microsoft applies Java.

➔ Watch Video Tutorial:

➔ Read the blog posts:

Did you find this article valuable?

Support Bobur Umurzokov by becoming a sponsor. Any amount is appreciated!