Mastering Spring Boot: Building a Dynamic Secret Santa Generator Web Application using Azure DevOps
Table of contents
- Prerequisites
- Key Points
- Advantages of Using This Project
- Step-by-Step Description
- Setting Up the Infrastructure
- Step-by-Step Process:
- Environment Cleanup:
- Conclusion
The Secret Santa Generator is a web application built using Spring Boot technologies, Thymeleaf views, JPA, H2 Database, and more. It features a Spring Model, View, and Controller (MVC) architecture along with Service and Repository layers. This project is designed to facilitate the popular Christmas game "Secret Santa," where friends draw names to decide who they will give a present to.
Prerequisites
Before diving into this project, here are some skills and tools you should be familiar with:
[x] Clone repository for terraform code
Note: Replace resource names and variables as per your requirement in terraform code- Update
terraform.tfvars
.
- Update
[x] Azure Account: You’ll need an Azure account to create resources like virtual Machines, and AKS cluster, and manage pipelines.
[x] Terraform Knowledge: Familiarity with Terraform in provisioning, managing, and cleaning up infrastructure.
[x] Basic Kubernetes (AKS): A basic understanding of Kubernetes, especially Azure AKS, to deploy and manage containers.
[x] Docker Knowledge: Basic knowledge of Docker for containerizing applications.
[x] GitHub: Experience with GitHub for version control and managing repositories.
[x] Command-Line Tools: Basic comfort with using the command line for managing infrastructure and services.
[x] Basic CI/CD Knowledge: Some understanding of Continuous Integration and Deployment is recommended.
[x] Azure Container Registry (ACR): Set up ACR to store your Docker images.
[x] Linux VM: Docker must be installed on a Linux virtual machine to run containers.
Key Points
Technologies Used: Spring Boot, Thymeleaf, JPA, H2 Database
Architecture: Spring MVC, Service, and Repository layers
Functionality: Randomly generates Secret Santa matches
Learning Objectives: Spring development, database management, application architecture
Advantages of Using This Project
Educational Value: This project is an excellent resource for learning Spring development, database management, and industry-standard application architecture.
Practical Application: It provides a practical solution to the "Secret Santa problem," making it useful for real-world applications.
Comprehensive Technology Stack: The project covers a wide range of technologies, including Java Spring Core, HTML5, CSS, Thymeleaf, JPA, and H2 Database.
MVC Architecture: It demonstrates the use of MVC architecture, which is a widely adopted design pattern in web development.
In-Memory Database: The use of H2 in-memory database allows for easy setup and testing without the need for an external database.
Step-by-Step Description
Project Setup
Clone the Repository: Clone the project repository from the source control.
Import into IDE: Import the project into your preferred Integrated Development Environment (IDE) such as IntelliJ IDEA or Eclipse.
Build the Project: Use Maven or Gradle to build the project and resolve dependencies.
Application Configuration
Spring Boot Configuration: Configure Spring Boot application properties in application.properties or application.yml.
Database Configuration: Set up the H2 in-memory database configuration for development and testing purposes.
Developing the Application
Model Layer: Define the data models using JPA annotations.
Repository Layer: Create repository interfaces for data access operations.
Service Layer: Implement business logic in service classes.
Controller Layer: Develop controllers to handle HTTP requests and responses.
Thymeleaf Integration
View Templates: Create Thymeleaf templates for the user interface.
Data Binding: Bind data from the model to the view using Thymeleaf syntax.
Implementing Secret Santa Logic
Random Pairing Algorithm: Implement the logic to randomly generate Secret Santa matches.
Directed Graph Solution: Ensure the solution handles the complexities of the "Secret Santa problem" by creating a directed graph.
Testing and Debugging
Unit Tests: Write unit tests for the service and repository layers.
Integration Tests: Develop integration tests to ensure the application components work together as expected.
Debugging: Use the IDE's debugging tools to troubleshoot and fix any issues.
Deployment
Package the Application: Package the application as a JAR or WAR file.
Deploy to Server: Deploy the packaged application to a web server or cloud platform.
Setting Up the Infrastructure
I have created a Terraform code to set up the entire infrastructure, including the installation of required applications, tools, and the AKS cluster automatically created.
Note ⇒ AKS cluster
creation will take approx. 10 to 15 minutes.
⇒ Virtual machines will be created named as
"devopsdemovm"
⇒ Docker Install
⇒ Azure Cli Install
⇒ KubeCtl Install
⇒ AKS Cluster Setup
Virtual Machine creation
First, we'll create the necessary virtual machines using terraform
code.
Below is a terraform Code:
Once you clone repo and run the terraform command.
$ ls -l
Mode LastWriteTime Length Name
---- ------------- ------ ----
dar--l 26/12/24 7:16 PM pipeline
dar--l 23/12/24 3:38 PM scripts
-a---l 25/12/24 2:31 PM 600 .gitignore
-a---l 26/12/24 9:29 PM 6571 VM_ACR.tf
-a---l 26/12/24 9:29 PM 892 main.tf
-a---l 26/12/24 9:29 PM 567 output.tf
-a---l 26/12/24 9:29 PM 269 provider.tf
-a---l 26/12/24 9:30 PM 223 terraform.tfvars
-a---l 26/12/24 9:30 PM 615 variable.tf
You need to run the following terraform command.
Now, run the following command.
terraform init
terraform fmt
terraform validate
terraform plan
terraform apply
# Optional <terraform apply --auto-approve>
After running the Terraform command, we will check the following to ensure everything is set up correctly with Terraform.
Inspect the Cloud-Init
logs:
Once connected to VM then you can check the status of the user_data
script by inspecting the log files
# Primary log file for cloud-init
sudo tail -f /var/log/cloud-init-output.log
or
sudo cat /var/log/cloud-init-output.log | more
If the user_data script runs successfully, you will see output logs and any errors encountered during execution.
If there’s an error, this log will provide clues about what failed.
Verify the Installation
- [x] Docker version
ubuntu@ip-172-31-95-197:~$ docker --version
Docker version 24.0.7, build 24.0.7-0ubuntu4.1
docker ps -a
ubuntu@ip-172-31-94-25:~$ docker ps
- [x] kubectl version
ubuntu@ip-172-31-89-97:~$ kubectl version
Client Version: v1.31.1
Kustomize Version: v5.4.2
- [x] Azure cli version
azureuser@devopsdemovm:~$ az version
{
"azure-cli": "2.67.0",
"azure-cli-core": "2.67.0",
"azure-cli-telemetry": "1.1.0",
"extensions": {}
}
Step-by-Step Process:
Step-01: Create project in Azure DevOps
Open the Azure UI and DevOps portal
https://dev.azure.com/<name>
Create a new project
Step-02: Clone the Repo in Azure DevOps
Clone the repo ::
click on Import a repository
Git clone: https://github.com/jaiswaladi246/secretsanta-generator.git
Create/Configure a pipeline in Azure DevOps.
Click on Pipeline:
- follow the instruction
Click on pipeline and build it
Step-03: To Configure self-hosted Linux agents in Azure DevOps
Need to configure Self-hosted Linux agents/integrate to azure DevOps
run the following command as part of provisioning the server, we have already installed the agent.
azureuser@devopsdemovm:~/myagent$ ls -l
total 144072
drwxrwxr-x 26 azureuser azureuser 20480 Nov 13 10:54 bin
-rwxrwxr-x 1 azureuser azureuser 3173 Nov 13 10:45 config.sh
-rwxrwxr-x 1 azureuser azureuser 726 Nov 13 10:45 env.sh
drwxrwxr-x 7 azureuser azureuser 4096 Nov 13 10:46 externals
-rw-rw-r-- 1 azureuser azureuser 9465 Nov 13 10:45 license.html
-rw-rw-r-- 1 azureuser azureuser 3170 Nov 13 10:45 reauth.sh
-rw-rw-r-- 1 azureuser azureuser 2753 Nov 13 10:45 run-docker.sh
-rwxrwxr-x 1 azureuser azureuser 2014 Nov 13 10:45 run.sh
-rw-r--r-- 1 root root 147471638 Nov 13 12:22 vsts-agent-linux-x64-4.248.0.tar.gz
- Configure the agent
~/myagent$ ./config.sh
Type 'Y'
#Server URL
Azure Pipelines: https://dev.azure.com/{your-organization}
https://dev.azure.com/mrbalraj
- Give any name for agent
devops-demo_vm
- We have to Optionally run the agent interactively. If you didn't run as a service above:
~/myagent$ ./run.sh &
Now, Agent is online ;-)
Additional settings needs to be done as below
Step-04: Setup AKS Cluster
Note: Key concept overview of pipeline.
Step-05: Install SonarQube Extension
Now, we will integrate SonarQube into the same pipeline. We need to search for it in the marketplace and select SonarQube.
Install the SonarQube Extension. Now, we will integrate SonarQube into the same pipeline. We need to search for it in the marketplace and select SonarQube as shown below.
Step-06: Setup SonarQube.
Note the agent's public IP address and try to access it on port
9000
.Generate the SonarQubeToken
Step-07: Configure the Service Connection for "Azure Resource Manager
"
Steps to configure connection for Azure Resource Manager:
Configure the Service Connection:
Select the project and project setting:
Will create three connection as below
- SonarQube
- Docker hub
- AKS Cluster
Steps to configure connection for SonarQube:
Steps to configure connection for DockerHub:
Steps to configure connection for Kubernetes:
IIt will prompt you for login credentials, and you should use the same credentials you used for the UI portal login.
Create/Configure a pipeline in Azure DevOps.
Click on Pipeline:
- follow the instruction
Click on pipeline and build it
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
# master
- none
pool:
name: devops-demo_vm
demands: agent.name -equals agent-1
stages:
- stage: CompileJob
displayName: 'Compile Stage'
jobs:
- job: CompileJob
displayName: 'Compile Job'
steps:
- script: mvn compile
displayName: 'Compile Step'
- stage: Test
displayName: 'Test Stage'
jobs:
- job: TestJob
displayName: 'Test Job'
steps:
- script: mvn test
displayName: 'Test Step'
# Add Trivy FS scan image.
- stage: Trivy_FS_Scan
displayName: 'Trivy-FS-Stage'
jobs:
- job: TrivyFSJob
displayName: 'TrivyFSJob'
steps:
- script: trivy fs --format table -o trivy-fs-report.html .
displayName: 'TrivyFS-Scan_Step'
Add Stages for SonarQube
taking help from the helper as below to complete the stage for sonarqube
- stage: SonarQube_Scan
displayName: 'SonarQube-Stage'
jobs:
- job: SonarQubeSJob
displayName: 'SonarQubeJob'
steps:
- task: SonarQubePrepare@7
inputs:
SonarQube: 'sonar-conn'
scannerMode: 'cli'
configMode: 'manual'
cliProjectKey: 'secretsanta'
cliProjectName: 'secretsanta'
cliSources: '.'
extraProperties: 'sonar.java.binaries=.'
- task: SonarQubeAnalyze@7
inputs:
jdkversion: 'JAVA_HOME'
- add build package stage
- stage: Build
displayName: 'Build-Stage'
jobs:
- job: BuildJob
displayName: 'BuildJob'
steps:
- script: mvn package
displayName: 'Build_package_Step'
Run the pipeline and status of pipeline as below-
Add Docker build and push image
- stage: Docker
displayName: 'Docker-Stage'
jobs:
- job: DockerJob
displayName: 'Docker Job'
steps:
- script: mvn package
displayName: 'Build_package_Step'
- task: Docker@2
inputs:
containerRegistry: 'docker-conn'
repository: 'balrajsi/secretsanta'
command: 'buildAndPush'
Dockerfile: '**/Dockerfile'
tags: 'latest'
- Trivy Image scan
- stage: Trivy_Image_Scan
displayName: 'Trivy-Image-Stage'
jobs:
- job: TrivyImageJob
displayName: 'TrivyImageJob'
steps:
- script: trivy image --format table -o trivy-image-report.html balrajsi/secretsanta:latest
displayName: 'TrivyImage-Scan_Step'
Pipeline status
update the image name in manifest file.
add K8s Stage in pipeline.
- stage: K8_Deploy
displayName: 'K8_Deploy_Stage'
jobs:
- job: K8s_Deploy_Job
displayName: 'K8s_Deploy_Job'
steps:
- task: KubectlInstaller@0
inputs:
kubectlVersion: 'latest'
- task: Kubernetes@1
inputs:
connectionType: 'Kubernetes Service Connection'
kubernetesServiceEndpoint: 'k8s-conn'
namespace: 'default'
command: 'apply'
useConfigurationFile: true
configuration: 'deployment-service.yaml'
Run the pipeline and got below message
Once i approved it and pipeline works fine.
Project Status in SonarQube:
Image View in Docker Hub
View status in Azure UI:
On Agent VM
sudo snap install kubectl --classic
az login
from UI | K8s
First, we will create a folder in the repository called 'scripts' and update the .sh file as shown below. We will create a shell script to get an updated image tag in case a new image is being created..
Don't forget to update the container registroty name in the script file.
Now, try to get all resouces and you will noticed there is an error related to "ImagePullBackoff".
kubectl get all
I am getting below error message.
Solution: As we are using private registory and we need to use 'imagepullsecrets'
Go to azure registory and get the password which will be used in below command
- command to create
ACRImagePullSecret
kubectl create secret docker-registry <secret-name> \
--namespace <namespace> \
--docker-server=<container-registry-name>.azurecr.io \
--docker-username=<service-principal-ID> \
--docker-password=<service-principal-password>
Explanation of the Command:
kubectl create secret docker-registry:
- This creates a new Kubernetes secret of type docker-registry.
<secret-name>:
- The name of the secret being created. For example, acr-credentials.
--namespace <namespace>:
- Specifies the namespace in which the secret will be created. If omitted, it defaults to the default namespace.
Replace <namespace> with the desired namespace name.
--docker-server=<container-registry-name>.azurecr.io:
- The URL of your container registry. For Azure Container Registry (ACR), the format is <container-registry-name>.azurecr.io.
Replace <container-registry-name> with your ACR name.
--docker-username=<service-principal-ID>:
- The username to authenticate with the container registry. For Azure, this is typically a service principal's application (client) ID.
--docker-password=<service-principal-password>:
- The password (or secret) associated with the service principal used for authentication.
To get a token, click on container registory
kubectl create secret docker-registry acr-credentials \
--namespace default \
--docker-server=aconregee7b05ba.azurecr.io \
--docker-username=aconregee7b05ba \
--docker-password=<token>
- Command to delete
secret
kubectl delete secret acr-credential --namespace default
Also, update the manifest file as below.
- To check the deployment
kubectl get deploy vote -o yaml
- Verify services and try to access the application
kubectl get svc
kubectl get node -o wide
kubectl describe svc argocd-server -n argocd
Now, we will open one more port in VMSS
azureuser@devopsdemovm:~$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/santa-deployment-786c6cb64d-6jrf6 1/1 Running 0 8m50s
pod/santa-deployment-786c6cb64d-sgtgp 1/1 Running 0 8m50s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 155m
service/santa-ssvc LoadBalancer 10.0.191.143 <pending> 8080:32144/TCP 8m51s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/santa-deployment 2/2 2 2 8m51s
NAME DESIRED CURRENT READY AGE
replicaset.apps/santa-deployment-786c6cb64d 2 2 2 8m51s
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
aks-system-36575698-vmss000000 Ready <none> 155m v1.31.2 10.224.0.4 52.191.142.89 Ubuntu 22.04.5 LTS 5.15.0-1075-azure containerd://1.7.23-1
from Agent VM:
Congratulations :-) the application is working and accessible.
Step-05: Clean up the images and container registroy using the pipeline.
First create Service Connection in Azure Devops.
Once you create a connection, make sure to note down the connection ID, as it will be used in the pipeline.
On the agent machine, ensure you are logged in with Azure, and the connection is active. If not, log in using the following steps.
az login --use-device-code
Environment Cleanup:
As we are using Terraform, we will use the following command to delete
Delete all deployment/Service first
kubectl delete deployment.apps/santa-deployment kubectl delete service/santa-ssvc
Now, time to delete the AKS Cluster and Virtual machine
.
run the terraform command.
Terraform destroy --auto-approve
Conclusion
The Secret Santa Generator web application is a comprehensive project that showcases various aspects of Spring development, database management, and web application architecture. It provides a practical solution to a common problem while offering valuable learning opportunities for developers.
Ref Link: