Repository: chef/automate
Pull request #7998 (2023-06-27 14:21:15)

UI Fix to give the resolution message
### :nut_and_bolt: Description: What code changed, and why?
- The UI was not giving the resolution message that were thrown from trigger or Handler funtions and there resolution in the how to resolve message
- the Hardware tigger and NFS mount where using same util it was giving the error response as string ( "400: Bad Request ) otherwise it should be the error that is coming from the Handlers , also refactored both the trigger files as well 

<!-- /!\ Please ensure that you are NOT disclosing any customer information without their consent /!\ -->

### :chains: Related Resources
- https://chefio.atlassian.net/browse/CHEF-3796
### :+1: Definition of Done

### :athletic_shoe: How to Build and Test the Change

### :white_check_mark: Checklist

**All PRs** must tick these:

- [x] I have read the [CONTRIBUTING document](https://github.com/chef/automate/blob/master/CONTRIBUTING.md).
- [x] All commits signed-off for the [Developer Certification of Origin](https://github.com/chef/chef/blob/master/CONTRIBUTING.md#developer-certification-of-origin-dco).

With occasional exceptions, all PRs **from Progress employees** must tick these:

- [ ] Is the code clear? *(complicated code or lots of comments--subdivide and use well-named methods, meaningful variable names, etc.)*
- [ ] Consistency checked? *(user notifications, user prompts, visual patterns, code patterns, variable names)*
- [ ] Repeated code blocks eliminated? *(adapt and reuse existing components, blocks, functions, etc.)*
- [ ] Spelling, grammar, typos checked? *(at a minimum use `make spell` in any component directory)*
- [ ] Code well-formatted? *(indents, line breaks, etc. improve rather than hinder readability)*

All PRs **from Progress employees** should tick these if appropriate:

- [ ] Tests added/updated? (all new code needs new tests)
- [ ] Docs added/updated? (all customer-facing changes)

*Please add a note next to any checkbox above if you are NOT ticking it.*

### :camera: Screenshots, if applicable

- The response from the trigger is now shown in the How Resolve section 

<img width="1792" alt="Screenshot 2023-06-27 at 7 46 59 PM" src="https://github.com/chef/automate/assets/62262938/abb5f5d5-5ee4-4082-93be-9d888252f39c">


- The Error given from the Handlers are also captured now in the error section

<img width="1792" alt="Screenshot 2023-06-27 at 7 47 38 PM" src="https://github.com/chef/automate/assets/62262938/90f25838-10b8-4ed5-bf3f-e6b54846b936">


<img width="1792" alt="Screenshot 2023-06-27 at 7 47 41 PM" src="https://github.com/chef/automate/assets/62262938/4ce52e8b-c3c7-46d9-8787-d34c7d9c0914">


<img width="1792" alt="Screenshot 2023-06-27 at 7 48 26 PM" src="https://github.com/chef/automate/assets/62262938/636f00a2-69d8-40e9-8104-894492d81fbc">


netlify[bot]: ### <span aria-hidden="true">👷</span> Deploy Preview for *chef-automate* processing.


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 6b7c1699f12a45b64ae8e88f6184260509cccaef |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/chef-automate/deploys/649af05f743a370008b0ff1e |
sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [![29.2%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/25-16px.png '29.2%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) 29.2% Coverage on New Code (is less than 80%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [![66.7%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '66.7%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) 66.7% Coverage on New Code (is less than 80%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate passed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)

[![Bug](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/bug-16px.png 'Bug')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG) [0 Bugs](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG)  
[![Vulnerability](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/vulnerability-16px.png 'Vulnerability')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/security_hotspot-16px.png 'Security Hotspot')](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [0 Security Hotspots](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)  
[![Code Smell](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/code_smell-16px.png 'Code Smell')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL)

[![80.8%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '80.8%')](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_coverage&view=list) [80.8% Coverage](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_coverage&view=list)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/3-16px.png '0.0%')](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_duplicated_lines_density&view=list)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate passed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)

[![Bug](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/bug-16px.png 'Bug')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG) [0 Bugs](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG)  
[![Vulnerability](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/vulnerability-16px.png 'Vulnerability')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/security_hotspot-16px.png 'Security Hotspot')](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [0 Security Hotspots](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)  
[![Code Smell](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/code_smell-16px.png 'Code Smell')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL)

[![83.3%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '83.3%')](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_coverage&view=list) [83.3% Coverage](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_coverage&view=list)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/3-16px.png '0.0%')](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_duplicated_lines_density&view=list)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [![70.8%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '70.8%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) 70.8% Coverage on New Code (is less than 80%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate passed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)

[![Bug](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/bug-16px.png 'Bug')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG) [0 Bugs](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=BUG)  
[![Vulnerability](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/vulnerability-16px.png 'Vulnerability')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/security_hotspot-16px.png 'Security Hotspot')](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998) [0 Security Hotspots](https://sonar.progress.com/security_hotspots?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998)  
[![Code Smell](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/common/code_smell-16px.png 'Code Smell')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/RatingBadge/A-16px.png 'A')](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonar.progress.com/project/issues?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&resolved=false&types=CODE_SMELL)

[![91.7%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/90-16px.png '91.7%')](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_coverage&view=list) [91.7% Coverage](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_coverage&view=list)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/3-16px.png '0.0%')](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonar.progress.com/component_measures?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7998&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/VERSION b/VERSION
index 5085c0a07..2009f4514 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-4.7.115
\ No newline at end of file
+4.7.129
\ No newline at end of file
diff --git a/components/automate-backend-deployment/habitat/plan.sh b/components/automate-backend-deployment/habitat/plan.sh
index ac1dbf5e0..821f55cb1 100644
--- a/components/automate-backend-deployment/habitat/plan.sh
+++ b/components/automate-backend-deployment/habitat/plan.sh
@@ -112,4 +112,4 @@ do_install() {
 
 do_strip() {
   return 0
-}
\ No newline at end of file
+}
diff --git a/components/automate-cli/cmd/chef-automate/certRotate.go b/components/automate-cli/cmd/chef-automate/certRotate.go
index 80193f02b..c9a940fd4 100644
--- a/components/automate-cli/cmd/chef-automate/certRotate.go
+++ b/components/automate-cli/cmd/chef-automate/certRotate.go
@@ -31,13 +31,6 @@ const (
 		cert = """%v"""
 		key = """%v"""`
 
-	CHEFSERVER_ROOTCA_CONFIG = `
-	[cs_nginx.v1.sys.ngx.http]
-		ssl_verify_depth = 6
-	[global.v1.external.automate.ssl]
-		server_name = "https://%v"
-		root_cert = """%v"""`
-
 	POSTGRES_CONFIG = `
 	[ssl]
 		enable = true
@@ -290,20 +283,6 @@ func (c *certRotateFlow) certRotateFrontend(sshUtil SSHUtil, certs *certificates
 		return err
 	}
 
-	// ignore root-ca when node flag is provided
-	if flagsObj.node != "" {
-		return nil
-	}
-
-	// If we pass root-ca flag in automate then we need to update root-ca in the ChefServer to maintain the connection
-	if flagsObj.automate {
-		skipIpsList := c.getFrontEndIpsForSkippingRootCAPatching(AUTOMATE, certs.rootCA, infra, currentCertsInfo)
-		c.skipMessagePrinter(CHEF_SERVER, SKIP_FRONT_END_IPS_MSG_A2, "", skipIpsList)
-		err = c.patchRootCAinCS(sshUtil, certs.rootCA, timestamp, infra, flagsObj, skipIpsList)
-		if err != nil {
-			return err
-		}
-	}
 	return nil
 }
 
@@ -561,42 +540,6 @@ func (c *certRotateFlow) patchConfig(param *patchFnParameters) error {
 	return nil
 }
 
-// patchRootCAinCS will rotate the root-ca in the ChefServer to maintain the connection.
-func (c *certRotateFlow) patchRootCAinCS(sshUtil SSHUtil, rootCA, timestamp string, infra *AutomateHAInfraDetails, flagsObj *certRotateFlags, skipIpsList []string) error {
-
-	fileName := "rotate-root_CA.toml"
-	remoteService := CHEF_SERVER
-	cmd := `sudo chef-automate config show | grep fqdn | awk '{print $3}' | tr -d '"'`
-	ips := c.getIps(remoteService, infra)
-	if len(ips) == 0 {
-		return errors.New(fmt.Sprintf("No %s IPs are found", remoteService))
-	}
-	sshUtil.getSSHConfig().hostIP = ips[0]
-	fqdn, err := sshUtil.connectAndExecuteCommandOnRemote(cmd, true)
-	if err != nil {
-		return err
-	}
-
-	config := fmt.Sprintf(CHEFSERVER_ROOTCA_CONFIG, strings.TrimSpace(string(fqdn)), rootCA)
-
-	patchFnParam := &patchFnParameters{
-		sshUtil:       sshUtil,
-		config:        config,
-		fileName:      fileName,
-		timestamp:     timestamp,
-		remoteService: remoteService,
-		infra:         infra,
-		flagsObj:      flagsObj,
-		skipIpsList:   skipIpsList,
-	}
-
-	err = c.patchConfig(patchFnParam)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
 // copyAndExecute will copy the toml file to each required node and then execute the set of commands.
 func (c *certRotateFlow) copyAndExecute(ips []string, sshUtil SSHUtil, timestamp string, remoteService string, fileName string, scriptCommands string, flagsObj *certRotateFlags) error {
 
@@ -691,7 +634,7 @@ func (c *certRotateFlow) getAllIPs(infra *AutomateHAInfraDetails) []string {
 func (c *certRotateFlow) getFilteredIps(serviceIps, skipIpsList []string) []string {
 	filteredIps := []string{}
 	for _, ip := range serviceIps {
-		if stringutils.SliceContains(skipIpsList, ip) == false {
+		if !stringutils.SliceContains(skipIpsList, ip) {
 			filteredIps = append(filteredIps, ip)
 		}
 	}
@@ -703,9 +646,6 @@ func (c *certRotateFlow) compareCurrentCertsWithNewCerts(remoteService string, n
 	skipIpsList := []string{}
 	isCertsSame := true
 	if remoteService == AUTOMATE {
-		if flagsObj.node == "" {
-			isCertsSame = strings.TrimSpace(currentCertsInfo.AutomateRootCert) == newCerts.rootCA
-		}
 		skipIpsList = c.comparePublicCertAndPrivateCert(newCerts, currentCertsInfo.AutomateCertsByIP, isCertsSame, flagsObj)
 		return skipIpsList
 	}
@@ -860,8 +800,8 @@ func (c *certRotateFlow) getCerts(infra *AutomateHAInfraDetails, flagsObj *certR
 		return nil, errors.New("Please provide the valid certificate for public-cert")
 	}
 
-	// Root CA is mandatory for A2, PG and OS nodes. But root CA is ignored when node flag is provided
-	if flagsObj.automate || flagsObj.postgres || flagsObj.opensearch {
+	// Root CA is mandatory for PG and OS nodes. But root CA is ignored when node flag is provided
+	if flagsObj.postgres || flagsObj.opensearch {
 		if rootCaPath == "" && flagsObj.node == "" {
 			return nil, errors.New("Please provide root-ca flag")
 		}
diff --git a/components/automate-cli/cmd/chef-automate/deployedConfig.go b/components/automate-cli/cmd/chef-automate/deployedConfig.go
index 38cf96b0b..d2d0e659a 100644
--- a/components/automate-cli/cmd/chef-automate/deployedConfig.go
+++ b/components/automate-cli/cmd/chef-automate/deployedConfig.go
@@ -6,22 +6,27 @@ import (
 	"github.com/chef/automate/lib/config"
 )
 
-func PopulateHaCommonConfig(configPuller PullConfigs) (haDeployConfig *config.HaDeployConfig, err error) {
-	existingInfraConfig, err := configPuller.fetchInfraConfig()
-	if err != nil {
-		return nil, err
-	}
-	if existingInfraConfig != nil {
-		return CopyExistingInfra(existingInfraConfig), nil
-	}
+var GetModeOfDeployment func() string = getModeOfDeployment
 
-	awsConfig, err := configPuller.fetchAwsConfig()
-	if err != nil {
-		return nil, err
-	}
+func PopulateHaCommonConfig(configPuller PullConfigs) (haDeployConfig *config.HaDeployConfig, err error) {
+	modeOfDeployment := GetModeOfDeployment()
+	if modeOfDeployment == EXISTING_INFRA_MODE {
+		existingInfraConfig, err := configPuller.fetchInfraConfig()
+		if err != nil {
+			return nil, err
+		}
+		if existingInfraConfig != nil {
+			return CopyExistingInfra(existingInfraConfig), nil
+		}
+	} else if modeOfDeployment == AWS_MODE {
+		awsConfig, err := configPuller.fetchAwsConfig()
+		if err != nil {
+			return nil, err
+		}
 
-	if awsConfig != nil {
-		return CopyAws(awsConfig), nil
+		if awsConfig != nil {
+			return CopyAws(awsConfig), nil
+		}
 	}
 
 	return nil, errors.New("deployed config was not found")
diff --git a/components/automate-cli/cmd/chef-automate/verify.go b/components/automate-cli/cmd/chef-automate/verify.go
index 55b4c4495..3e4f11e8f 100644
--- a/components/automate-cli/cmd/chef-automate/verify.go
+++ b/components/automate-cli/cmd/chef-automate/verify.go
@@ -292,12 +292,6 @@ func (v *verifyCmdFlow) RunVerify(config string) error {
 
 	// Get config required for batch-check API call
 	batchCheckConfig := models.NewConfig()
-
-	err := batchCheckConfig.PopulateWith(v.Config)
-	if err != nil {
-		return err
-	}
-
 	if v.Config.IsExistingInfra() {
 		v.sshPort, v.sshKeyFile, v.sshUserName = v.getSSHConfig(v.Config.Architecture.ExistingInfra)
 
@@ -317,9 +311,13 @@ func (v *verifyCmdFlow) RunVerify(config string) error {
 		v.postgresqlIPs = configDetails.PostgresqlIps
 		v.opensearchIPs = configDetails.OpensearchIps
 
-		batchCheckConfig.ExternalOS.OSRoleArn = configDetails.OsSnapshotRoleArn
-		batchCheckConfig.ExternalOS.OsSnapshotUserAccessKeyId = configDetails.OsSnapshotUserID
-		batchCheckConfig.ExternalOS.OsSnapshotUserAccessKeySecret = configDetails.OsSnapshotUserSecret
+		if v.Config.Aws.Config.SetupManagedServices {
+			batchCheckConfig.ExternalOS = &models.ExternalOS{
+				OSRoleArn:                     configDetails.OsSnapshotRoleArn,
+				OsSnapshotUserAccessKeyId:     configDetails.OsSnapshotUserID,
+				OsSnapshotUserAccessKeySecret: configDetails.OsSnapshotUserSecret,
+			}
+		}
 		// assign ip's to models.Hardware
 		batchCheckHardware := batchCheckConfig.Hardware
 		batchCheckHardware.AutomateNodeIps = configDetails.AutomateIps
@@ -330,6 +328,10 @@ func (v *verifyCmdFlow) RunVerify(config string) error {
 		return errors.New("Invalid config")
 	}
 
+	err := batchCheckConfig.PopulateWith(v.Config)
+	if err != nil {
+		return err
+	}
 	var batchCheckResultBastion, batchCheckResultRemote models.BatchCheckResponse
 	var batchCheckResults []models.BatchCheckResult
 
@@ -650,6 +652,14 @@ func buildReports(batchCheckResults []models.BatchCheckResult) []reporting.Verif
 	for _, batchCheckResult := range batchCheckResults {
 
 		for _, test := range batchCheckResult.Tests {
+
+			var errorMsgs, resolutionMsgs []string
+			var successfulCount, failedCount int
+
+			if test.Error != nil {
+				resolutionMsgs = append(resolutionMsgs, test.Error.Message)
+				failedCount++
+			}
 			report := reporting.VerificationReport{}
 			report.TableKey = batchCheckResult.NodeType
 			info := reporting.Info{}
@@ -665,8 +675,6 @@ func buildReports(batchCheckResults []models.BatchCheckResult) []reporting.Verif
 				info.Status = "Failed"
 			}
 
-			var errorMsgs, resolutionMsgs []string
-			var successfulCount, failedCount int
 			for _, check := range test.Checks {
 				if check.Passed {
 					successfulCount++
@@ -694,7 +702,6 @@ func buildReports(batchCheckResults []models.BatchCheckResult) []reporting.Verif
 		}
 
 	}
-
 	return reports
 }
 
diff --git a/components/automate-cli/pkg/verifyserver/models/batchcheck.go b/components/automate-cli/pkg/verifyserver/models/batchcheck.go
index 8a28dbd5f..56f1ef9cb 100644
--- a/components/automate-cli/pkg/verifyserver/models/batchcheck.go
+++ b/components/automate-cli/pkg/verifyserver/models/batchcheck.go
@@ -87,6 +87,7 @@ type Config struct {
 	SSHUser         *SSHUser       `json:"ssh_user"`
 	Arch            string         `json:"arch"`
 	Backup          *Backup        `json:"backup"`
+	ExternalDbType  string         `json:"external_db_type"`
 	Hardware        *Hardware      `json:"hardware"`
 	Certificate     []*Certificate `json:"certificate"`
 	ExternalOS      *ExternalOS    `json:"external_opensearch"`
@@ -100,8 +101,6 @@ func NewConfig() *Config {
 		Hardware:    &Hardware{},
 		Certificate: []*Certificate{},
 		SSHUser:     &SSHUser{},
-		ExternalOS:  &ExternalOS{},
-		ExternalPG:  &ExternalPG{},
 	}
 }
 
@@ -295,14 +294,14 @@ func (c *Config) populateAwsCerts(haConfig *config.HaDeployConfig) {
 	automateConfig := haConfig.Automate.Config
 	cert := addCertificatesInConfig(automateConfig.Fqdn, automateConfig.FqdnRootCA, config.AUTOMATE)
 	if automateConfig.EnableCustomCerts {
-		cert.Nodes = appendCertsByIpToNodeCerts(nil, []string{""}, automateConfig.PrivateKey, automateConfig.PublicKey, "", "", "")
+		cert.Nodes = appendCertsByIpToNodeCerts(nil, c.Hardware.AutomateNodeIps, automateConfig.PrivateKey, automateConfig.PublicKey, "", "", "")
 	}
 	c.Certificate = append(c.Certificate, cert)
 	chefserverConfig := haConfig.ChefServer.Config
 	//We can populate this later as well in config
 	cert = addCertificatesInConfig(chefserverConfig.ChefServerFqdn, chefserverConfig.RootCA, config.CHEFSERVER)
 	if chefserverConfig.EnableCustomCerts {
-		cert.Nodes = appendCertsByIpToNodeCerts(nil, []string{""}, chefserverConfig.PrivateKey, chefserverConfig.PublicKey, "", "", "")
+		cert.Nodes = appendCertsByIpToNodeCerts(nil, c.Hardware.ChefInfraServerNodeIps, chefserverConfig.PrivateKey, chefserverConfig.PublicKey, "", "", "")
 	}
 
 	c.Certificate = append(c.Certificate, cert)
@@ -310,37 +309,40 @@ func (c *Config) populateAwsCerts(haConfig *config.HaDeployConfig) {
 	postgresqlConfig := haConfig.Postgresql.Config
 	if postgresqlConfig.EnableCustomCerts {
 		cert = addCertificatesInConfig("", "", config.POSTGRESQL)
-		cert.Nodes = appendCertsByIpToNodeCerts(nil, []string{""}, postgresqlConfig.PrivateKey, postgresqlConfig.PublicKey, "", "", postgresqlConfig.RootCA)
+		cert.Nodes = appendCertsByIpToNodeCerts(nil, c.Hardware.PostgresqlNodeIps, postgresqlConfig.PrivateKey, postgresqlConfig.PublicKey, "", "", postgresqlConfig.RootCA)
 		c.Certificate = append(c.Certificate, cert)
 	}
 
 	openSearchConfig := haConfig.Opensearch.Config
 	if openSearchConfig.EnableCustomCerts {
 		cert = addCertificatesInConfig("", "", config.OPENSEARCH)
-		cert.Nodes = appendCertsByIpToNodeCerts(nil, []string{""}, openSearchConfig.PrivateKey, openSearchConfig.PublicKey, openSearchConfig.AdminKey, openSearchConfig.AdminCert, openSearchConfig.RootCA)
+		cert.Nodes = appendCertsByIpToNodeCerts(nil, c.Hardware.OpenSearchNodeIps, openSearchConfig.PrivateKey, openSearchConfig.PublicKey, openSearchConfig.AdminKey, openSearchConfig.AdminCert, openSearchConfig.RootCA)
 		c.Certificate = append(c.Certificate, cert)
 	}
 }
 
 func (c *Config) populateAwsManagedServicesConfig(haConfig *config.HaDeployConfig) {
 	awsManagedServicesConfig := haConfig.Aws.Config
+	if c.ExternalPG == nil {
+		c.ExternalPG = &ExternalPG{}
+	}
+
 	c.ExternalPG.PGDbUserName = awsManagedServicesConfig.ManagedRdsDbuserUsername
 	c.ExternalPG.PGDbUserPassword = awsManagedServicesConfig.ManagedRdsDbuserPassword
 	c.ExternalPG.PGInstanceURL = awsManagedServicesConfig.ManagedRdsInstanceURL
-
-	// pg root-ca might be nil in pre deploy state
 	c.ExternalPG.PGRootCert = awsManagedServicesConfig.ManagedRdsCertificate
 	c.ExternalPG.PGSuperuserName = awsManagedServicesConfig.ManagedRdsSuperuserUsername
 	c.ExternalPG.PGSuperuserPassword = awsManagedServicesConfig.ManagedRdsSuperuserPassword
 
+	if c.ExternalOS == nil {
+		c.ExternalOS = &ExternalOS{}
+	}
+
 	c.ExternalOS.OSDomainName = awsManagedServicesConfig.ManagedOpensearchDomainName
 	c.ExternalOS.OSDomainURL = awsManagedServicesConfig.ManagedOpensearchDomainURL
-
-	// os root-ca might be nil in pre deploy state
 	c.ExternalOS.OSCert = awsManagedServicesConfig.ManagedOpensearchCertificate
 	c.ExternalOS.OSUserPassword = awsManagedServicesConfig.ManagedOpensearchUserPassword
 	c.ExternalOS.OSUsername = awsManagedServicesConfig.ManagedOpensearchUsername
-	c.ExternalOS.OSRoleArn = awsManagedServicesConfig.AwsOsSnapshotRoleArn
 }
 
 func (c *Config) populateExistingInfraCommonConfig(haConfig *config.HaDeployConfig) {
@@ -377,21 +379,26 @@ func addCertificatesInConfig(fqdn, rootCA, nodeType string) *Certificate {
 }
 
 func (c *Config) populateExternalDbConfig(haConfig *config.HaDeployConfig) {
+	c.ExternalDbType = haConfig.External.Database.Type
 	externalPgConfig := haConfig.External.Database.PostgreSQL
+	if c.ExternalPG == nil {
+		c.ExternalPG = &ExternalPG{}
+	}
 	c.ExternalPG.PGDbUserName = externalPgConfig.DbuserUsername
 	c.ExternalPG.PGDbUserPassword = externalPgConfig.DbuserPassword
 	c.ExternalPG.PGInstanceURL = externalPgConfig.InstanceURL
-
-	// pg root-ca might be nil in pre deploy state
 	c.ExternalPG.PGRootCert = externalPgConfig.PostgresqlRootCert
 	c.ExternalPG.PGSuperuserName = externalPgConfig.SuperuserUsername
 	c.ExternalPG.PGSuperuserPassword = externalPgConfig.SuperuserPassword
 
 	externalOsConfig := haConfig.External.Database.OpenSearch
+
+	if c.ExternalOS == nil {
+		c.ExternalOS = &ExternalOS{}
+	}
+
 	c.ExternalOS.OSDomainName = externalOsConfig.OpensearchDomainName
 	c.ExternalOS.OSDomainURL = externalOsConfig.OpensearchDomainURL
-
-	// os root-ca might be nil in pre deploy state
 	c.ExternalOS.OSCert = externalOsConfig.OpensearchRootCert
 	c.ExternalOS.OSUserPassword = externalOsConfig.OpensearchUserPassword
 	c.ExternalOS.OSUsername = externalOsConfig.OpensearchUsername
@@ -471,6 +478,7 @@ type NodeCert struct {
 type HardwareResourceCheckResponse struct {
 	Status string                           `json:"status"`
 	Result []HardwareResourceCountApiResult `json:"result"`
+	Error  fiber.Error                      `json:"error"`
 }
 
 type HardwareResourceCountApiResult struct {
@@ -506,6 +514,7 @@ type FirewallRequest struct {
 type NFSMountCheckResponse struct {
 	Status string             `json:"status"`
 	Result []NFSMountResponse `json:"result"`
+	Error  fiber.Error        `json:"error"`
 }
 
 type FqdnRequest struct {
diff --git a/components/automate-cli/pkg/verifyserver/models/nfsmount.go b/components/automate-cli/pkg/verifyserver/models/nfsmount.go
index 3c2f1b36d..bdc994492 100644
--- a/components/automate-cli/pkg/verifyserver/models/nfsmount.go
+++ b/components/automate-cli/pkg/verifyserver/models/nfsmount.go
@@ -1,6 +1,7 @@
 package models
 
 type NFSMountRequest struct {
+	ExternalDbType         string   `json:"external_db_type"`
 	AutomateNodeIPs        []string `json:"automate_node_ips"`
 	ChefInfraServerNodeIPs []string `json:"chef_infra_server_node_ips"`
 	PostgresqlNodeIPs      []string `json:"postgresql_node_ips"`
diff --git a/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount.go b/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount.go
index 294895895..7da6b6e46 100644
--- a/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount.go
+++ b/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount.go
@@ -14,10 +14,16 @@ func (h *Handler) NFSMount(c *fiber.Ctx) error {
 		h.Logger.Error(err.Error())
 		return fiber.NewError(http.StatusBadRequest, "Invalid Body Request")
 	}
-	if len(reqBody.AutomateNodeIPs) == 0 || len(reqBody.ChefInfraServerNodeIPs) == 0 || len(reqBody.PostgresqlNodeIPs) == 0 || len(reqBody.OpensearchNodeIPs) == 0 {
-		return fiber.NewError(http.StatusBadRequest, "AutomateNodeIPs, ChefInfraServerNodeIPs, PostgresqlNodeIPs or OpensearchNodeIPs cannot be empty")
-	}
 
+	if reqBody.ExternalDbType == "self-managed" {
+		if len(reqBody.AutomateNodeIPs) == 0 || len(reqBody.ChefInfraServerNodeIPs) == 0 {
+			return fiber.NewError(http.StatusBadRequest, "AutomateNodeIPs or ChefInfraServerNodeIPs cannot be empty")
+		}
+	} else {
+		if len(reqBody.AutomateNodeIPs) == 0 || len(reqBody.ChefInfraServerNodeIPs) == 0 || len(reqBody.PostgresqlNodeIPs) == 0 || len(reqBody.OpensearchNodeIPs) == 0 {
+			return fiber.NewError(http.StatusBadRequest, "AutomateNodeIPs, ChefInfraServerNodeIPs, PostgresqlNodeIPs or OpensearchNodeIPs cannot be empty")
+		}
+	}
 	if reqBody.MountLocation == "" {
 		return fiber.NewError(http.StatusBadRequest, "Mount Location cannot be empty")
 	}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger.go
index fbbe91149..adb380095 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger.go
@@ -298,6 +298,8 @@ func constructResponseFromOutput(result []models.CheckTriggerResponse) []models.
 			newChecks := value.Result.Checks
 			newChecks = append(newChecks, checkResponse.Result.Checks...)
 			//Adding the new checks to the result
+			value.Result.Passed = checkResponse.Result.Passed
+			value.Result.Skipped = checkResponse.Result.Skipped
 			value.Result.Checks = newChecks
 			if checkResponse.Result.Error != nil {
 				value.Result.Error = checkResponse.Result.Error
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/vars.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/vars.go
index 3ede9d020..56bae3e6b 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/vars.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/vars.go
@@ -4,6 +4,6 @@ var (
 	postgresqlTCPPorts   = [4]string{"9631", "7432", "5432", "6432"}
 	opensearchTCPPorts   = [3]string{"9631", "9200", "9300"}
 	a2CsTCPPorts         = [1]string{"22"}
-	postgresBastionPorts = [2]string{"22", "7432"}
-	ossBastionPorts      = [2]string{"22", "9200"}
+	postgresBastionPorts = [1]string{"22"}
+	ossBastionPorts      = [1]string{"22"}
 )
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger.go
index c1a8e4d58..6e100be2e 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger.go
@@ -2,6 +2,7 @@ package hardwareresourcechecktrigger
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
 	"net/http"
@@ -39,10 +40,16 @@ func (ss *HardwareResourceCountCheck) Run(config *models.Config) []models.CheckT
 	// for each and every IP to make the processing simple at the caller end
 
 	if err != nil {
+		statusCode := 500
+		errMessage := err.Error()
+		if resp != nil {
+			statusCode = resp.Error.Code
+			errMessage = resp.Error.Message
+		}
 		hostMap := configutils.GetNodeTypeMap(config.Hardware)
 		for ip, types := range hostMap {
 			for i := 0; i < len(types); i++ {
-				finalResult = append(finalResult, checkutils.PrepareTriggerResponse(nil, ip, types[i], err.Error(), constants.HARDWARE_RESOURCE_COUNT, constants.HARDWARE_RESOURCE_COUNT_MSG, true))
+				finalResult = append(finalResult, checkutils.PrepareTriggerResponse(nil, ip, types[i], errMessage, constants.HARDWARE_RESOURCE_COUNT, constants.HARDWARE_RESOURCE_COUNT_MSG, true, statusCode))
 			}
 		}
 		return finalResult
@@ -82,9 +89,14 @@ func (ss *HardwareResourceCountCheck) TriggerHardwareResourceCountCheck(body int
 	response := models.HardwareResourceCheckResponse{}
 	err = json.Unmarshal(respBody, &response)
 	if err != nil {
-		ss.log.Error("Error while reading unmarshalling response of Hardware resource count check from batch Check API : ", err)
+		ss.log.Error("Error while reading unmarshalled response of Hardware resource count check from batch Check API : ", err)
 		return nil, err
 	}
+	
+	if response.Error.Message != "" {
+		ss.log.Error("Error while calling the Hardware Resource Count: ", response.Error.Message)
+		return &response, errors.New(response.Error.Message) 
+	}
 	return &response, nil
 }
 
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck.go
index 12d6109e5..0c359a6ec 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck.go
@@ -2,6 +2,7 @@ package nfsmountbackupchecktrigger
 
 import (
 	"encoding/json"
+	"errors"
 	"io"
 	"net/http"
 
@@ -40,6 +41,7 @@ func (nbc *NfsBackupConfigCheck) Run(config *models.Config) []models.CheckTrigge
 	}
 
 	nfsMountReq := models.NFSMountRequest{
+		ExternalDbType:         config.ExternalDbType,
 		AutomateNodeIPs:        config.Hardware.AutomateNodeIps,
 		ChefInfraServerNodeIPs: config.Hardware.ChefInfraServerNodeIps,
 		PostgresqlNodeIPs:      config.Hardware.PostgresqlNodeIps,
@@ -50,8 +52,10 @@ func (nbc *NfsBackupConfigCheck) Run(config *models.Config) []models.CheckTrigge
 	//Triggers only one API call for nfs mount API
 	nfsMountAPIResponse, err := nbc.triggerCheckForMountService(nfsMountReq)
 	if err != nil {
-		response := constructErrorResult(config, err)
-		return response
+		if nfsMountAPIResponse!= nil {
+			return constructErrorResult(config, nfsMountAPIResponse.Error.Message, nfsMountAPIResponse.Error.Code)
+		}
+		return constructErrorResult(config, err.Error(), 500)
 
 	}
 	result := constructSuccessResult(*nfsMountAPIResponse)
@@ -76,20 +80,23 @@ func (ss *NfsBackupConfigCheck) triggerCheckForMountService(body models.NFSMount
 	apiResp := &models.NFSMountCheckResponse{}
 	err = json.Unmarshal(respBody, apiResp)
 	if err != nil {
-		ss.log.Error("Error while reading unmarshalling response of NFS Mount respons from batch Check API : ", err)
-		return apiResp, err
+		ss.log.Error("Error while reading unmarshalled response of NFS Mount response from batch Check API : ", err)
+		return nil, err
+	}
+	if apiResp.Error.Message != "" {
+		return apiResp, errors.New(apiResp.Error.Message)
 	}
 	return apiResp, nil
 }
 
 // constructErrorResult constructs the error response when recived from the API
-func constructErrorResult(config *models.Config, err error) []models.CheckTriggerResponse {
+func constructErrorResult(config *models.Config, errMessage string, statusCode int) []models.CheckTriggerResponse {
 	var result []models.CheckTriggerResponse
 
 	hostMap := configutils.GetNodeTypeMap(config.Hardware)
 	for ip, types := range hostMap {
 		for i := 0; i < len(types); i++ {
-			result = append(result, checkutils.PrepareTriggerResponse(nil, ip, types[i], err.Error(), "", "", true))
+			result = append(result, checkutils.PrepareTriggerResponse(nil, ip, types[i], errMessage, "", "", true, statusCode))
 		}
 	}
 
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck.go
index 904000ae7..42cb0a749 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck.go
@@ -27,7 +27,7 @@ func NewOpensearchS3BucketAccessCheck(log logger.Logger, port string) *Opensearc
 func (osb *OpensearchS3BucketAccessCheck) Run(config *models.Config) []models.CheckTriggerResponse {
 	if config.ExternalOS == nil || config.Backup.ObjectStorage == nil {
 		return []models.CheckTriggerResponse{
-			trigger.SkippedTriggerCheckResp(constants.UNKNOWN_HOST, constants.AWS_OPENSEARCH_S3_BUCKET_ACCESS, constants.OPENSEARCH),
+			trigger.SkippedTriggerCheckResp("-", constants.AWS_OPENSEARCH_S3_BUCKET_ACCESS, constants.OPENSEARCH),
 		}
 	}
 
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger.go
index 01edcb5f2..9174d0eed 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger.go
@@ -23,12 +23,16 @@ func NewS3BackupConfigCheck(log logger.Logger, port string) *S3BackupConfigCheck
 }
 
 func (svc *S3BackupConfigCheck) Run(config *models.Config) []models.CheckTriggerResponse {
-	if config.Hardware == nil || config.Backup.ObjectStorage == nil {
+	if config.Hardware == nil {
 		return []models.CheckTriggerResponse{
-			trigger.SkippedTriggerCheckResp(constants.UNKNOWN_HOST, constants.S3_BACKUP_CONFIG, constants.AUTOMATE),
+			trigger.SkippedTriggerCheckResp("-", constants.S3_BACKUP_CONFIG, constants.AUTOMATE),
 		}
 	}
 
+	if config.Backup.ObjectStorage == nil {
+		return s3ConfigSkippedResponse(config, constants.S3_BACKUP_CONFIG)
+	}
+
 	if isObjectStorage(config.Backup) {
 		return emptyResp(config, constants.S3_BACKUP_CONFIG)
 	}
@@ -37,6 +41,20 @@ func (svc *S3BackupConfigCheck) Run(config *models.Config) []models.CheckTrigger
 	return runCheckForS3Config(config.Hardware.AutomateNodeIps, svc.log, svc.port, http.MethodPost, req)
 }
 
+func s3ConfigSkippedResponse(config *models.Config, checkType string) []models.CheckTriggerResponse {
+	var triggerResps []models.CheckTriggerResponse
+
+	for _, ip := range config.Hardware.AutomateNodeIps {
+		triggerResps = append(triggerResps, trigger.SkippedTriggerCheckResp(ip, checkType, constants.AUTOMATE))
+	}
+
+	for _, ip := range config.Hardware.ChefInfraServerNodeIps {
+		triggerResps = append(triggerResps, trigger.SkippedTriggerCheckResp(ip, checkType, constants.CHEF_INFRA_SERVER))
+	}
+
+	return triggerResps
+}
+
 func (ss *S3BackupConfigCheck) GetPortsForMockServer() map[string]map[string][]int {
 	nodeTypePortMap := make(map[string]map[string][]int)
 	return nodeTypePortMap
diff --git a/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation.go b/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation.go
index d5f1b1e6b..a9d528f36 100644
--- a/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation.go
+++ b/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation.go
@@ -152,12 +152,7 @@ func (vc *ValidateCertificateService) validateKeyFormat(privateKeys map[string]s
 		}
 
 		// this is for checking that our private keys are of PKCS8 format or not.
-		_, err := x509.ParsePKCS8PrivateKey(block.Bytes)
-		if err != nil {
-			vc.log.Debugf("%s is not in PKCS8 format", key)
-			invalidFormatKeys += key + ", "
-			continue
-		}
+
 	}
 
 	if invalidFormatKeys == "" {
diff --git a/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice.go b/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice.go
index fa8896155..654bb1f26 100644
--- a/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice.go
+++ b/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice.go
@@ -9,8 +9,6 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/gofiber/fiber/v2"
-
 	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/constants"
 	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
 	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/response"
@@ -188,7 +186,8 @@ func prepareMountResp(ip, nodeType, mountLocation string, mountLocResp *models.N
 	node.NodeType = nodeType
 
 	if err != nil {
-		node.Error = fiber.NewError(http.StatusBadRequest, err.Error())
+		checkList := createCheck("NFS mount", false, "", "NFS mount location not found", "NFS volume should be mounted on "+mountLocation)
+		node.CheckList = append(node.CheckList, checkList)
 		return node
 	}
 	checkMount(mountLocation, &node, mountLocResp)
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice.go b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice.go
index bb4c36769..5961b17a6 100644
--- a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice.go
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice.go
@@ -36,20 +36,27 @@ func NewSoftwareVersionService(logger logger.Logger, CheckPath func(cmd string)
 }
 
 const (
-	AVAILABILITY              = " availability"
-	ENSURE                    = "Ensure "
-	OSFILEPATH                = "/etc/os-release"
-	KERNELFILEPATH            = "/proc/sys/kernel/osrelease"
-	LINUX_VERSION_CHECK       = "Linux Version Check"
-	KERNAL_VERSION_CHECK      = "Kernal Version Check"
-	UBUNTU                    = "Ubuntu"
-	RED_HAT                   = "Red Hat"
-	DEBIAN                    = "Debian"
-	RED_HAT_SUPPORTED_VERSION = 7
-	KERNAL_SUPPORTED_VERSION  = 3.2
+	AVAILABILITY                          = " availability"
+	ENSURE                                = "Ensure "
+	OSFILEPATH                            = "/etc/os-release"
+	KERNELFILEPATH                        = "/proc/sys/kernel/osrelease"
+	LINUX_VERSION_CHECK                   = "Linux Version Check"
+	KERNAL_VERSION_CHECK                  = "Kernal Version Check"
+	UBUNTU                                = "Ubuntu"
+	RED_HAT                               = "Red Hat"
+	AMAZON_LINUX                          = "Amazon Linux"
+	SUSE_LINUX                            = "SUSE Linux"
+	RED_HAT_SUPPORTED_VERSION             = 7
+	KERNAL_SUPPORTED_VERSION              = 3.2
+	KERNAL_SUPPORTED_VERSION_AMAZON_LINUX = 5.10
 )
 
-var cmdCheckArray = []string{"mkdir", "useradd", "chown", "rm", "touch", "truncate", "echo", "sleep", "ls", "grep", "yum", "which", "cp", "curl", "bash", "sysctl", "cat", "sed", "mount", "mv", "systemd", "wget", "exec", "rsync"}
+var cmdCheckArray = []string{"mkdir", "useradd", "usermod", "groupadd", "chown", "chmod",
+	"rm", "touch", "truncate", "echo", "sleep", "ls", "ln",
+	"grep", "which", "cp", "curl", "bash", "sh",
+	"sysctl", "cat", "sed", "mount", "mv", "systemctl",
+	"wget", "rsync", "tar", "find", "sort", "awk",
+	"xargs", "tail", "id"}
 
 func (sv *SoftwareVersionService) GetSoftwareVersionDetails(query string) (*models.SoftwareVersionDetails, error) {
 	sv.logger.Debug("The query parameter entered: ", query)
@@ -78,14 +85,14 @@ func (sv *SoftwareVersionService) GetSoftwareVersionDetails(query string) (*mode
 		}
 		serviceResponseArray = append(serviceResponseArray, checkResponse)
 	}
-	osResponse, err := sv.checkOsVersion(sv.osFilePath)
+	osResponse, osName, err := sv.checkOsVersion(sv.osFilePath)
 	if err != nil {
 		sv.logger.Error("Error while getting the OS Version: ", osResponse.ErrorMsg)
 	}
 	if !osResponse.Passed {
 		serviceResponse.Passed = false
 	}
-	kernelResponse, err := sv.checkKernelVersion(sv.kernelFilePath)
+	kernelResponse, err := sv.checkKernelVersion(sv.kernelFilePath, osName)
 	if err != nil {
 		sv.logger.Error("Error while getting the Kernal Version: ", kernelResponse.ErrorMsg)
 	}
@@ -110,20 +117,20 @@ func (sv *SoftwareVersionService) checkCommandVersion(cmdName string) *models.Ch
 	return successResponse(cmdName+AVAILABILITY, cmdName+" is available")
 }
 
-func (sv *SoftwareVersionService) checkOsVersion(osFilepath string) (*models.Checks, error) {
+func (sv *SoftwareVersionService) checkOsVersion(osFilepath string) (*models.Checks, string, error) {
 	osVersions := map[string][]string{
 		"Red Hat":      {"7,8,9"},
 		"Ubuntu":       {"16.04.x", "18.04.x", "20.04.x", "22.04.x"},
-		"Centos":       {"7"},
+		"CentOS":       {"7"},
 		"Amazon Linux": {"2"},
-		"SUSE Linux":   {"12"},
+		"SUSE Linux":   {"12.5"},
 		"Debian":       {"9", "10", "11", "12"},
 	}
 	checkResponse := &models.Checks{}
 	var osName, osVersion, err = getosutils.GetOsVersion(osFilepath)
 	if err != nil {
 		sv.logger.Error("Enable to get OS Version as the file on the path does not exist: ", err)
-		return failureResponse(LINUX_VERSION_CHECK, "Its not feasible to determine the Operating system version", "Please run automate on the supported platforms."), err
+		return failureResponse(LINUX_VERSION_CHECK, "Its not feasible to determine the Operating system version", "Please run automate on the supported platforms."), osName, err
 	}
 	sv.logger.Debug("Got the OS Version: ", osVersion)
 	sv.logger.Debug("Got the OS Name: ", osName)
@@ -139,7 +146,7 @@ func (sv *SoftwareVersionService) checkOsVersion(osFilepath string) (*models.Che
 		}
 		checkResponse = failureResponse(LINUX_VERSION_CHECK, osName+" version is not supported by automate", ENSURE+osName+" correct version is installed on the node")
 	}
-	return checkResponse, nil
+	return checkResponse, osName, nil
 }
 
 func (sv *SoftwareVersionService) checkOs(osVersions map[string][]string, osVersion string, osName string) bool {
@@ -172,7 +179,7 @@ func (sv *SoftwareVersionService) checkOs(osVersions map[string][]string, osVers
 	return correctVersion
 }
 
-func (sv *SoftwareVersionService) checkKernelVersion(kernelFilePath string) (*models.Checks, error) {
+func (sv *SoftwareVersionService) checkKernelVersion(kernelFilePath, osName string) (*models.Checks, error) {
 	kernelVersion, err := getosutils.GetKernelVersion(kernelFilePath)
 	if err != nil {
 		sv.logger.Error("Enable to get OS Version as the file on the path does not exit: ", err)
@@ -180,6 +187,12 @@ func (sv *SoftwareVersionService) checkKernelVersion(kernelFilePath string) (*mo
 	}
 	sv.logger.Debug("Got the kernal version:", kernelVersion)
 	checkVersion, _ := strconv.ParseFloat(kernelVersion, 64)
+	if strings.Contains(strings.ToLower(osName), strings.ToLower(AMAZON_LINUX)) {
+		if checkVersion == KERNAL_SUPPORTED_VERSION_AMAZON_LINUX {
+			return successResponse(KERNAL_VERSION_CHECK, "Linux kernal version is "+fmt.Sprintf("%.2f", checkVersion)), nil
+		}
+		return failureResponse(KERNAL_VERSION_CHECK, "Linux kernel version is not equal to 5.10", "Use a linux version whose kernel version is equal to 5.10"), nil
+	}
 	if checkVersion >= KERNAL_SUPPORTED_VERSION {
 		return successResponse(KERNAL_VERSION_CHECK, "Linux kernal version is "+fmt.Sprintf("%.2f", checkVersion)), nil
 	}
diff --git a/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil.go b/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil.go
index 2daf246db..8ad3c6d14 100644
--- a/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil.go
+++ b/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil.go
@@ -7,7 +7,7 @@ import (
 	"github.com/gofiber/fiber/v2"
 )
 
-func PrepareTriggerResponse(resp *models.CheckTriggerResponse, host, nodeType, errorString, check, msg string, isError bool) models.CheckTriggerResponse {
+func PrepareTriggerResponse(resp *models.CheckTriggerResponse, host, nodeType, errorString, check, msg string, isError bool, statusCode int) models.CheckTriggerResponse {
 	if isError {
 		return models.CheckTriggerResponse{
 			Host:     host,
@@ -16,7 +16,7 @@ func PrepareTriggerResponse(resp *models.CheckTriggerResponse, host, nodeType, e
 				Passed:  false,
 				Check:   check,
 				Message: msg,
-				Error:   fiber.NewError(fiber.StatusServiceUnavailable, errorString),
+				Error:   fiber.NewError(statusCode, errorString),
 			},
 		}
 	}
diff --git a/components/automate-cli/pkg/verifyserver/utils/httputils/httputil.go b/components/automate-cli/pkg/verifyserver/utils/httputils/httputil.go
index e541be514..2dbc8e83c 100644
--- a/components/automate-cli/pkg/verifyserver/utils/httputils/httputil.go
+++ b/components/automate-cli/pkg/verifyserver/utils/httputils/httputil.go
@@ -3,7 +3,6 @@ package httputils
 import (
 	"bytes"
 	"encoding/json"
-	"errors"
 	"io"
 	"net/http"
 
@@ -45,8 +44,5 @@ func MakeRequest(requestMethod string, url string, body interface{}) (*http.Resp
 	if err != nil {
 		return resp, err
 	}
-	if err == nil && resp.StatusCode != 200 {
-		return resp, errors.New(resp.Status)
-	}
 	return resp, nil
 }
diff --git a/components/docs-chef-io/content/automate/ha_aws_deployment_prerequisites.md b/components/docs-chef-io/content/automate/ha_aws_deployment_prerequisites.md
index 9a46e86c9..f2c93e728 100644
--- a/components/docs-chef-io/content/automate/ha_aws_deployment_prerequisites.md
+++ b/components/docs-chef-io/content/automate/ha_aws_deployment_prerequisites.md
@@ -136,7 +136,7 @@ The first column in the table below represents the source of the connection. The
 | Infra Server  | 443            |                   | 7432                                | 9200                                 |         |               |
 | PostgreSQL    |                |                   | 9631, 7432, 5432, 6432, 9638<br/>UDP 9638 |                                      |         |               |
 | OpenSearch    |                |                   |                                     | 9631, 9200, 9300, 9638 <br/>UDP 9638 |         |               |
-| Bastion       | 22, 9631, 9638 | 22, 9631, 9638    | 22, 9631, 9638, 7432                | 22, 9631, 9638, 9200                 |         | 22            |
+| Bastion       | 22, 9631, 9638, 7799 | 22, 9631, 9638, 7799    | 22, 9631, 9638, 7432, 7799                | 22, 9631, 9638, 9200, 7799                 |         | 22            |
 | Load Balancer | 443, 80        | 443, 80           |                                     |                                      |         |               |
 | Internet Access |     |        |  |     |   80, 443     |      |
 
diff --git a/components/docs-chef-io/content/automate/ha_cert_rotation.md b/components/docs-chef-io/content/automate/ha_cert_rotation.md
index 650d3df71..c44fc5714 100644
--- a/components/docs-chef-io/content/automate/ha_cert_rotation.md
+++ b/components/docs-chef-io/content/automate/ha_cert_rotation.md
@@ -41,7 +41,7 @@ If you want to rotate certificates of the entire cluster, then you can follow th
 
 - To rotate certificates of automate cluster:
 
-`chef-automate cert-rotate --public-cert <path of public certificate of automate node> --private-cert <path of private certificate of automate node> --root-ca <path of root certificate of automate load balancer> --a2`
+`chef-automate cert-rotate --public-cert <path of public certificate of automate node> --private-cert <path of private certificate of automate node> --a2`
 
 You can also use `--automate` or `-a` instead of a2 flag
 
@@ -95,3 +95,24 @@ You can also use `--opensearch` or `-o` instead of the os flag
 
 {{< note >}} Since admin-cert and admin-key are common in all nodes, So if you want to rotate admin-cert and admin-key, you must first run this open search cluster command: 
 `chef-automate cert-rotate --public-cert <path of public certificate> --private-cert <path of private certificate> --root-ca <path of root certificate> --admin-cert <path of admin certificate> --admin-key <path of admin key> --os`{{< /note >}}
+
+
+### Rotate Automate Load Balancer Root CA
+
+To rotate the Automate Load balancer root certificate: 
+
+1. Create a root_ca.toml file with the following content. Replace server_name with Automate Fqdn and root_cert with Automate Load balancer root certificate. 
+
+    ```toml
+    [cs_nginx.v1.sys.ngx.http]
+      ssl_verify_depth = 6
+    [global.v1.external.automate.ssl]
+      server_name = "https://<automatefqdn.example.com>"
+      root_cert = """<Root_CA_Content>"""
+    ```
+
+1. Run the following command to apply your configuration on Chef-Server from bastion:
+
+    ```shell
+    chef-automate config patch root_ca.toml --cs
+    ```
diff --git a/components/docs-chef-io/content/automate/ha_on_premises_deployment_prerequisites.md b/components/docs-chef-io/content/automate/ha_on_premises_deployment_prerequisites.md
index e7ba61560..3bd02be15 100644
--- a/components/docs-chef-io/content/automate/ha_on_premises_deployment_prerequisites.md
+++ b/components/docs-chef-io/content/automate/ha_on_premises_deployment_prerequisites.md
@@ -129,7 +129,7 @@ The first column in the table below represents the source of the connection. The
 | Infra Server  | 443            |                   | 7432                                | 9200                                 |         |               |
 | PostgreSQL    |                |                   | 9631, 7432, 5432, 6432, 9638<br/>UDP 9638 |                                      |         |               |
 | OpenSearch    |                |                   |                                     | 9631, 9200, 9300, 9638 <br/>UDP 9638 |         |               |
-| Bastion       | 22, 9631, 9638 | 22, 9631, 9638    | 22, 9631, 9638, 7432                | 22, 9631, 9638, 9200                 |         | 22            |
+| Bastion       | 22, 9631, 9638, 7799 | 22, 9631, 9638, 7799    | 22, 9631, 9638, 7432, 7799                | 22, 9631, 9638, 9200, 7799                 |         | 22            |
 | Load Balancer | 443, 80        | 443, 80           |                                     |                                      |         |               |
 
 {{< note >}} Custom SSH port is supported, but use the same port across all the machines. {{< /note >}}
diff --git a/lib/config/hadeployconfigverify.go b/lib/config/hadeployconfigverify.go
index b19c5c665..434e93556 100644
--- a/lib/config/hadeployconfigverify.go
+++ b/lib/config/hadeployconfigverify.go
@@ -206,7 +206,7 @@ func (c *HaDeployConfig) verifyAutomateSettings() error {
 		errorList.PushBack(err)
 	}
 	if automateSettings.EnableCustomCerts {
-		if err := validateAutomateCerts(automateSettings); err != nil {
+		if err := validateAutomateCerts(c); err != nil {
 			errorList.PushBack(err)
 		}
 		if c.IsExistingInfra() {
@@ -227,7 +227,7 @@ func (c *HaDeployConfig) verifyChefServerSettings() error {
 		errorList.PushBack(err)
 	}
 	if chefServerSettings.EnableCustomCerts {
-		if err := validateChefServerCerts(chefServerSettings); err != nil {
+		if err := validateChefServerCerts(c); err != nil {
 			errorList.PushBack(err)
 		}
 		if c.IsExistingInfra() {
@@ -248,7 +248,7 @@ func (c *HaDeployConfig) verifyOpensearchSettings() error {
 		errorList.PushBack(err)
 	}
 	if opensearchSettings.EnableCustomCerts {
-		if err := validateOpensearchCerts(opensearchSettings); err != nil {
+		if err := validateOpensearchCerts(c); err != nil {
 			errorList.PushBack(err)
 		}
 		if c.IsExistingInfra() {
@@ -269,7 +269,7 @@ func (c *HaDeployConfig) verifyPostgresqlSettings() error {
 		errorList.PushBack(err)
 	}
 	if postgresqlSettings.EnableCustomCerts {
-		if err := validatePostgresqlCerts(postgresqlSettings); err != nil {
+		if err := validatePostgresqlCerts(c); err != nil {
 			errorList.PushBack(err)
 		}
 		if c.IsExistingInfra() {
diff --git a/lib/config/helper.go b/lib/config/helper.go
index 860cd4209..837a12518 100644
--- a/lib/config/helper.go
+++ b/lib/config/helper.go
@@ -16,6 +16,11 @@ import (
 	"github.com/chef/automate/components/local-user-service/password"
 )
 
+var (
+	returnErrorPublicKeyMsg = "cannot find public key for ip %s"
+	returnErrorPrivetKeyMsg = "cannot find private key for ip %s"
+)
+
 type keydetails struct {
 	key      string
 	certtype string
@@ -191,30 +196,72 @@ func validateAutomateAdminPassword(automateSettings *ConfigAutomateSettings) err
 	return nil
 }
 
-func validateAutomateCerts(automateSettings *ConfigAutomateSettings) error {
-	if len(strings.TrimSpace(automateSettings.FqdnRootCA)) < 1 ||
-		len(strings.TrimSpace(automateSettings.PrivateKey)) < 1 ||
-		len(strings.TrimSpace(automateSettings.PublicKey)) < 1 {
-		return fmt.Errorf("automate root_ca and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+func validateAutomateCerts(depConfig *HaDeployConfig) error {
+	// If CertByIp is available validate it is available for all the nodes.
+	if depConfig.Automate.Config.CertsByIP == nil || len(*depConfig.Automate.Config.CertsByIP) == 0 {
+		if len(strings.TrimSpace(depConfig.Automate.Config.PrivateKey)) < 1 ||
+			len(strings.TrimSpace(depConfig.Automate.Config.PublicKey)) < 1 {
+			return fmt.Errorf("automate root_ca and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+		}
+
+		return checkCertValid([]keydetails{
+			{key: depConfig.Automate.Config.PrivateKey, certtype: PRIVATE_KEY, svc: AUTOMATE},
+			{key: depConfig.Automate.Config.PublicKey, certtype: PUBLIC_KEY, svc: AUTOMATE},
+		})
 	}
 
-	return checkCertValid([]keydetails{
-		{key: automateSettings.FqdnRootCA, certtype: ROOT_CA, svc: AUTOMATE},
-		{key: automateSettings.PrivateKey, certtype: PRIVATE_KEY, svc: AUTOMATE},
-		{key: automateSettings.PublicKey, certtype: PUBLIC_KEY, svc: AUTOMATE},
-	})
+	// If CertByIp available then check it's availabe for all the nodes
+	for _, v := range *depConfig.Automate.Config.CertsByIP {
+		if v.PrivateKey == "" {
+			return fmt.Errorf(returnErrorPrivetKeyMsg, v.IP)
+		}
+		if v.PublicKey == "" {
+			return fmt.Errorf(returnErrorPublicKeyMsg, v.IP)
+		}
+
+		if err := checkCertValid([]keydetails{
+			{key: v.PrivateKey, certtype: PRIVATE_KEY, svc: AUTOMATE},
+			{key: v.PublicKey, certtype: PUBLIC_KEY, svc: AUTOMATE},
+		}); err != nil {
+			return err
+		}
+	}
+
+	return nil
 }
 
-func validateChefServerCerts(chefServerSettings *ConfigSettings) error {
-	if len(strings.TrimSpace(chefServerSettings.PrivateKey)) < 1 ||
-		len(strings.TrimSpace(chefServerSettings.PublicKey)) < 1 {
-		return fmt.Errorf("chefServer public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+func validateChefServerCerts(depConfig *HaDeployConfig) error {
+	// If CertByIp is available validate it is available for all the nodes.
+	if depConfig.ChefServer.Config.CertsByIP == nil || len(*depConfig.ChefServer.Config.CertsByIP) == 0 {
+		if len(strings.TrimSpace(depConfig.ChefServer.Config.PrivateKey)) < 1 ||
+			len(strings.TrimSpace(depConfig.ChefServer.Config.PublicKey)) < 1 {
+			return fmt.Errorf("chefServer public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+		}
+
+		return checkCertValid([]keydetails{
+			{key: depConfig.ChefServer.Config.PrivateKey, certtype: PRIVATE_KEY, svc: CHEFSERVER},
+			{key: depConfig.ChefServer.Config.PublicKey, certtype: PUBLIC_KEY, svc: CHEFSERVER},
+		})
+	}
+
+	// If CertByIp available then check it's availabe for all the nodes
+	for _, v := range *depConfig.ChefServer.Config.CertsByIP {
+		if v.PrivateKey == "" {
+			return fmt.Errorf(returnErrorPrivetKeyMsg, v.IP)
+		}
+		if v.PublicKey == "" {
+			return fmt.Errorf(returnErrorPublicKeyMsg, v.IP)
+		}
+
+		if err := checkCertValid([]keydetails{
+			{key: v.PrivateKey, certtype: PRIVATE_KEY, svc: CHEFSERVER},
+			{key: v.PublicKey, certtype: PUBLIC_KEY, svc: CHEFSERVER},
+		}); err != nil {
+			return err
+		}
 	}
 
-	return checkCertValid([]keydetails{
-		{key: chefServerSettings.PrivateKey, certtype: PRIVATE_KEY, svc: CHEFSERVER},
-		{key: chefServerSettings.PublicKey, certtype: PUBLIC_KEY, svc: CHEFSERVER},
-	})
+	return nil
 }
 
 func checkCertValid(keys []keydetails) error {
@@ -249,36 +296,95 @@ func validateRootCACertificate(certBytes []byte, svc string) error {
 	return nil
 }
 
-func validatePostgresqlCerts(postgresqlSettings *ConfigSettings) error {
-	if len(strings.TrimSpace(postgresqlSettings.RootCA)) < 1 ||
-		len(strings.TrimSpace(postgresqlSettings.PrivateKey)) < 1 ||
-		len(strings.TrimSpace(postgresqlSettings.PublicKey)) < 1 {
-		return fmt.Errorf("postgresql root_ca and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+func validatePostgresqlCerts(depConfig *HaDeployConfig) error {
+	if depConfig.Postgresql.Config.CertsByIP == nil || len(*depConfig.Postgresql.Config.CertsByIP) == 0 {
+		if len(strings.TrimSpace(depConfig.Postgresql.Config.RootCA)) < 1 ||
+			len(strings.TrimSpace(depConfig.Postgresql.Config.PrivateKey)) < 1 ||
+			len(strings.TrimSpace(depConfig.Postgresql.Config.PublicKey)) < 1 {
+			return fmt.Errorf("postgresql root_ca and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+		}
+
+		return checkCertValid([]keydetails{
+			{key: depConfig.Postgresql.Config.RootCA, certtype: ROOT_CA, svc: POSTGRESQL},
+			{key: depConfig.Postgresql.Config.PrivateKey, certtype: PRIVATE_KEY, svc: POSTGRESQL},
+			{key: depConfig.Postgresql.Config.PublicKey, certtype: PUBLIC_KEY, svc: POSTGRESQL},
+		})
 	}
 
-	return checkCertValid([]keydetails{
-		{key: postgresqlSettings.RootCA, certtype: ROOT_CA, svc: POSTGRESQL},
-		{key: postgresqlSettings.PrivateKey, certtype: PRIVATE_KEY, svc: POSTGRESQL},
-		{key: postgresqlSettings.PublicKey, certtype: PUBLIC_KEY, svc: POSTGRESQL},
-	})
+	if depConfig.Postgresql.Config.RootCA == "" {
+		return fmt.Errorf("cannot find root_ca for ip for PostgresSQL")
+	}
+
+	// If CertByIp available then check it's availabe for all the nodes
+	for _, v := range *depConfig.Postgresql.Config.CertsByIP {
+		if v.PrivateKey == "" {
+			return fmt.Errorf(returnErrorPrivetKeyMsg, v.IP)
+		}
+
+		if v.PublicKey == "" {
+			return fmt.Errorf(returnErrorPublicKeyMsg, v.IP)
+		}
+
+		if err := checkCertValid([]keydetails{
+			{key: depConfig.Postgresql.Config.RootCA, certtype: ROOT_CA, svc: POSTGRESQL},
+			{key: v.PrivateKey, certtype: PRIVATE_KEY, svc: POSTGRESQL},
+			{key: v.PublicKey, certtype: PUBLIC_KEY, svc: POSTGRESQL},
+		}); err != nil {
+			return err
+		}
+
+	}
+
+	return nil
 }
 
-func validateOpensearchCerts(opensearchSettings *ConfigOpensearchSettings) error {
-	if len(strings.TrimSpace(opensearchSettings.RootCA)) < 1 ||
-		len(strings.TrimSpace(opensearchSettings.AdminKey)) < 1 ||
-		len(strings.TrimSpace(opensearchSettings.AdminCert)) < 1 ||
-		len(strings.TrimSpace(opensearchSettings.PrivateKey)) < 1 ||
-		len(strings.TrimSpace(opensearchSettings.PublicKey)) < 1 {
+func validateOpensearchCerts(depConfig *HaDeployConfig) error {
+	if depConfig.Opensearch.Config.CertsByIP == nil || len(*depConfig.Opensearch.Config.CertsByIP) == 0 {
+		if len(strings.TrimSpace(depConfig.Opensearch.Config.RootCA)) < 1 ||
+			len(strings.TrimSpace(depConfig.Opensearch.Config.AdminKey)) < 1 ||
+			len(strings.TrimSpace(depConfig.Opensearch.Config.AdminCert)) < 1 ||
+			len(strings.TrimSpace(depConfig.Opensearch.Config.PrivateKey)) < 1 ||
+			len(strings.TrimSpace(depConfig.Opensearch.Config.PublicKey)) < 1 {
+			return fmt.Errorf("opensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
+		}
+
+		return checkCertValid([]keydetails{
+			{key: depConfig.Opensearch.Config.RootCA, certtype: ROOT_CA, svc: OPENSEARCH},
+			{key: depConfig.Opensearch.Config.AdminKey, certtype: ADMIN_KEY, svc: OPENSEARCH},
+			{key: depConfig.Opensearch.Config.AdminCert, certtype: ADMIN_CERT, svc: OPENSEARCH},
+			{key: depConfig.Opensearch.Config.PrivateKey, certtype: PRIVATE_KEY, svc: OPENSEARCH},
+			{key: depConfig.Opensearch.Config.PublicKey, certtype: PUBLIC_KEY, svc: OPENSEARCH},
+		})
+	}
+
+	if len(strings.TrimSpace(depConfig.Opensearch.Config.RootCA)) < 1 ||
+		len(strings.TrimSpace(depConfig.Opensearch.Config.AdminKey)) < 1 ||
+		len(strings.TrimSpace(depConfig.Opensearch.Config.AdminCert)) < 1 {
 		return fmt.Errorf("opensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false")
 	}
 
-	return checkCertValid([]keydetails{
-		{key: opensearchSettings.RootCA, certtype: ROOT_CA, svc: OPENSEARCH},
-		{key: opensearchSettings.AdminKey, certtype: ADMIN_KEY, svc: OPENSEARCH},
-		{key: opensearchSettings.AdminCert, certtype: ADMIN_CERT, svc: OPENSEARCH},
-		{key: opensearchSettings.PrivateKey, certtype: PRIVATE_KEY, svc: OPENSEARCH},
-		{key: opensearchSettings.PublicKey, certtype: PUBLIC_KEY, svc: OPENSEARCH},
-	})
+	// If CertByIp available then check it's availabe for all the nodes
+	for _, v := range *depConfig.Opensearch.Config.CertsByIP {
+		if v.PrivateKey == "" {
+			return fmt.Errorf(returnErrorPrivetKeyMsg, v.IP)
+		}
+		if v.PublicKey == "" {
+			return fmt.Errorf(returnErrorPublicKeyMsg, v.IP)
+		}
+
+		if err := checkCertValid([]keydetails{
+			{key: depConfig.Opensearch.Config.RootCA, certtype: ROOT_CA, svc: OPENSEARCH},
+			{key: depConfig.Opensearch.Config.AdminKey, certtype: ADMIN_KEY, svc: OPENSEARCH},
+			{key: depConfig.Opensearch.Config.AdminCert, certtype: ROOT_CA, svc: OPENSEARCH},
+			{key: v.PrivateKey, certtype: PRIVATE_KEY, svc: OPENSEARCH},
+			{key: v.PublicKey, certtype: PUBLIC_KEY, svc: OPENSEARCH},
+		}); err != nil {
+			return err
+		}
+
+	}
+
+	return nil
 }
 
 func validateIPList(ipList []string, prefix string) error {
diff --git a/lib/reporting/helperForVerification.go b/lib/reporting/helperForVerification.go
index 8895c8963..02b0e03ef 100644
--- a/lib/reporting/helperForVerification.go
+++ b/lib/reporting/helperForVerification.go
@@ -97,7 +97,14 @@ func updateTablesWithData(reporting Reporting, nodeInfo map[string][]Info, keyMa
 	}
 }
 
+func sortTablesByIps(info []Info) {
+	sort.Slice(info, func(i, j int) bool {
+		return info[i].Hostip < info[j].Hostip
+	})
+}
+
 func createSingleNodeRowsForBothTables(title string, nodeInfo []Info, reporting Reporting, summaryMap map[string]SummaryInfo) ([]table.Row, []table.Row) {
+	sortTablesByIps(nodeInfo)
 	var statusTableRows []table.Row
 	var summaryTableRows []table.Row
 	for idx, value := range nodeInfo {
diff --git a/lib/reporting/reporting.go b/lib/reporting/reporting.go
index 7741e1ef1..57befca9c 100644
--- a/lib/reporting/reporting.go
+++ b/lib/reporting/reporting.go
@@ -121,7 +121,7 @@ func (r *ReportingModule) ChangeColour(fgColor int, msg string) string {
 	case Yellow:
 		return color.New(color.FgYellow).Sprint(msg)
 	case Grey:
-		return color.New(90).Sprint(msg)
+		return color.New(color.FgHiBlack).Sprint(msg)
 	default:
 		return msg
 	}
diff --git a/terraform/a2ha-terraform/modules/aws/security.tf b/terraform/a2ha-terraform/modules/aws/security.tf
index 8483876ce..c3c1fb592 100644
--- a/terraform/a2ha-terraform/modules/aws/security.tf
+++ b/terraform/a2ha-terraform/modules/aws/security.tf
@@ -121,6 +121,16 @@ resource "aws_security_group_rule" "ingress_chef_automate_allow_443_tcp" {
   security_group_id = aws_security_group.chef_automate_ui.id
 }
 
+# Allow Verify service
+resource "aws_security_group_rule" "ingress_chef_automate_allow_7799_tcp" {
+  type              = "ingress"
+  from_port         = 7799
+  to_port           = 7799
+  protocol          = "tcp"
+  cidr_blocks       = ["0.0.0.0/0"]
+  security_group_id = aws_security_group.chef_automate.id
+}
+
 # Allow elasticsearch clients
 resource "aws_security_group_rule" "ingress_chef_automate_allow_elasticsearch_tcp" {
   type                     = "ingress"


Test patch:
diff --git a/components/automate-cli/cmd/chef-automate/certRotate_test.go b/components/automate-cli/cmd/chef-automate/certRotate_test.go
index 4c3b58ec9..cde597978 100644
--- a/components/automate-cli/cmd/chef-automate/certRotate_test.go
+++ b/components/automate-cli/cmd/chef-automate/certRotate_test.go
@@ -260,9 +260,8 @@ func TestGetCerts(t *testing.T) {
 				automate:        true,
 				privateCertPath: ValidCertPath,
 				publicCertPath:  ValidCertPath,
-				rootCAPath:      ValidCertPath,
 			},
-			rootCaWant:      FileContent,
+			rootCaWant:      "",
 			publicCertWant:  FileContent,
 			privateCertWant: FileContent,
 			adminCertWant:   "",
@@ -349,26 +348,11 @@ func TestGetCerts(t *testing.T) {
 				publicCertPath:  ValidCertPath,
 			},
 			rootCaWant:      "",
-			publicCertWant:  "",
-			privateCertWant: "",
-			adminCertWant:   "",
-			adminKeyWant:    "",
-			isError:         true,
-		},
-		{
-			testCaseDescription: "All paths given but root-ca path is invalid(file not exist) flag is automate service",
-			flagsObj: certRotateFlags{
-				automate:        true,
-				privateCertPath: ValidCertPath,
-				publicCertPath:  ValidCertPath,
-				rootCAPath:      "./xyx-cert.go",
-			},
-			rootCaWant:      "",
-			publicCertWant:  "",
-			privateCertWant: "",
+			publicCertWant:  FileContent,
+			privateCertWant: FileContent,
 			adminCertWant:   "",
 			adminKeyWant:    "",
-			isError:         true,
+			isError:         false,
 		},
 		{
 			testCaseDescription: "Some mandatory path not given and flag is opensearch service",
diff --git a/components/automate-cli/cmd/chef-automate/deployedConfig_test.go b/components/automate-cli/cmd/chef-automate/deployedConfig_test.go
index 66f3f6efc..1e56db571 100644
--- a/components/automate-cli/cmd/chef-automate/deployedConfig_test.go
+++ b/components/automate-cli/cmd/chef-automate/deployedConfig_test.go
@@ -5,6 +5,7 @@ import (
 
 	dc "github.com/chef/automate/api/config/deployment"
 	"github.com/chef/automate/lib/config"
+	"github.com/pkg/errors"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -308,53 +309,107 @@ func (m *MockPullConfigs) getOsCertsByIp(configKeysMap map[string]*ConfigKeys) [
 	return m.getOsCertsByIpFunc(configKeysMap)
 }
 
-func TestPopulateHaCommonConfig_ExistingInfraConfig(t *testing.T) {
-	mockPullConfigs := &MockPullConfigs{
-		fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
-			return existingInfraConfig, nil
-		},
-		fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
-			return nil, nil
+func TestPopulateHaCommonConfig(t *testing.T) {
+	tests := []struct {
+		name                string
+		mockPullConfigs     *MockPullConfigs
+		getModeOfDeployment func() string
+		err                 string
+		wantErr             bool
+	}{
+		{
+			name: "ExistingInfraConfig passed",
+			mockPullConfigs: &MockPullConfigs{
+				fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
+					return existingInfraConfig, nil
+				},
+				fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
+					return nil, nil
+				},
+			},
+			getModeOfDeployment: func() string {
+				return EXISTING_INFRA_MODE
+			},
+			wantErr: false,
 		},
-	}
-
-	haDeployConfig, err := PopulateHaCommonConfig(mockPullConfigs)
-
-	assert.Nil(t, err)
-	assert.NotNil(t, haDeployConfig)
-}
-
-func TestPopulateHaCommonConfig_AwsConfig(t *testing.T) {
-	// Create a mock instance of PullConfigs
-	mockPullConfigs := &MockPullConfigs{
-		fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
-			return nil, nil
+		{
+			name: "ExistingInfraConfig failed",
+			mockPullConfigs: &MockPullConfigs{
+				fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
+					return nil, errors.New("Error while config generation")
+				},
+				fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
+					return nil, nil
+				},
+			},
+			getModeOfDeployment: func() string {
+				return EXISTING_INFRA_MODE
+			},
+			err:     "Error while config generation",
+			wantErr: true,
 		},
-		fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
-			return awsConfig, nil
+		{
+			name: "AwsConfig passed",
+			mockPullConfigs: &MockPullConfigs{
+				fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
+					return nil, nil
+				},
+				fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
+					return awsConfig, nil
+				},
+			},
+			getModeOfDeployment: func() string {
+				return AWS_MODE
+			},
+			wantErr: false,
 		},
-	}
-
-	haDeployConfig, err := PopulateHaCommonConfig(mockPullConfigs)
-
-	assert.Nil(t, err)
-	assert.NotNil(t, haDeployConfig)
-}
-
-func TestPopulateHaCommonConfig_NoConfigFound(t *testing.T) {
-	mockPullConfigs := &MockPullConfigs{
-		fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
-			return nil, nil
+		{
+			name: "AwsConfig failed",
+			mockPullConfigs: &MockPullConfigs{
+				fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
+					return nil, nil
+				},
+				fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
+					return nil, errors.New("Error while config generation")
+				},
+			},
+			getModeOfDeployment: func() string {
+				return AWS_MODE
+			},
+			err:     "Error while config generation",
+			wantErr: true,
 		},
-		fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
-			return nil, nil
+		{
+			name: "NoConfigFound",
+			mockPullConfigs: &MockPullConfigs{
+				fetchInfraConfigFunc: func() (*ExistingInfraConfigToml, error) {
+					return nil, nil
+				},
+				fetchAwsConfigFunc: func() (*AwsConfigToml, error) {
+					return nil, nil
+				},
+			},
+			getModeOfDeployment: func() string {
+				return AWS_MODE
+			},
+			err:     "deployed config was not found",
+			wantErr: true,
 		},
 	}
-
-	haDeployConfig, err := PopulateHaCommonConfig(mockPullConfigs)
-	assert.NotNil(t, err)
-	assert.Nil(t, haDeployConfig)
-	assert.EqualError(t, err, "deployed config was not found")
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			GetModeOfDeployment = tt.getModeOfDeployment
+			haDeployConfig, err := PopulateHaCommonConfig(tt.mockPullConfigs)
+			if tt.wantErr {
+				assert.Nil(t, haDeployConfig)
+				assert.Error(t, err)
+				assert.EqualError(t, err, tt.err)
+			} else {
+				assert.Nil(t, err)
+				assert.NotNil(t, haDeployConfig)
+			}
+		})
+	}
 }
 
 func TestCopyCertsByIP(t *testing.T) {
diff --git a/components/automate-cli/cmd/chef-automate/verify_test.go b/components/automate-cli/cmd/chef-automate/verify_test.go
index df3040c50..aa73d3c01 100644
--- a/components/automate-cli/cmd/chef-automate/verify_test.go
+++ b/components/automate-cli/cmd/chef-automate/verify_test.go
@@ -6,12 +6,15 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
 	"github.com/chef/automate/components/automate-cli/pkg/verifysystemdcreate"
 	"github.com/chef/automate/lib/config"
 	"github.com/chef/automate/lib/httputils"
 	"github.com/chef/automate/lib/majorupgrade_utils"
+	"github.com/chef/automate/lib/reporting"
 	"github.com/chef/automate/lib/sshutils"
 	"github.com/chef/automate/lib/version"
+	"github.com/gofiber/fiber/v2"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -603,3 +606,119 @@ func newMockVerifyCmdFlow(mockHttputils *httputils.MockHTTPClient, cw *majorupgr
 		mockVerifyCmdDeps,
 	)
 }
+
+func TestBuildReports(t *testing.T) {
+	type args struct {
+		batchCheckResults []models.BatchCheckResult
+	}
+	tests := []struct {
+		name string
+		args args
+		want []reporting.VerificationReport
+	}{
+		{
+			name: "If Report is successfully created",
+			args: args{
+				batchCheckResults: []models.BatchCheckResult{
+					{
+						NodeType: "automate",
+						Ip:       "1.1.1.1",
+						Tests: []models.ApiResult{
+							{
+								Passed:  true,
+								Message: "SSH User Access Check",
+								Check:   "ssh-user",
+								Checks: []models.Checks{
+									{
+										Title:         "SSH user accessible",
+										Passed:        true,
+										SuccessMsg:    "SSH user is accessible for the node: 1.1.1.1",
+										ErrorMsg:      "",
+										ResolutionMsg: "",
+									},
+									{
+										Title:         "Sudo password valid",
+										Passed:        true,
+										SuccessMsg:    "SSH user sudo password is valid for the node: 1.1.1.1",
+										ErrorMsg:      "",
+										ResolutionMsg: "",
+									},
+								},
+								Skipped: false,
+							},
+						},
+					},
+				},
+			},
+			want: []reporting.VerificationReport{
+				{
+					TableKey: "automate",
+					Report: reporting.Info{
+						Hostip:    "1.1.1.1",
+						Parameter: "ssh-user",
+						Status:    "Success",
+						StatusMessage: &reporting.StatusMessage{
+							MainMessage: "SSH User Access Check - Success",
+							SubMessage:  nil,
+						},
+						SummaryInfo: &reporting.SummaryInfo{
+							SuccessfulCount: 2,
+							FailedCount:     0,
+							ToResolve:       nil,
+						},
+					},
+				},
+			},
+		},
+		{
+			name: "Error was there form the handler or Trigger response",
+			args: args{
+				batchCheckResults: []models.BatchCheckResult{
+					{
+						NodeType: "automate",
+						Ip: "1.1.1.1",
+						Tests: []models.ApiResult{
+							{
+								Passed: false,
+								Message: "SSH User Access Check",
+								Check: "ssh-user",
+								Checks: nil,
+								Error: &fiber.Error{
+									Code: 400,
+									Message: "Permissions on the ssh key file do not satisfy the requirement",
+								},
+								Skipped: false,
+							},
+						},
+					},
+				},
+			},
+			want: []reporting.VerificationReport{
+				{
+					TableKey: "automate",
+					Report: reporting.Info{
+						Hostip:    "1.1.1.1",
+						Parameter: "ssh-user",
+						Status:    "Failed",
+						StatusMessage: &reporting.StatusMessage{
+							MainMessage: "SSH User Access Check - Failed",
+							SubMessage: nil,
+						},
+						SummaryInfo: &reporting.SummaryInfo{
+							SuccessfulCount: 0,
+							FailedCount: 1,
+							ToResolve: []string{"Permissions on the ssh key file do not satisfy the requirement"},
+						},
+					},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got := buildReports(tt.args.batchCheckResults)
+			assert.Equal(t, got, tt.want)
+
+		})
+	}
+}
diff --git a/components/automate-cli/pkg/verifyserver/models/batchcheck_test.go b/components/automate-cli/pkg/verifyserver/models/batchcheck_test.go
index 4a5d29526..aca4d2b7a 100644
--- a/components/automate-cli/pkg/verifyserver/models/batchcheck_test.go
+++ b/components/automate-cli/pkg/verifyserver/models/batchcheck_test.go
@@ -343,7 +343,7 @@ func TestPopulateWith(t *testing.T) {
 			filePath: "./testdata/InvalidHaOnPrem.toml",
 			want:     &Config{},
 			wantErr:  true,
-			err:      errors.New("invalid or empty: ssh_user\ninvalid or empty: ssh_key_file\nautomate private ip 1324.2534.1is not valid\ninvalid or empty: chef_server_private_ips\ninvalid or empty: opensearch_private_ips\ninvalid or empty: postgresql_private_ips\nurl should not include the protocol (http:// or https://): automate fqdn\nempty value: automate instance_count\ninvalid value 'automate.toml' for field 'config_file'. Expected values are: configs/automate.toml\ninvalid format. Failed to decode root_ca for automate\ninvalid format. Failed to decode private_key for automate\ninvalid format. Failed to decode public_key for automate\ninvalid format. Failed to decode private_key for automate ip\ninvalid format. Failed to decode public_key for automate ip\ninvalid value 'chef server instance_count' for field 'two'\ninvalid format. Failed to decode private_key for chef-infra-server\ninvalid format. Failed to decode public_key for chef-infra-server\ninvalid format. Failed to decode private_key for chef server ip\ninvalid format. Failed to decode public_key for chef server ip\nempty value: opensearch instance_count\nopensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false\nopensearch ippublic_key and/or private_key are missing in certs_by_ip. Otherwise set enable_custom_certs to false\nempty value: postgresql instance_count\ninvalid format. Failed to decode root_ca for postgresql\ninvalid format. Failed to decode private_key for postgresql\ninvalid format. Failed to decode public_key for postgresql\npostgresql ip 0.0.1 for certs is not valid\ninvalid format. Failed to decode private_key for postgresql ip\ninvalid format. Failed to decode public_key for postgresql ip"),
+			err:      errors.New("invalid or empty: ssh_user\ninvalid or empty: ssh_key_file\nautomate private ip 1324.2534.1is not valid\ninvalid or empty: chef_server_private_ips\ninvalid or empty: opensearch_private_ips\ninvalid or empty: postgresql_private_ips\nurl should not include the protocol (http:// or https://): automate fqdn\nempty value: automate instance_count\ninvalid value 'automate.toml' for field 'config_file'. Expected values are: configs/automate.toml\ninvalid format. Failed to decode private_key for automate\ninvalid format. Failed to decode public_key for automate\ninvalid format. Failed to decode private_key for automate ip\ninvalid format. Failed to decode public_key for automate ip\ninvalid value 'chef server instance_count' for field 'two'\ninvalid format. Failed to decode private_key for chef-infra-server\ninvalid format. Failed to decode public_key for chef-infra-server\ninvalid format. Failed to decode private_key for chef server ip\ninvalid format. Failed to decode public_key for chef server ip\nempty value: opensearch instance_count\nopensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false\nopensearch ippublic_key and/or private_key are missing in certs_by_ip. Otherwise set enable_custom_certs to false\nempty value: postgresql instance_count\ninvalid format. Failed to decode root_ca for postgresql\ninvalid format. Failed to decode private_key for postgresql\ninvalid format. Failed to decode public_key for postgresql\npostgresql ip 0.0.1 for certs is not valid\ninvalid format. Failed to decode private_key for postgresql ip\ninvalid format. Failed to decode public_key for postgresql ip"),
 		},
 		{
 			name:     "PopulateWith OnPrem Db Aws Managed Config",
diff --git a/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount_test.go b/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount_test.go
index bf70b3a48..19b6e3885 100644
--- a/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount_test.go
+++ b/components/automate-cli/pkg/verifyserver/server/api/v1/nfsmount_test.go
@@ -519,6 +519,7 @@ func TestNFSMount(t *testing.T) {
 				]
 			}`,
 			RequestBody: `{
+				"external_db_type":"",
 				"automate_node_ips": [
 					"localhost",
 					"localhost"
@@ -554,7 +555,7 @@ func TestNFSMount(t *testing.T) {
 			RequestBody: "Invalid Body",
 		},
 		{
-			TestName:     "Not Given all the required IPs",
+			TestName:     "Not Given all the required IPs in On-Prem chef managed",
 			ExpectedCode: 400,
 			ExpectedBody: `{
 				"status": "FAILED",
@@ -565,6 +566,23 @@ func TestNFSMount(t *testing.T) {
 				}
 			}`,
 			RequestBody: `{
+				"external_db_type":"",
+				"automate_node_ips": []
+			}`,
+		},
+		{
+			TestName:     "Not Given all the required IPs in On-Prem self managed",
+			ExpectedCode: 400,
+			ExpectedBody: `{
+				"status": "FAILED",
+				"result": null,
+				"error": {
+					"code": 400,
+					"message": "AutomateNodeIPs or ChefInfraServerNodeIPs cannot be empty"
+				}
+			}`,
+			RequestBody: `{
+				"external_db_type":"self-managed",
 				"automate_node_ips": []
 			}`,
 		},
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger_test.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger_test.go
index f5b06fa8a..de50e43a4 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger/firewallchecktrigger_test.go
@@ -109,12 +109,6 @@ const (
 						"success_msg": "The <protocol> service running at <destination_node_ip>:<destination_node_port> is reachable fro <source_node_ip>",
 						"error_msg": "",
 						"resolution_msg": ""
-					},{
-						"title": "Check for reachability of service at destination port from the source node",
-						"passed": true,
-						"success_msg": "The <protocol> service running at <destination_node_ip>:<destination_node_port> is reachable fro <source_node_ip>",
-						"error_msg": "",
-						"resolution_msg": ""
 					}
 				]
 			}
@@ -159,12 +153,6 @@ const (
 						"success_msg": "",
 						"error_msg": "The <protocol> service running at <destination_node_ip>:<destination_node_port> is not reachable from <source_ip>",
 						"resolution_msg": "Check your firewall settings to provide access to <destination_node_port> port at <destination_node_ip> from <source_node_ip>"
-					},{
-						"title": "Check for reachability of service at destination port",
-						"passed": false,
-						"success_msg": "",
-						"error_msg": "The <protocol> service running at <destination_node_ip>:<destination_node_port> is not reachable from <source_ip>",
-						"resolution_msg": "Check your firewall settings to provide access to <destination_node_port> port at <destination_node_ip> from <source_node_ip>"
 					}
 				]
 			}
@@ -246,7 +234,7 @@ func TestMakeRequests(t *testing.T) {
 
 	requestsForBastion, ok := mapRequests[constants.BASTION]
 	assert.True(t, ok)
-	assert.Equal(t, len(requestsForBastion), 11)
+	assert.Equal(t, len(requestsForBastion), 7)
 
 	require.Equal(t, expected[0].SourceNodeIP, requestsForautomate[0].SourceNodeIP)
 	require.Equal(t, expected[0].DestinationNodeIP, requestsForautomate[0].DestinationNodeIP)
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger_test.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger_test.go
index 037adcbb9..e97bfb050 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcechecktrigger/hardwareresourcecountchecktrigger_test.go
@@ -264,11 +264,10 @@ func TestHardwareResourceCountCheck_Run(t *testing.T) {
 			}
 		}
 	})
-
 	t.Run("Returns error", func(t *testing.T) {
 		mockServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 			w.WriteHeader(http.StatusOK)
-			w.Write([]byte(`invalid JSON`))
+			w.Write([]byte(`{"status":"failure", "result":[], "error":{"code":400, "message":"Invalid JSON"}}`))
 		}))
 		err := startMockServerOnCustomPort(mockServer, "1134")
 		assert.NoError(t, err)
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck_test.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck_test.go
index 2c6b1c382..5e9b1ba9f 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsmountbackupchecktrigger/nfsmountbackupcheck_test.go
@@ -29,6 +29,7 @@ var (
 
 const (
 	mountLocation = "test-mount"
+	TYPE          = "self-managed"
 
 	nfsMountResponse = `{
 		"status": "SUCCESS",
@@ -635,7 +636,8 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 			name: "Passed Response for chef-server,automate,opensearch and postgresql",
 			args: args{
 				config: &models.Config{
-					Hardware: hardware,
+					ExternalDbType: TYPE,
+					Hardware:       hardware,
 					Backup: &models.Backup{
 						FileSystem: &models.FileSystem{
 							MountLocation: mountLocation,
@@ -654,7 +656,8 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 			name: "Failure Mount Response for chef-server,automate,opensearch and postgresql",
 			args: args{
 				config: &models.Config{
-					Hardware: hardware,
+					ExternalDbType: TYPE,
+					Hardware:       hardware,
 					Backup: &models.Backup{
 						FileSystem: &models.FileSystem{
 							MountLocation: mountLocation,
@@ -674,7 +677,8 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 			name: "Recived Internal Server Error From the API",
 			args: args{
 				config: &models.Config{
-					Hardware: hardware,
+					ExternalDbType: TYPE,
+					Hardware:       hardware,
 					Backup: &models.Backup{
 						FileSystem: &models.FileSystem{
 							MountLocation: mountLocation,
@@ -682,7 +686,7 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 					},
 				},
 			},
-			response:       "Error while triggering NFS Mount API from Batch Check API: 500 Internal Server Error",
+			response:       "unexpected end of JSON input",
 			isPassed:       false,
 			httpStatusCode: http.StatusInternalServerError,
 			isError:        true,
@@ -693,7 +697,8 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 			name: "Invalid Response from service",
 			args: args{
 				config: &models.Config{
-					Hardware: hardware,
+					ExternalDbType: TYPE,
+					Hardware:       hardware,
 					Backup: &models.Backup{
 						FileSystem: &models.FileSystem{
 							MountLocation: mountLocation,
@@ -713,6 +718,7 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 			name: "Checking for Same Front end Nodes",
 			args: args{
 				config: &models.Config{
+					ExternalDbType: TYPE,
 					Hardware: &models.Hardware{
 						AutomateNodeIps:        hardware.AutomateNodeIps,
 						ChefInfraServerNodeIps: hardware.AutomateNodeIps,
@@ -732,6 +738,7 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 			httpStatusCode:        http.StatusOK,
 			isError:               false,
 			wantRequest: models.NFSMountRequest{
+				ExternalDbType:         TYPE,
 				AutomateNodeIPs:        hardware.AutomateNodeIps,
 				ChefInfraServerNodeIPs: hardware.AutomateNodeIps,
 				PostgresqlNodeIPs:      hardware.PostgresqlNodeIps,
@@ -759,7 +766,7 @@ func TestNfsBackupConfigCheck_Run(t *testing.T) {
 				assert.Len(t, got, 4)
 				assert.NotNil(t, got[0].Result.Error)
 				assert.NotNil(t, got[0].Host)
-				assert.Contains(t, tt.response, got[0].Result.Error.Error())
+				assert.Contains(t, tt.response, got[0].Result.Error.Message)
 
 			} else {
 				var want []models.CheckTriggerResponse
@@ -820,6 +827,7 @@ func createDummyServer(t *testing.T, requiredStatusCode int, isPassed bool, pars
 
 func getRequest() models.NFSMountRequest {
 	return models.NFSMountRequest{
+		ExternalDbType:         TYPE,
 		AutomateNodeIPs:        hardware.AutomateNodeIps,
 		ChefInfraServerNodeIPs: hardware.ChefInfraServerNodeIps,
 		PostgresqlNodeIPs:      hardware.PostgresqlNodeIps,
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck_test.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck_test.go
index 0e9e14cb7..7f76416bd 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger/opensearchs3bucketaccesscheck_test.go
@@ -226,7 +226,7 @@ func TestOpensearchS3BucketAccessCheck_Run(t *testing.T) {
 			} else {
 				if tt.name == "Nil OS and Object storage" {
 					assert.Len(t, got, 1)
-					assert.Equal(t, constants.UNKNOWN_HOST, got[0].Host)
+					assert.Equal(t, "-", got[0].Host)
 					assert.Equal(t, constants.OPENSEARCH, got[0].NodeType)
 					assert.Equal(t, constants.AWS_OPENSEARCH_S3_BUCKET_ACCESS, got[0].CheckType)
 					assert.True(t, got[0].Result.Skipped)
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger_test.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger_test.go
index 66fca2eb2..5c4ff7e25 100644
--- a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupchecktrigger/s3backupconfigchecktrigger_test.go
@@ -339,7 +339,7 @@ func TestRunS3BackupCheck(t *testing.T) {
 		got := svc.Run(config)
 
 		assert.Len(t, got, 1)
-		assert.Equal(t, constants.UNKNOWN_HOST, got[0].Host)
+		assert.Equal(t, "-", got[0].Host)
 		assert.Equal(t, constants.AUTOMATE, got[0].NodeType)
 		assert.Equal(t, constants.S3_BACKUP_CONFIG, got[0].CheckType)
 		assert.True(t, got[0].Result.Skipped)
diff --git a/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation_test.go b/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation_test.go
index 1f8f2356d..4a9c88cce 100644
--- a/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/certificatevalidation/certificatevalidation_test.go
@@ -550,49 +550,7 @@ func TestCertificateValidation(t *testing.T) {
 				},
 			},
 		},
-		{
-			TestName: "Private Key is not in PKCS8 format",
-			ReqBody: models.CertificateCheckRequest{
-				RootCertificate:  ROOT_CERTIFICATE,
-				PrivateKey:       INVALID_KEY_FORMAT,
-				NodeCertificate:  NODE_CERTIFICATE,
-				AdminPrivateKey:  ADMIN_PRIVATE_KEY,
-				AdminCertificate: ADMIN_CERTIFICATE,
-			},
-			ExpectedResBody: models.CertificateCheckResponse{
-				Passed: false,
-				Checks: []models.Checks{
-					{
-						Title:         constants.CERTIFICATE_EXPIRY_TITLE,
-						Passed:        true,
-						SuccessMsg:    constants.CERTIFICATE_EXPIRY_SUCCESS_MESSAGE,
-						ErrorMsg:      "",
-						ResolutionMsg: "",
-					},
-					{
-						Title:         constants.CERTIFICATE_FORMAT_TITLE,
-						Passed:        true,
-						SuccessMsg:    constants.CERTIFICATE_FORMAT_SUCCESS_MESSAGE,
-						ErrorMsg:      "",
-						ResolutionMsg: "",
-					},
-					{
-						Title:         constants.KEY_FORMAT_TITLE,
-						Passed:        false,
-						SuccessMsg:    "",
-						ErrorMsg:      fmt.Sprintf(constants.KEY_FORMAT_ERROR_MESSAGE, constants.NODE_KEY),
-						ResolutionMsg: fmt.Sprintf(constants.KEY_FORMAT_RESOLUTION_MESSAGE, constants.NODE_KEY),
-					},
-					{
-						Title:         constants.CERTIFICATE_ALGORITHM_TITLE,
-						Passed:        true,
-						SuccessMsg:    constants.CERTIFICATE_ALGORITHM_SUCCESS_MESSAGE,
-						ErrorMsg:      "",
-						ResolutionMsg: "",
-					},
-				},
-			},
-		},
+
 		{
 			TestName: "There is no root certificate",
 			ReqBody: models.CertificateCheckRequest{
diff --git a/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice_test.go b/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice_test.go
index 3f65a1f3b..1b33d3bb3 100644
--- a/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/nfsmountservice/nfsmountservice_test.go
@@ -348,21 +348,27 @@ func TestGetNFSMountDetails(t *testing.T) {
 			Response: []models.NFSMountResponse{
 				{IP: "localhost", NodeType: "automate", CheckList: []models.Checks{
 					{Passed: true},
-					{Passed: true},
+					{Passed: false},
+				}, Error: nil},
+				{IP: "192.168.54.34", NodeType: "automate", CheckList: []models.Checks{
+					{Passed: false},
+					{Passed: false},
 				}, Error: nil},
-				{IP: "192.168.54.34", NodeType: "automate", CheckList: nil, Error: errors.New("")},
 				{IP: "localhost", NodeType: "chef-infra-server", CheckList: []models.Checks{
 					{Passed: true},
-					{Passed: true},
+					{Passed: false},
+				}, Error: nil},
+				{IP: "anything.com", NodeType: "postgresql", CheckList: []models.Checks{
+					{Passed: false},
+					{Passed: false},
 				}, Error: nil},
-				{IP: "anything.com", NodeType: "postgresql", CheckList: nil, Error: errors.New("")},
 				{IP: "localhost", NodeType: "postgresql", CheckList: []models.Checks{
 					{Passed: true},
-					{Passed: true},
+					{Passed: false},
 				}, Error: nil},
 				{IP: "localhost", NodeType: "opensearch", CheckList: []models.Checks{
 					{Passed: true},
-					{Passed: true},
+					{Passed: false},
 				}, Error: nil},
 			},
 		},
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice_test.go b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice_test.go
index 1944869c2..9ab104554 100644
--- a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice_test.go
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/softwareversionservice_test.go
@@ -13,25 +13,32 @@ var osTestVersion = map[string][]string{
 	"Ubuntu":        {"16.04.x", "18.04.x", "20.04.x", "22.04.x"},
 	"Centos":        {"7"},
 	"Amazon Linux":  {"2"},
-	"SUSE Linux":    {"12"},
+	"SUSE Linux":    {"12.5"},
 	"Debian":        {"9", "10", "11", "12"},
 }
 
 const (
-	successfile        = "./testfiles/success.txt"
-	failurefile        = "./testfiles/failure.txt"
-	versionfile        = "./testfiles/version.txt"
-	failfilepath       = "./failfilepath"
-	LinuxVersionTitle  = "Linux Version Check"
-	KernalVersionTitle = "Kernal Version Check"
-	MkdirTitle         = "mkdir availability"
-	OpensslTitle       = "openssl availability"
-	StatTitle          = "stat availability"
-	MkdirIsAvailable   = "mkdir is available"
-	OpensslIsAvailable = "openssl is available"
-	StatIsAvailable    = "stat is available"
-	successKernelfile  = "./testfiles/successkernel.txt"
-	failureKernelfile  = "./testfiles/failurekernel.txt"
+	osReleaseRedHatFail  = "./testfiles/os_release_red_hat_failure.txt"
+	osReleaseUbuntuFail  = "./testfiles/os_release_ubuntu_failure.txt"
+	osReleaseDebian      = "./testfiles/os_release_debian.txt"
+	osReleaseSuse        = "./testfiles/os_release_suse.txt"
+	osReleaseAmazonLinux = "./testfiles/os_release_amazon_linux.txt"
+	osReleaseRedHat      = "./testfiles/os_release_red_hat.txt"
+	osReleaseCentos      = "./testfiles/os_release_centos.txt"
+	successfile          = "./testfiles/os_release_ubuntu.txt"
+	failurefile          = "./testfiles/failure.txt"
+	versionfile          = "./testfiles/os_release_suse_failure.txt"
+	failfilepath         = "./failfilepath"
+	LinuxVersionTitle    = "Linux Version Check"
+	KernalVersionTitle   = "Kernal Version Check"
+	MkdirTitle           = "mkdir availability"
+	OpensslTitle         = "openssl availability"
+	StatTitle            = "stat availability"
+	MkdirIsAvailable     = "mkdir is available"
+	OpensslIsAvailable   = "openssl is available"
+	StatIsAvailable      = "stat is available"
+	successKernelfile    = "./testfiles/successkernel.txt"
+	failureKernelfile    = "./testfiles/failurekernel.txt"
 )
 
 var (
@@ -553,7 +560,7 @@ func TestCheckOsVersion(t *testing.T) {
 			},
 		},
 		{
-			description: "If the os and version both are correct",
+			description: "If the os and version both are correct for Ubuntu",
 			args: args{
 				osFilepath: successfile,
 			},
@@ -568,7 +575,82 @@ func TestCheckOsVersion(t *testing.T) {
 			expectedErr: "",
 		},
 		{
-			description: "If the os name is correct but version is incorrect",
+			description: "If the os and version both are correct for red_hat",
+			args: args{
+				osFilepath: osReleaseRedHat,
+			},
+			expectedBody: &models.Checks{
+				Title:         "Linux Version Check",
+				Passed:        true,
+				SuccessMsg:    "Red Hat version is 9.2",
+				ErrorMsg:      "",
+				ResolutionMsg: "",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
+		{
+			description: "If the os and version both are correct for centos",
+			args: args{
+				osFilepath: osReleaseCentos,
+			},
+			expectedBody: &models.Checks{
+				Title:         "Linux Version Check",
+				Passed:        true,
+				SuccessMsg:    "CentOS version is 7",
+				ErrorMsg:      "",
+				ResolutionMsg: "",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
+		{
+			description: "If the os and version both are correct for amazon linux",
+			args: args{
+				osFilepath: osReleaseAmazonLinux,
+			},
+			expectedBody: &models.Checks{
+				Title:         "Linux Version Check",
+				Passed:        true,
+				SuccessMsg:    "Amazon Linux version is 2",
+				ErrorMsg:      "",
+				ResolutionMsg: "",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
+		{
+			description: "If the os and version both are correct for debian",
+			args: args{
+				osFilepath: osReleaseDebian,
+			},
+			expectedBody: &models.Checks{
+				Title:         "Linux Version Check",
+				Passed:        true,
+				SuccessMsg:    "Debian version is 11",
+				ErrorMsg:      "",
+				ResolutionMsg: "",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
+		{
+			description: "If the os and version both are correct for SUSE",
+			args: args{
+				osFilepath: osReleaseSuse,
+			},
+			expectedBody: &models.Checks{
+				Title:         "Linux Version Check",
+				Passed:        true,
+				SuccessMsg:    "SUSE Linux version is 12.5",
+				ErrorMsg:      "",
+				ResolutionMsg: "",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
+		{
+			description: "If the os name is correct but version is incorrect for SUSE",
 			args: args{
 				osFilepath: versionfile,
 			},
@@ -582,6 +664,36 @@ func TestCheckOsVersion(t *testing.T) {
 			wantErr:     false,
 			expectedErr: "",
 		},
+		{
+			description: "If the os name is correct but version is incorrect for Ubuntu",
+			args: args{
+				osFilepath: osReleaseUbuntuFail,
+			},
+			expectedBody: &models.Checks{
+				Title:         LinuxVersionTitle,
+				Passed:        false,
+				SuccessMsg:    "",
+				ErrorMsg:      "Ubuntu version is not supported by automate",
+				ResolutionMsg: "Ensure Ubuntu correct version is installed on the node",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
+		{
+			description: "If the os name is correct but version is incorrect for Red Hat",
+			args: args{
+				osFilepath: osReleaseRedHatFail,
+			},
+			expectedBody: &models.Checks{
+				Title:         LinuxVersionTitle,
+				Passed:        false,
+				SuccessMsg:    "",
+				ErrorMsg:      "Red Hat version is not supported by automate",
+				ResolutionMsg: "Ensure Red Hat correct version is installed on the node",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
 		{
 			description: "If not able to get the OS Details from the filepath",
 			args: args{
@@ -600,7 +712,7 @@ func TestCheckOsVersion(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.description, func(t *testing.T) {
-			got, err := sv.checkOsVersion(tt.args.osFilepath)
+			got, _, err := sv.checkOsVersion(tt.args.osFilepath)
 			if tt.wantErr {
 				assert.Equal(t, tt.expectedErr, err.Error())
 				return
@@ -618,6 +730,7 @@ func TestCheckKernelVersion(t *testing.T) {
 	})
 	type args struct {
 		kernelFilePath string
+		osname         string
 	}
 	tests := []struct {
 		description  string
@@ -630,6 +743,7 @@ func TestCheckKernelVersion(t *testing.T) {
 			description: "If the Kernal version is supported",
 			args: args{
 				kernelFilePath: successKernelfile,
+				osname:         AMAZON_LINUX,
 			},
 			expectedBody: &models.Checks{
 				Title:         "Kernal Version Check",
@@ -642,9 +756,10 @@ func TestCheckKernelVersion(t *testing.T) {
 			expectedErr: "",
 		},
 		{
-			description: "If the Kernal Version entered is not supported",
+			description: "If the Kernal Version entered is not supported suse linux",
 			args: args{
 				kernelFilePath: failureKernelfile,
+				osname:         SUSE_LINUX,
 			},
 			expectedBody: &models.Checks{
 				Title:         KernalVersionTitle,
@@ -656,10 +771,26 @@ func TestCheckKernelVersion(t *testing.T) {
 			wantErr:     false,
 			expectedErr: "",
 		},
+		{
+			description: "If the Kernal Version entered is not supported Amazon linux",
+			args: args{
+				kernelFilePath: failureKernelfile,
+				osname:         AMAZON_LINUX,
+			},
+			expectedBody: &models.Checks{
+				Title:  "Kernal Version Check",
+				Passed: false, SuccessMsg: "",
+				ErrorMsg:      "Linux kernel version is not equal to 5.10",
+				ResolutionMsg: "Use a linux version whose kernel version is equal to 5.10",
+			},
+			wantErr:     false,
+			expectedErr: "",
+		},
 		{
 			description: "If not able to get the kernal Version",
 			args: args{
 				kernelFilePath: failfilepath,
+				osname:         AMAZON_LINUX,
 			},
 			expectedBody: &models.Checks{},
 			wantErr:      true,
@@ -668,7 +799,7 @@ func TestCheckKernelVersion(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.description, func(t *testing.T) {
-			got, err := sv.checkKernelVersion(tt.args.kernelFilePath)
+			got, err := sv.checkKernelVersion(tt.args.kernelFilePath, tt.args.osname)
 			if tt.wantErr {
 				assert.Equal(t, tt.expectedErr, err.Error())
 				return
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_amazon_linux.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_amazon_linux.txt
new file mode 100644
index 000000000..2903a695f
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_amazon_linux.txt
@@ -0,0 +1,9 @@
+NAME="Amazon Linux"
+VERSION="2"
+ID="amzn"
+ID_LIKE="centos rhel fedora"
+VERSION_ID="2"
+PRETTY_NAME="Amazon Linux 2"
+ANSI_COLOR="0;33"
+CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
+HOME_URL="https://amazonlinux.com/"
\ No newline at end of file
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_centos.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_centos.txt
new file mode 100644
index 000000000..b678aa458
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_centos.txt
@@ -0,0 +1,15 @@
+NAME="CentOS Linux"
+VERSION="7 (Core)"
+ID="centos"
+ID_LIKE="rhel fedora"
+VERSION_ID="7"
+PRETTY_NAME="CentOS Linux 7 (Core)"
+ANSI_COLOR="0;31"
+CPE_NAME="cpe:/o:centos:centos:7"
+HOME_URL="https://www.centos.org/"
+BUG_REPORT_URL="https://bugs.centos.org/"
+ 
+CENTOS_MANTISBT_PROJECT="CentOS-8"
+CENTOS_MANTISBT_PROJECT_VERSION="8"
+REDHAT_SUPPORT_PRODUCT="centos"
+REDHAT_SUPPORT_PRODUCT_VERSION="8"
\ No newline at end of file
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_debian.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_debian.txt
new file mode 100644
index 000000000..08d942836
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_debian.txt
@@ -0,0 +1,9 @@
+PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
+NAME="Debian GNU/Linux"
+VERSION_ID="11"
+VERSION="11 (bullseye)"
+VERSION_CODENAME=bullseye
+ID=debian
+HOME_URL="https://www.debian.org/"
+SUPPORT_URL="https://www.debian.org/support"
+BUG_REPORT_URL="https://bugs.debian.org/"
\ No newline at end of file
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_red_hat.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_red_hat.txt
new file mode 100644
index 000000000..4e1c983cf
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_red_hat.txt
@@ -0,0 +1,18 @@
+NAME="Red Hat Enterprise Linux"
+VERSION="9.2 (Plow)"
+ID="rhel"
+ID_LIKE="fedora"
+VERSION_ID="9.2"
+PLATFORM_ID="platform:el9"
+PRETTY_NAME="Red Hat Enterprise Linux 9.2 (Plow)"
+ANSI_COLOR="0;31"
+LOGO="fedora-logo-icon"
+CPE_NAME="cpe:/o:redhat:enterprise_linux:9::baseos"
+HOME_URL="https://www.redhat.com/"
+DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9"
+BUG_REPORT_URL="https://bugzilla.redhat.com/"
+
+REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 9"
+REDHAT_BUGZILLA_PRODUCT_VERSION=9.2
+REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
+REDHAT_SUPPORT_PRODUCT_VERSION="9.2"
\ No newline at end of file
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_red_hat_failure.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_red_hat_failure.txt
new file mode 100644
index 000000000..08bd39b16
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_red_hat_failure.txt
@@ -0,0 +1,18 @@
+NAME="Red Hat Enterprise Linux"
+VERSION="9.2 (Plow)"
+ID="rhel"
+ID_LIKE="fedora"
+VERSION_ID="6.2"
+PLATFORM_ID="platform:el9"
+PRETTY_NAME="Red Hat Enterprise Linux 9.2 (Plow)"
+ANSI_COLOR="0;31"
+LOGO="fedora-logo-icon"
+CPE_NAME="cpe:/o:redhat:enterprise_linux:9::baseos"
+HOME_URL="https://www.redhat.com/"
+DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9"
+BUG_REPORT_URL="https://bugzilla.redhat.com/"
+
+REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 9"
+REDHAT_BUGZILLA_PRODUCT_VERSION=9.2
+REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
+REDHAT_SUPPORT_PRODUCT_VERSION="9.2"
\ No newline at end of file
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/version.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_suse.txt
similarity index 100%
rename from components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/version.txt
rename to components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_suse.txt
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_suse_failure.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_suse_failure.txt
new file mode 100644
index 000000000..e3458d114
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_suse_failure.txt
@@ -0,0 +1,7 @@
+NAME="SLES"
+VERSION="12-SP5"
+VERSION_ID="13.4"
+PRETTY_NAME="SUSE Linux Enterprise Server 12 SP5"
+ID="sles"
+ANSI_COLOR="0;32"
+CPE_NAME="cpe:/o:suse:sles:12:sp5"
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/success.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_ubuntu.txt
similarity index 100%
rename from components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/success.txt
rename to components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_ubuntu.txt
diff --git a/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_ubuntu_failure.txt b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_ubuntu_failure.txt
new file mode 100644
index 000000000..1a5da4c19
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/softwareversionservice/testfiles/os_release_ubuntu_failure.txt
@@ -0,0 +1,12 @@
+NAME="Ubuntu"
+VERSION="20.04.6 LTS (Focal Fossa)"
+ID=ubuntu
+ID_LIKE=debian
+PRETTY_NAME="Ubuntu 20.04.6 LTS"
+VERSION_ID="14.04"
+HOME_URL="https://www.ubuntu.com/"
+SUPPORT_URL="https://help.ubuntu.com/"
+BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
+PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
+VERSION_CODENAME=focal
+UBUNTU_CODENAME=focal
\ No newline at end of file
diff --git a/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil_test.go b/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil_test.go
index a3875677e..0b4e7e19a 100644
--- a/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil_test.go
+++ b/components/automate-cli/pkg/verifyserver/utils/checkutils/checkutil_test.go
@@ -44,9 +44,10 @@ func TestPrepareTriggerResponse_WithNoError(t *testing.T) {
 	check := "test check"
 	msg := "test message"
 	isError := false
+	statusCode := 200
 
 	// Act
-	result := PrepareTriggerResponse(resp, host, nodeType, errorString, check, msg, isError)
+	result := PrepareTriggerResponse(resp, host, nodeType, errorString, check, msg, isError, statusCode)
 
 	// Assert
 	assert.Equal(t, resp.Status, result.Status)
@@ -68,9 +69,9 @@ func TestPrepareTriggerResponse_WithError(t *testing.T) {
 	check := "test check"
 	msg := "test message"
 	isError := true
-
+	statusCode := 400
 	// Act
-	result := PrepareTriggerResponse(resp, host, nodeType, errorString, check, msg, isError)
+	result := PrepareTriggerResponse(resp, host, nodeType, errorString, check, msg, isError, statusCode)
 
 	// Assert
 	assert.Equal(t, resp.Status, result.Status)
diff --git a/components/automate-cli/pkg/verifyserver/utils/getosutils/getosutils_test.go b/components/automate-cli/pkg/verifyserver/utils/getosutils/getosutils_test.go
index 3d40c7f39..21775f776 100644
--- a/components/automate-cli/pkg/verifyserver/utils/getosutils/getosutils_test.go
+++ b/components/automate-cli/pkg/verifyserver/utils/getosutils/getosutils_test.go
@@ -6,7 +6,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-const successfile = "../../services/softwareversionservice/testfiles/success.txt"
+const successfile = "../../services/softwareversionservice/testfiles/os_release_ubuntu.txt"
 const failurefile = "../../services/softwareversionservice/testfiles/wrongfile.txt"
 const successKernelfile = "../../services/softwareversionservice/testfiles/successkernel.txt"
 
diff --git a/lib/config/hadeployconfigverify_test.go b/lib/config/hadeployconfigverify_test.go
index 47d348eac..d905371cd 100644
--- a/lib/config/hadeployconfigverify_test.go
+++ b/lib/config/hadeployconfigverify_test.go
@@ -33,7 +33,7 @@ func TestParseAndVerify(t *testing.T) {
 			name:    "Verify OnPrem Config",
 			args:    args{configFile: "./testdata/HaOnPrem.toml"},
 			wantErr: true,
-			err:     errors.New("invalid or empty: ssh_user\ninvalid or empty: ssh_key_file\nautomate private ip 1324.2534.1is not valid\ninvalid or empty: chef_server_private_ips\ninvalid or empty: opensearch_private_ips\ninvalid or empty: postgresql_private_ips\nurl should not include the protocol (http:// or https://): automate fqdn\nempty value: automate instance_count\ninvalid value 'automate.toml' for field 'config_file'. Expected values are: configs/automate.toml\ninvalid format. Failed to decode root_ca for automate\ninvalid format. Failed to decode private_key for automate\ninvalid format. Failed to decode public_key for automate\ninvalid format. Failed to decode private_key for automate ip\ninvalid format. Failed to decode public_key for automate ip\ninvalid value 'chef server instance_count' for field 'two'\ninvalid format. Failed to decode private_key for chef-infra-server\ninvalid format. Failed to decode public_key for chef-infra-server\ninvalid format. Failed to decode private_key for chef server ip\ninvalid format. Failed to decode public_key for chef server ip\nempty value: opensearch instance_count\nopensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false\nopensearch ippublic_key and/or private_key are missing in certs_by_ip. Otherwise set enable_custom_certs to false\nempty value: postgresql instance_count\ninvalid format. Failed to decode root_ca for postgresql\ninvalid format. Failed to decode private_key for postgresql\ninvalid format. Failed to decode public_key for postgresql\npostgresql ip 0.0.1 for certs is not valid\ninvalid format. Failed to decode private_key for postgresql ip\ninvalid format. Failed to decode public_key for postgresql ip"),
+			err:     errors.New("invalid or empty: ssh_user\ninvalid or empty: ssh_key_file\nautomate private ip 1324.2534.1is not valid\ninvalid or empty: chef_server_private_ips\ninvalid or empty: opensearch_private_ips\ninvalid or empty: postgresql_private_ips\nurl should not include the protocol (http:// or https://): automate fqdn\nempty value: automate instance_count\ninvalid value 'automate.toml' for field 'config_file'. Expected values are: configs/automate.toml\ninvalid format. Failed to decode private_key for automate\ninvalid format. Failed to decode public_key for automate\ninvalid format. Failed to decode private_key for automate ip\ninvalid format. Failed to decode public_key for automate ip\ninvalid value 'chef server instance_count' for field 'two'\ninvalid format. Failed to decode private_key for chef-infra-server\ninvalid format. Failed to decode public_key for chef-infra-server\ninvalid format. Failed to decode private_key for chef server ip\ninvalid format. Failed to decode public_key for chef server ip\nempty value: opensearch instance_count\nopensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false\nopensearch ippublic_key and/or private_key are missing in certs_by_ip. Otherwise set enable_custom_certs to false\nempty value: postgresql instance_count\ninvalid format. Failed to decode root_ca for postgresql\ninvalid format. Failed to decode private_key for postgresql\ninvalid format. Failed to decode public_key for postgresql\npostgresql ip 0.0.1 for certs is not valid\ninvalid format. Failed to decode private_key for postgresql ip\ninvalid format. Failed to decode public_key for postgresql ip"),
 		},
 		{
 			name:    "Verify OnPrem Db Self-Managed Config",
diff --git a/lib/config/helper_test.go b/lib/config/helper_test.go
index 9fca0c043..c7bf12f1a 100644
--- a/lib/config/helper_test.go
+++ b/lib/config/helper_test.go
@@ -10,6 +10,8 @@ import (
 	"math/big"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestValidateStringBasedBoolean(t *testing.T) {
@@ -426,3 +428,554 @@ func generateExpiredCert() []byte {
 	derBytes, _ := x509.CreateCertificate(rand.Reader, template, template, &publicKey, privateKey)
 	return derBytes
 }
+
+const (
+	PublicKey  = "-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIUMUG0kbGT5s8Vo415aNfii81CzRcwDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM\nB1NlYXR0bGUxGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApj\naGVmcm9vdGNhMB4XDTIyMDYwMTA3MzMwMFoXDTI1MDUzMTA3MzMwMFowZTELMAkG\nA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx\nGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApjaGVmcm9vdGNh\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aKz6j+Otgeg+oZSsHtq\nz5Phyb2cWr+CdbLb2qZA9ZDcCjEzkxvuvI6QBScF9feVk7YVXg59DXlHJRP7AHx5\nnG5iQmND0jUUQGjyZfKTWO8Z9F8D/w0HAFOk4LTvVR/AAC6f9PpxjaydfSzkh5cc\nNxeotjlkYUgh6D7fFma9gRtjX4a36miA5FqCv0Lkwrk9tXHdDk6skdjBvCS0URnq\nzDfyTcK7R/L/iaGYtY43c8tB8eHKwK+ZQ2fR4V90YI3xkbkwr6j0efZyU2Kp/03r\n2nDtFQXHwwuj6Sg465DJB9MQ01IbR30NUjJiFGOJaxdRlhsEeWWNL8BELQuGpJe9\nVQIDAQABo1MwUTAdBgNVHQ4EFgQU3XAfDSRK1wCTf0wiDjlR4m06FCQwHwYDVR0j\nBBgwFoAU3XAfDSRK1wCTf0wiDjlR4m06FCQwDwYDVR0TAQH/BAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAQEAVTiFfpOzYfXzQxTrl4VxctdQJI52jPjWP55PmK/IO7sb\nn/DKzRNnvn7mN3EDGmshh5i76/hoGA09pK4SdAwJl2QIRJSu3ChH4QCf7n/iIYww\nSxhpOp9QtJA5Cyu4MoemK49Lld/7xf3Qdt1pOgEMz4AGLt2uwS5SdmR4OkSPHqt0\nQq/lgSoiawVOd0UE+5Ocu5S472du/REcVS4KkQdkzZaw9Q7OGIN9G0X0wb0V3UZs\nR2XuApUUaGOl0s0a1uNMv3WkyOrCGS3JkIem6+R59pfliaz6FPcQD+0oXI2gjG3c\nH4VFwOis/oT/2FwYM89j7XZPDpRfUUGMHD53W7YPHA==\n-----END CERTIFICATE-----"
+	PrivateKey = "-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIUMUG0kbGT5s8Vo415aNfii81CzRcwDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM\nB1NlYXR0bGUxGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApj\naGVmcm9vdGNhMB4XDTIyMDYwMTA3MzMwMFoXDTI1MDUzMTA3MzMwMFowZTELMAkG\nA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx\nGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApjaGVmcm9vdGNh\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aKz6j+Otgeg+oZSsHtq\nz5Phyb2cWr+CdbLb2qZA9ZDcCjEzkxvuvI6QBScF9feVk7YVXg59DXlHJRP7AHx5\nnG5iQmND0jUUQGjyZfKTWO8Z9F8D/w0HAFOk4LTvVR/AAC6f9PpxjaydfSzkh5cc\nNxeotjlkYUgh6D7fFma9gRtjX4a36miA5FqCv0Lkwrk9tXHdDk6skdjBvCS0URnq\nzDfyTcK7R/L/iaGYtY43c8tB8eHKwK+ZQ2fR4V90YI3xkbkwr6j0efZyU2Kp/03r\n2nDtFQXHwwuj6Sg465DJB9MQ01IbR30NUjJiFGOJaxdRlhsEeWWNL8BELQuGpJe9\nVQIDAQABo1MwUTAdBgNVHQ4EFgQU3XAfDSRK1wCTf0wiDjlR4m06FCQwHwYDVR0j\nBBgwFoAU3XAfDSRK1wCTf0wiDjlR4m06FCQwDwYDVR0TAQH/BAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAQEAVTiFfpOzYfXzQxTrl4VxctdQJI52jPjWP55PmK/IO7sb\nn/DKzRNnvn7mN3EDGmshh5i76/hoGA09pK4SdAwJl2QIRJSu3ChH4QCf7n/iIYww\nSxhpOp9QtJA5Cyu4MoemK49Lld/7xf3Qdt1pOgEMz4AGLt2uwS5SdmR4OkSPHqt0\nQq/lgSoiawVOd0UE+5Ocu5S472du/REcVS4KkQdkzZaw9Q7OGIN9G0X0wb0V3UZs\nR2XuApUUaGOl0s0a1uNMv3WkyOrCGS3JkIem6+R59pfliaz6FPcQD+0oXI2gjG3c\nH4VFwOis/oT/2FwYM89j7XZPDpRfUUGMHD53W7YPHA==\n-----END CERTIFICATE-----"
+	RootCa     = "-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIUMUG0kbGT5s8Vo415aNfii81CzRcwDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM\nB1NlYXR0bGUxGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApj\naGVmcm9vdGNhMB4XDTIyMDYwMTA3MzMwMFoXDTI1MDUzMTA3MzMwMFowZTELMAkG\nA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx\nGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApjaGVmcm9vdGNh\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aKz6j+Otgeg+oZSsHtq\nz5Phyb2cWr+CdbLb2qZA9ZDcCjEzkxvuvI6QBScF9feVk7YVXg59DXlHJRP7AHx5\nnG5iQmND0jUUQGjyZfKTWO8Z9F8D/w0HAFOk4LTvVR/AAC6f9PpxjaydfSzkh5cc\nNxeotjlkYUgh6D7fFma9gRtjX4a36miA5FqCv0Lkwrk9tXHdDk6skdjBvCS0URnq\nzDfyTcK7R/L/iaGYtY43c8tB8eHKwK+ZQ2fR4V90YI3xkbkwr6j0efZyU2Kp/03r\n2nDtFQXHwwuj6Sg465DJB9MQ01IbR30NUjJiFGOJaxdRlhsEeWWNL8BELQuGpJe9\nVQIDAQABo1MwUTAdBgNVHQ4EFgQU3XAfDSRK1wCTf0wiDjlR4m06FCQwHwYDVR0j\nBBgwFoAU3XAfDSRK1wCTf0wiDjlR4m06FCQwDwYDVR0TAQH/BAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAQEAVTiFfpOzYfXzQxTrl4VxctdQJI52jPjWP55PmK/IO7sb\nn/DKzRNnvn7mN3EDGmshh5i76/hoGA09pK4SdAwJl2QIRJSu3ChH4QCf7n/iIYww\nSxhpOp9QtJA5Cyu4MoemK49Lld/7xf3Qdt1pOgEMz4AGLt2uwS5SdmR4OkSPHqt0\nQq/lgSoiawVOd0UE+5Ocu5S472du/REcVS4KkQdkzZaw9Q7OGIN9G0X0wb0V3UZs\nR2XuApUUaGOl0s0a1uNMv3WkyOrCGS3JkIem6+R59pfliaz6FPcQD+0oXI2gjG3c\nH4VFwOis/oT/2FwYM89j7XZPDpRfUUGMHD53W7YPHA==\n-----END CERTIFICATE-----"
+	AdminCert  = "-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIUMUG0kbGT5s8Vo415aNfii81CzRcwDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM\nB1NlYXR0bGUxGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApj\naGVmcm9vdGNhMB4XDTIyMDYwMTA3MzMwMFoXDTI1MDUzMTA3MzMwMFowZTELMAkG\nA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx\nGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApjaGVmcm9vdGNh\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aKz6j+Otgeg+oZSsHtq\nz5Phyb2cWr+CdbLb2qZA9ZDcCjEzkxvuvI6QBScF9feVk7YVXg59DXlHJRP7AHx5\nnG5iQmND0jUUQGjyZfKTWO8Z9F8D/w0HAFOk4LTvVR/AAC6f9PpxjaydfSzkh5cc\nNxeotjlkYUgh6D7fFma9gRtjX4a36miA5FqCv0Lkwrk9tXHdDk6skdjBvCS0URnq\nzDfyTcK7R/L/iaGYtY43c8tB8eHKwK+ZQ2fR4V90YI3xkbkwr6j0efZyU2Kp/03r\n2nDtFQXHwwuj6Sg465DJB9MQ01IbR30NUjJiFGOJaxdRlhsEeWWNL8BELQuGpJe9\nVQIDAQABo1MwUTAdBgNVHQ4EFgQU3XAfDSRK1wCTf0wiDjlR4m06FCQwHwYDVR0j\nBBgwFoAU3XAfDSRK1wCTf0wiDjlR4m06FCQwDwYDVR0TAQH/BAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAQEAVTiFfpOzYfXzQxTrl4VxctdQJI52jPjWP55PmK/IO7sb\nn/DKzRNnvn7mN3EDGmshh5i76/hoGA09pK4SdAwJl2QIRJSu3ChH4QCf7n/iIYww\nSxhpOp9QtJA5Cyu4MoemK49Lld/7xf3Qdt1pOgEMz4AGLt2uwS5SdmR4OkSPHqt0\nQq/lgSoiawVOd0UE+5Ocu5S472du/REcVS4KkQdkzZaw9Q7OGIN9G0X0wb0V3UZs\nR2XuApUUaGOl0s0a1uNMv3WkyOrCGS3JkIem6+R59pfliaz6FPcQD+0oXI2gjG3c\nH4VFwOis/oT/2FwYM89j7XZPDpRfUUGMHD53W7YPHA==\n-----END CERTIFICATE-----"
+	AdminKey   = "-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIUMUG0kbGT5s8Vo415aNfii81CzRcwDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM\nB1NlYXR0bGUxGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApj\naGVmcm9vdGNhMB4XDTIyMDYwMTA3MzMwMFoXDTI1MDUzMTA3MzMwMFowZTELMAkG\nA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx\nGjAYBgNVBAoMEUNoZWYgU29mdHdhcmUgSW5jMRMwEQYDVQQDDApjaGVmcm9vdGNh\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aKz6j+Otgeg+oZSsHtq\nz5Phyb2cWr+CdbLb2qZA9ZDcCjEzkxvuvI6QBScF9feVk7YVXg59DXlHJRP7AHx5\nnG5iQmND0jUUQGjyZfKTWO8Z9F8D/w0HAFOk4LTvVR/AAC6f9PpxjaydfSzkh5cc\nNxeotjlkYUgh6D7fFma9gRtjX4a36miA5FqCv0Lkwrk9tXHdDk6skdjBvCS0URnq\nzDfyTcK7R/L/iaGYtY43c8tB8eHKwK+ZQ2fR4V90YI3xkbkwr6j0efZyU2Kp/03r\n2nDtFQXHwwuj6Sg465DJB9MQ01IbR30NUjJiFGOJaxdRlhsEeWWNL8BELQuGpJe9\nVQIDAQABo1MwUTAdBgNVHQ4EFgQU3XAfDSRK1wCTf0wiDjlR4m06FCQwHwYDVR0j\nBBgwFoAU3XAfDSRK1wCTf0wiDjlR4m06FCQwDwYDVR0TAQH/BAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAQEAVTiFfpOzYfXzQxTrl4VxctdQJI52jPjWP55PmK/IO7sb\nn/DKzRNnvn7mN3EDGmshh5i76/hoGA09pK4SdAwJl2QIRJSu3ChH4QCf7n/iIYww\nSxhpOp9QtJA5Cyu4MoemK49Lld/7xf3Qdt1pOgEMz4AGLt2uwS5SdmR4OkSPHqt0\nQq/lgSoiawVOd0UE+5Ocu5S472du/REcVS4KkQdkzZaw9Q7OGIN9G0X0wb0V3UZs\nR2XuApUUaGOl0s0a1uNMv3WkyOrCGS3JkIem6+R59pfliaz6FPcQD+0oXI2gjG3c\nH4VFwOis/oT/2FwYM89j7XZPDpRfUUGMHD53W7YPHA==\n-----END CERTIFICATE-----"
+
+	DummyPublicKey  = "DummyPublicKey"
+	DummyPrivateKey = "DummyPrivateKey"
+)
+
+func Test_validateAutomateCerts(t *testing.T) {
+	t.Run("NIL CERTByIP", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Automate: &AutomateSettings{
+				Config: &ConfigAutomateSettings{
+					CertsByIP: nil,
+				},
+			},
+		}
+
+		expectedErr := "automate root_ca and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false"
+		err := validateAutomateCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("Invalid common Certs", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Automate: &AutomateSettings{
+				Config: &ConfigAutomateSettings{
+					CertsByIP:  nil,
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode private_key for automate\ninvalid format. Failed to decode public_key for automate"
+		err := validateAutomateCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Automate: &AutomateSettings{
+				Config: &ConfigAutomateSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP: "10.10.10.10",
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "cannot find private key for ip 10.10.10.10"
+		err := validateAutomateCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Automate: &AutomateSettings{
+				Config: &ConfigAutomateSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: DummyPrivateKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "cannot find public key for ip 10.10.10.11"
+		err := validateAutomateCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No CertByIP validate", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Automate: &AutomateSettings{
+				Config: &ConfigAutomateSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: DummyPrivateKey,
+							PublicKey:  DummyPublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode private_key for automate\ninvalid format. Failed to decode public_key for automate"
+		err := validateAutomateCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("NO Error", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Automate: &AutomateSettings{
+				Config: &ConfigAutomateSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: PrivateKey,
+							PublicKey:  PublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		err := validateAutomateCerts(depConfig)
+		assert.NoError(t, err)
+	})
+}
+
+func Test_validateChefServerCerts(t *testing.T) {
+	t.Run("NIL CERTByIP", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			ChefServer: &ChefServerSettings{
+				Config: &ConfigSettings{
+					CertsByIP: nil,
+				},
+			},
+		}
+
+		expectedErr := "chefServer public_key and/or private_key are missing. Otherwise set enable_custom_certs to false"
+		err := validateChefServerCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("Invalid common Certs", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			ChefServer: &ChefServerSettings{
+				Config: &ConfigSettings{
+					CertsByIP:  nil,
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode private_key for chef-infra-server\ninvalid format. Failed to decode public_key for chef-infra-server"
+		err := validateChefServerCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			ChefServer: &ChefServerSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP: "10.10.10.10",
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "cannot find private key for ip 10.10.10.10"
+		err := validateChefServerCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			ChefServer: &ChefServerSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: "-----PK-----",
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "cannot find public key for ip 10.10.10.11"
+		err := validateChefServerCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No CertByIP validate", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			ChefServer: &ChefServerSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: DummyPrivateKey,
+							PublicKey:  DummyPublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode private_key for chef-infra-server\ninvalid format. Failed to decode public_key for chef-infra-server"
+		err := validateChefServerCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("NO Error", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			ChefServer: &ChefServerSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: PrivateKey,
+							PublicKey:  PublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+				},
+			},
+		}
+
+		err := validateChefServerCerts(depConfig)
+		assert.NoError(t, err)
+	})
+}
+
+func Test_validatePostgresqlCerts(t *testing.T) {
+	t.Run("NIL CERTByIP", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{},
+			},
+		}
+
+		expectedErr := "postgresql root_ca and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false"
+		err := validatePostgresqlCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("Invalid common Certs", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{
+					CertsByIP:  nil,
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+					RootCA:     "dummy_root_cert",
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode root_ca for postgresql\ninvalid format. Failed to decode private_key for postgresql\ninvalid format. Failed to decode public_key for postgresql"
+		err := validatePostgresqlCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP: "10.10.10.10",
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+					RootCA:     "-----ROOTCA KEY-----",
+				},
+			},
+		}
+
+		expectedErr := "cannot find private key for ip 10.10.10.10"
+		err := validatePostgresqlCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: DummyPrivateKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+					RootCA:     "-----ROOTCA KEY-----",
+				},
+			},
+		}
+
+		expectedErr := "cannot find public key for ip 10.10.10.11"
+		err := validatePostgresqlCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No CertByIP validate", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: DummyPrivateKey,
+							PublicKey:  DummyPublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+					RootCA:     "-----ROOTCA KEY-----",
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode root_ca for postgresql\ninvalid format. Failed to decode private_key for postgresql\ninvalid format. Failed to decode public_key for postgresql"
+		err := validatePostgresqlCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("NO Error", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: PrivateKey,
+							PublicKey:  PublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+					RootCA:     RootCa,
+				},
+			},
+		}
+
+		err := validatePostgresqlCerts(depConfig)
+		assert.NoError(t, err)
+	})
+
+	t.Run("RootCert Error", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Postgresql: &PostgresqlSettings{
+				Config: &ConfigSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: PrivateKey,
+							PublicKey:  PublicKey,
+						},
+					},
+					PrivateKey: DummyPrivateKey,
+					PublicKey:  DummyPublicKey,
+					RootCA:     "",
+				},
+			},
+		}
+
+		expectedErr := "cannot find root_ca for ip for PostgresSQL"
+		err := validatePostgresqlCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+}
+
+func Test_validateOpensearchCerts(t *testing.T) {
+	t.Run("NIL CERTByIP", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{},
+			},
+		}
+
+		expectedErr := "opensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false"
+		err := validateOpensearchCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("Invalid common Certs", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{
+					CertsByIP:  nil,
+					PrivateKey: "-----PRIVATE KEY-----",
+					PublicKey:  "-----PUBLIC KEY-----",
+					RootCA:     "dummy_root_cert",
+					AdminCert:  "admin key",
+					AdminKey:   "admin key",
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode root_ca for opensearch\ninvalid format. Failed to decode admin_key for opensearch\ninvalid format. Failed to decode admin_cert for opensearch\ninvalid format. Failed to decode private_key for opensearch\ninvalid format. Failed to decode public_key for opensearch"
+		err := validateOpensearchCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No CertByIP validate", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: "-----PRIVATE2 KEY-----",
+							PublicKey:  "-----PRIVATE2sdsf KEY-----",
+						},
+					},
+					PrivateKey: "-----PRIVATE1 KEY-----",
+					PublicKey:  "-----PUBLIC1 KEY-----",
+					RootCA:     "-----ROOTCA KEY-----",
+					AdminCert:  "admin cer",
+					AdminKey:   "admin key",
+				},
+			},
+		}
+
+		expectedErr := "invalid format. Failed to decode root_ca for opensearch\ninvalid format. Failed to decode admin_key for opensearch\ninvalid format. Failed to decode root_ca for opensearch\ninvalid format. Failed to decode private_key for opensearch\ninvalid format. Failed to decode public_key for opensearch"
+		err := validateOpensearchCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("NO Error", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: PrivateKey,
+							PublicKey:  PublicKey,
+						},
+					},
+					PrivateKey: "-----PRIVATE1 KEY-----",
+					PublicKey:  "-----PUBLIC1 KEY-----",
+					RootCA:     RootCa,
+					AdminCert:  AdminCert,
+					AdminKey:   AdminKey,
+				},
+			},
+		}
+
+		err := validateOpensearchCerts(depConfig)
+		assert.NoError(t, err)
+	})
+
+	t.Run("RootCert Error", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.11",
+							PrivateKey: PrivateKey,
+							PublicKey:  PublicKey,
+						},
+					},
+					PrivateKey: "-----PRIVATE1 KEY-----",
+					PublicKey:  "-----PUBLIC1 KEY-----",
+					RootCA:     "",
+				},
+			},
+		}
+
+		expectedErr := "opensearch root_ca and/or admin_key and/or admin_cert and/or public_key and/or private_key are missing. Otherwise set enable_custom_certs to false"
+		err := validateOpensearchCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+
+	t.Run("No private key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP: "10.10.10.10",
+						},
+					},
+					RootCA:    "root ca",
+					AdminCert: "admin cert",
+					AdminKey:  "admin  key",
+				},
+			},
+		}
+
+		expectedErr := "cannot find private key for ip 10.10.10.10"
+		err := validateOpensearchCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+	t.Run("No Public key", func(t *testing.T) {
+		depConfig := &HaDeployConfig{
+			Opensearch: &OpensearchSettings{
+				Config: &ConfigOpensearchSettings{
+					CertsByIP: &[]CertByIP{
+						{
+							IP:         "10.10.10.10",
+							PrivateKey: "private key",
+						},
+					},
+					RootCA:    "root ca",
+					AdminCert: "admin cert",
+					AdminKey:  "admin  key",
+				},
+			},
+		}
+
+		expectedErr := "cannot find public key for ip 10.10.10.10"
+		err := validateOpensearchCerts(depConfig)
+		assert.Error(t, err)
+		assert.EqualError(t, err, expectedErr)
+	})
+}