Deploy your first Spring boot app using IaC on Azure
Published: 2023-04-14 16:17:28

Are you a Spring Boot and Infrastructure as Code (IaC) pro already? Great, then skip to the end of this blog post and grab the code to finish your POC and call it a day! But if you're new to this, buckle up! In this post, we'll take you on a journey to deploy your first Spring Boot application using IaC on Azure. It's going to be a wild ride, but we promise it'll be fun!

## Introduction

Are you new to Spring Boot and Infrastructure as Code (IaC)? In this blog post, we will guide you through the process of deploying your first Spring Boot application using IaC on Azure.

IaC is a modern approach to infrastructure management that emphasizes fully automated deployment workflows. This approach allows developers to focus on writing code while the infrastructure is automatically provisioned and managed.

In this post, we'll use Bicep, a human-readable language for defining Azure resources. Bicep simplifies creating and managing Azure resources by abstracting the underlying JSON syntax. You can define resources as code, version it, test it, and deploy it using tools like Azure CLI, Azure PowerShell, or GitHub Actions. Developed by Microsoft, Bicep is open source and gaining popularity among Azure users for its ease of use and flexibility.

Azure is a cloud platform that provides a wide range of infrastructure services. It is a popular choice for deploying Spring Boot applications due to its scalability, reliability, and ease of use.

In this blog post, we will cover the following steps:

1. Create a spring boot project
2. Create an azure account and subscription
3. Install Azure CLI
4. Azure App Service
5. Create a Resource group
6. Create bicep file
7. Deploy the infra 
8. Build and Deploy Spring Boot app

By the end of this blog post, you will have a fully functional Spring Boot application running on Azure using IaC. Let's get started!

## Create a spring boot project.

1. Go to **[https://start.spring.io/](https://start.spring.io/)** and select "Generate a Gradle Project" or "Generate a Maven Project" depending on your preference.
2. Choose a project name, package name, and location to store the project files.
3. Click on the "Generate" button to create the project.
4. Import the project into your IDE of choice.
5. Start coding your Spring Boot application.

First, let’s add the spring web dependency to build our rest API 

```xml
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
```
or if you prefer gradle
```grovvy

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '3.0.5'

```



now let’s a create a simple Controller

```java
@RestController
@RequestMapping("/api/v1")
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello from java app";
    }

}
```

let’s test it. 

```java
mvn spring-boot: run 
```

you should be able to hit the rest api 

```bash
curl http://localhost:8080/api/v1/hello
hello from java app
```

## Create a subscription

1. First, create an Azure account if you haven't already. You can sign up for a free account or a paid account, depending on your needs.
2. Once you have an Azure account, go to the Azure portal at **[https://portal.azure.com/](https://portal.azure.com/)**.
3. In the top-right corner of the page, click on the "Create a resource" button.
4. From the list of available services, select "Subscription".
5. On the "Create subscription" page, enter the required information such as your subscription name, billing information, and your Azure Active Directory tenant (if applicable).
6. Review the terms and conditions, and then click on the "Create" button to create your new subscription.

Once you have created your subscription, you can start using Azure services such as virtual machines, databases, storage, and more. You'll be charged for the services you use based on the pricing plan you selected during the subscription creation process. You can also manage your subscription and its resources through the Azure portal, Azure CLI, or Azure PowerShell.

## Install Azure CLI

instructions can be find here [https://learn.microsoft.com/en-us/cli/azure/](https://learn.microsoft.com/en-us/cli/azure/)

## What is needed to create an Azure AppService

To create an App Service on Azure, you need the following components:

1. **Resource Group**: A logical container for resources that are deployed within an Azure subscription. It helps you organize and manage resources based on their lifecycle and their relationship to each other.
2. **App Service Plan**: This defines a set of compute resources for a web app to run. It determines the performance, cost, and features available to your application. You can choose from various tiers, including Free, Shared, Basic, Standard, Premium, and Isolated, based on your needs.
3. **App Service**: This is a fully managed platform for building, deploying, and scaling your web apps. It supports a variety of programming languages and frameworks, such as .NET, Java, Node.js, Python, and PHP. You can deploy your application to an App Service, which automatically provides the necessary underlying infrastructure, scaling, and management capabilities.

## Create a resource group

```bash
az group create --location westeurope --resource-group todo-rg
```

## Create the bicep files

We are going to start with a few bicep code blocks: 

- Parameters

```jsx
param location string = 'westeurope'
param appName string
param appServicePlanName string
param sku string = 'F1'

```

This code snippet defines parameters in a Bicep configuration file. Parameters allow you to pass values into your Bicep file when deploying your resources, making the configuration more dynamic and reusable. Let's break down each parameter:

1. **`param location string = 'westeurope'`**: This defines a parameter named **`location`** of type **`string`** with a default value of **`'westeurope'`**. The **`location`** parameter represents the Azure region where resources will be deployed.
2. **`param appName string`**: This defines a parameter named **`appName`** of type **`string`**. This parameter does not have a default value, so it must be provided when deploying the Bicep file. The **`appName`** parameter represents the name of the App Service to be created.
3. **`param appServicePlanName string`**: This defines a parameter named **`appServicePlanName`** of type **`string`**. This parameter also does not have a default value and must be provided when deploying the Bicep file. The **`appServicePlanName`** parameter represents the name of the App Service Plan to be created.
4. **`param sku string = 'F1'`**: This defines a parameter named **`sku`** of type **`string`** with a default value of **`'F1'`**. The **`sku`** parameter represents the SKU (Stock Keeping Unit) of the App Service Plan, which determines its pricing tier and performance characteristics. The default value **`'F1'`** corresponds to the Free tier.

These parameters allow you to customise the deployment of your Azure resources, such as specifying different names, locations, or pricing tiers, without modifying the Bicep configuration file directly.

- App Service Plan

```jsx
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: appServicePlanName
  location: location
  properties: {
    reserved: true
  }
  sku: {
    name: sku
    tier: 'Free'
    size: sku
    family: 'F'
    capacity: 1
  }
  
}
```

This code snippet is a Bicep configuration for defining an Azure App Service Plan resource. Let's break it down:

1. **`resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01'`**: This line declares a new resource named **`appServicePlan`** of type **`Microsoft.Web/serverfarms`** with an API version **`2022-03-01`**.
2. **`name: appServicePlanName`**: This sets the name of the App Service Plan to the value of the **`appServicePlanName`** parameter.
3. **`location: location`**: This sets the location (region) where the App Service Plan will be deployed, using the value of the **`location`** parameter.
4. **`properties: { reserved: true }`**: This sets the **`reserved`** property to **`true`**. For an App Service Plan running on Linux, this property must be set to **`true`**. It's not applicable for Windows-based App Service Plans.
5. **`sku: { ... }`**: This block defines the pricing tier and performance characteristics of the App Service Plan.
    - **`name: sku`**: This sets the name of the SKU (Stock Keeping Unit) using the value of the **`sku`** parameter.
    - **`tier: 'Free'`**: This sets the tier of the App Service Plan to 'Free'. Other options include Shared, Basic, Standard, Premium, and Isolated.
    - **`size: sku`**: This sets the size of the SKU using the value of the **`sku`** parameter.
    - **`family: 'F'`**: This sets the family of the SKU to 'F', which corresponds to the Free tier.
    - **`capacity: 1`**: This sets the capacity, which represents the number of instances (VMs) allocated for this App Service Plan, to 1.

In summary, this Bicep configuration creates a new Azure App Service Plan resource with the specified name and location, running on Linux, using the Free pricing tier with a single instance.

- App Service

```jsx

resource appService 'Microsoft.Web/sites@2022-03-01' = {
  name: appName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      linuxFxVersion: 'JAVA|17-java17'    
    }
  }
}
```

This code snippet is a Bicep configuration for defining an Azure App Service resource. Let's break it down:

1. **`resource appService 'Microsoft.Web/sites@2022-03-01'`**: This line declares a new resource named **`appService`** of type **`Microsoft.Web/sites`** with an API version **`2022-03-01`**.
2. **`name: appName`**: This sets the name of the App Service to the value of the **`appName`** parameter.
3. **`location: location`**: This sets the location (region) where the App Service will be deployed, using the value of the **`location`** parameter.
4. **`properties: { ... }`**: This block defines the properties of the App Service.
    - **`serverFarmId: appServicePlan.id`**: This associates the App Service with an App Service Plan by setting the **`serverFarmId`** property to the **`id`** of the **`appServicePlan`** resource defined earlier.
    - **`siteConfig: { ... }`**: This block sets the configuration for the App Service.
        - **`linuxFxVersion: 'JAVA|17-java17'`**: This sets the runtime environment for the App Service to Java 17. The **`linuxFxVersion`** property is used to specify the runtime stack when deploying an App Service on Linux.

In summary, this Bicep configuration creates a new Azure App Service resource with the specified name and location, running on a Linux environment with Java 17 as the runtime stack, and associates it with an App Service Plan defined by **`appServicePlan.id`**.

enough blah blah, right? 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8b07y0cf6epczxntzi9.png)


Create a main.bicep 

```bash
param location string = 'westeurope'
param appName string
param appServicePlanName string
param sku string = 'F1'

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: appServicePlanName
  location: location
  properties: {
    reserved: true
  }
  sku: {
    name: sku
    tier: 'Free'
    size: sku
    family: 'F'
    capacity: 1
  }
  
}

resource appService 'Microsoft.Web/sites@2022-03-01' = {
  name: appName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      linuxFxVersion: 'JAVA|17-java17'    
    }
  }
}
		
```

now it's time to deploy your infra. 

```jsx
az deployment group create --resource-group 'todo-rg' --template-file main.bicep --parameters appName='todo-app-as' appServicePlanName='todo-app-asp'
```

You can follow the deployments on azure portal


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3sk133k2mksashl8ecty.png)


and after a new minutes you will be able to see the infra created here. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyetw7jn0ot6jouo7rh8.png)


## Deploy Jar file via Azure CLI

```jsx
az webapp deploy --resource-group  'todo-rg' --name 'todo-app-as' --src-path ./target/todo-0.0.1-SNAPSHOT.jar --type 'jar'
```

## Pro Tips

- When you're playing around with cloud vendors like Microsoft, it's always a good idea to keep your configurations as code. This way, you can easily delete and recreate your infrastructure only when you're using it. That way, you won't be surprised by an unpleasant cloud bill.
- if you are new to Azure, just be patient, if the CLI says it worked, it worked even thought you can see it yet on the portal.
- This is not production code, be aware, stay secure!

 

## What's next?

This is an introductory post featuring a basic Java application deployed on Azure App Services, but there is so much more to come! In the upcoming posts, we will delve into other Azure services such as Key Vault and App Insights. Additionally, we will explore the creation of build pipelines and the deployment of a variety of exciting applications. So, get ready to be amazed and stay tuned for more updates and insights!

You can find the code examples here: [https://github.com/RafMaia92/blog-code/tree/main/01-spring-iac-appservice-basic](https://github.com/RafMaia92/blog-code/tree/main/01-spring-iac-appservice-basic)

feel always free to reach out via twitter @RafMaia92

Happy Coding!