Infrastructure as Code (IaC) for Java-Based Apps on Azure
A closer look at Java at Microsoft and Azure and what Microsoft can offer to modernize existing Java-based apps or bring new ones with the practice of IaC
Join the DZone community and get the full member experience.
Join For FreeThe 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 Java developers are looking at how they can bring their existing Java applications to the cloud—or 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 article, let's take a closer look at Java at Microsoft and Azure to understand what Microsoft can offer to modernize existing Java-based apps or bring new ones with the well-known practice of Infrastructure as Code (IaC).
Java at Microsoft
We all know that Microsoft's evolution and main focus are on Windows with a .NET mindset.
I expect this comes as a surprise to some people as I was surprised and had several questions like how it came to be Java on Azure and why is Microsoft’s choice Java. Why not use other public clouds, such as AWS? At that time, I was new to Azure as I got used to developing, building, and deploying apps in the AWS ecosystem. Maybe one reason is that recent research has shown Java is in the top three languages among the world’s leading start-ups, and Java continues to gain more popularity, according to RedMonk.
AWS and Azure have been persistent in the market for many years and have taken the top honors for a while now.
After a small investigation, I found that Microsoft actively supports Java community organizations to help promote the future of Java, including the ongoing development of the Java language and the Java Virtual Machine (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.
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 for 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 2 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 Java developers in How Microsoft applies Java: The Inside Story e-book.
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 allow you to scale your applications across hundreds to thousands of VMs rapidly. As we all probably know, virtual machines require a high level of management and configuration versus other available options.
If your organization leverages containers, you can use the Kubernetes service on Azure, known as AKS for Azure Kubernetes Service. You can also 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, services like App Service provides a managed platform for deploying code or Containers.
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 going through the 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 a suitable deployment strategy, you have to automatically provision 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 (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 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.
Note: 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, 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 an 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 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 you create your serverless function using Java; then, you can make automation of deployment via the library. Or use other deployment options 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 on GitHub. You can select to use the single-service package for each service and import it 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 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.
Published at DZone with permission of Bobur Umurzokov. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments