---
title: TeamCity Plugin Development Journey
description: TeamCity Plugin Development Journey
image: https://blog.quali.com/hubfs/Tomer-admon-banner-2.jpg
---

[![logo](https://blog.quali.com/hs-fs/hubfs/logo.png?width=120&height=36&name=logo.png "logo")](https://www.quali.com/)

- SOLUTIONS 
    - [DEVOPS CLOUD AUTOMATION](https://www.quali.com/solutions/devops-environments/)
    - [TEST ENVIRONMENTS](https://www.quali.com/solutions/software-test-environments-as-a-service/)
    - [LAB AS A SERVICE](https://www.quali.com/solutions/network-and-security-dev-test-lab-as-a-service/)
    - [SALES DEMO/VIRTUAL POC](https://www.quali.com/solutions/sales-demos-virtual-poc-environments/)
    - [CYBER RANGE ENVIRONMENTS](https://www.quali.com/solutions/cyber-range-environments/)
    - [VIRTUAL TRAINING LABS](https://www.quali.com/solutions/virtual-training-labs/)
- [PRODUCTS](https://www.quali.com/cloudshell-platform/) 
    - [CloudShell Pro](https://www.quali.com/cloudshell-pro/) 
          - [Product](https://www.quali.com/cloudshell-pro/)
          - [Community](https://www.quali.com/community/)
          - [University](https://www.quali.com/university/)
          - [Support](https://support.quali.com/)
    - [CloudShell Colony \[NEW\]](https://www.quali.com/cloudshell-colony/) 
          - [Product](https://www.quali.com/cloudshell-colony/)
          - [Request Free Trial](https://app.cloudshellcolony.com/sign_up?utm_referrer=https%3A%2F%2Ffreedcamp.com%2FJacobs_Work_Projects_gNM%2FQuali_7GO%2Ftodos%2F25066065%2F&__hstc=208618317.2af89ba750e0bbc1c35b7c40ea6ff838.1567174142272.1567174142272.1567174142272.1&__hssc=208618317.1.1567174142272&__hsfp=1037199243)
          - [Login](https://app.cloudshellcolony.com/login?__hstc=208618317.2af89ba750e0bbc1c35b7c40ea6ff838.1567174142272.1567174142272.1567174142272.1&__hssc=208618317.1.1567174142272&__hsfp=1037199243)
- [CUSTOMERS](https://www.quali.com/customers/)
- [RESOURCES](https://www.quali.com/resource-center/) 
    - [Blog](https://blog.quali.com/blog/)
    - Financial Services 
          - [Financial Services Application Continuous Delivery](https://www.quali.com/financial-services-application-continuous-delivery/)
          - [Infrastructure Environments for Banks and Financial Services](https://www.quali.com/environment-as-service-for-banks-finserv/)
    - [FAQ](https://www.quali.com/faq/)
    - [Resource Library](https://www.quali.com/resource-center/)
- [COMPANY](https://www.quali.com/about-us/) 
    - [About Us](https://www.quali.com/about-us/)
    - [Leadership](https://www.quali.com/about-us/#management)
    - [News and Events](https://www.quali.com/about-us/news-events/)
    - [Partners](https://www.quali.com/partners/)
    - [Locations](https://www.quali.com/about-us/#locations)
    - [Careers](https://www.quali.com/about-us/careers/)
    - [Awards](https://www.quali.com/awards/)
- [CONTACT US](https://info.quali.com/contact-us)

### Blog

Stay up to date with blogs written by experts in the fields of cloud automation, infrastructure orchestration, and devops.

### TeamCity Plugin Development Journey

# TeamCity Plugin Development Journey

![header-picture](https://blog.quali.com/hubfs/Tomer-admon-banner-2.jpg "header-picture")

**Author:**  
Pascal Joly

**Published:**  
February 18, 2018

**Share it:**

- <https://www.facebook.com/sharer/sharer.php?u=https://blog.quali.com/blog/teamcity-plugin-development-journey>
- <https://www.linkedin.com/shareArticle?mini=true&url=https://blog.quali.com/blog/teamcity-plugin-development-journey&title=&summary=&source=>
- <https://twitter.com/home?status=>
- [mailto:?&subject=https://blog.quali.com/blog/teamcity-plugin-development-journey&body=https://blog.quali.com/blog/teamcity-plugin-development-journey](mailto:?&subject=https://blog.quali.com/blog/teamcity-plugin-development-journey&body=https://blog.quali.com/blog/teamcity-plugin-development-journey)

![header-picture](https://blog.quali.com/hubfs/Tomer-admon-banner-2.jpg "header-picture")

[Jet Brains TeamCity](https://www.jetbrains.com/teamcity/) & [Quali CloudShell](https://www.quali.com/cloudshell-pro/) integration case study

This article is intended for developers who wish to perform 3rd party integration with TeamCity.

Following customer requests, Quali has decided to support custom integration between CloudShell (our main product) to JetBrains TeamCity CI.

In this article, we will dive into the design and development process of the[CloudShell Sandbox TeamCity](https://plugins.jetbrains.com/plugin/10255-cloudshell-sandbox) plugin, which is now available in JetBrains community.

## Getting Started

#### CloudShell & TeamCity

[CloudShell](https://www.quali.com/cloudshell-pro/), a cloud sandbox platform by [Quali](https://www.quali.com/), allows users to create and publish a CloudShell Sandbox, which is a replica of a specific computing infrastructure and application configurations, and use it for development, testing, demos, training, and support.

This plugin enables the consumption of CloudShell Sandboxes directly from TeamCity in order to be able to test complex testing environments.

When new code is pushed to the SCM system, TeamCity triggers a build configuration that starts a Sandbox using the CloudShell plugin to enable the execution of tests on that particular Sandbox’s components. Communication between TeamCity and CloudShell is provided by CloudShell’s Sandbox API, a RESTful API designed specifically for DevOps use cases that allows easy interaction with Sandboxes.

 

![1_Rpf3ibrN8_YOUCL76ejxLg](https://blog.quali.com/hs-fs/hubfs/1_Rpf3ibrN8_YOUCL76ejxLg.jpeg?width=832&name=1_Rpf3ibrN8_YOUCL76ejxLg.jpeg)

 

Here is an example of a Sandbox containing an application and some AWS services that mimic the staging configuration. This particular Sandbox is designed to be launched by TeamCity and will allow end-users to execute tests on the different components in the Sandbox.

 

![1_TsjHUwUErVitepmW8i6dtw](https://blog.quali.com/hs-fs/hubfs/1_TsjHUwUErVitepmW8i6dtw.png?width=832&name=1_TsjHUwUErVitepmW8i6dtw.png)

Sandbox containing an application and some AWS services

## Plugin Requirements & Design

The plugin comprises three main components: Admin configuration page, Build feature and a runner type.

- **Admin Configuration page** - Administration page that allows the TeamCity administrator to configure, manage and verify the plugin’s integration and connectivity with CloudShell. The connection info provided in this page will be used in the plugin’s other two components.

 

![1_cKCFB4QzlvPxNMPeoHwa6A](https://blog.quali.com/hs-fs/hubfs/1_cKCFB4QzlvPxNMPeoHwa6A.png?width=590&name=1_cKCFB4QzlvPxNMPeoHwa6A.png)

 

- **Build Feature (single Sandbox)** - Use this option if you want to use a build configuration with a specific Sandbox. The build feature will start a Sandbox prior to the execution of the build steps and will make sure to tear down the Sandbox just before the build completes.
- **“Start Sandbox” and “Stop sandbox” runner type (multiple Sandboxes)**- When more than one sandbox is needed in a build execution, a build step for starting and stopping each sandbox helps to manage the consumption of the different Sandboxes.

 

![1_-3yHdQ9IYqdjRMA7XKQIxg](https://blog.quali.com/hs-fs/hubfs/1_-3yHdQ9IYqdjRMA7XKQIxg.png?width=663&name=1_-3yHdQ9IYqdjRMA7XKQIxg.png)

 

## Admin configuration page

**Basics**  
To begin, we added an AdminPage class. This requires implementing the basic configuration of the page (the below basic configuration is from our plugin). Adding an admin page adds a new section in TeamCity’s Administration tab. Note that the new page is under the Integrations section as we override the getGroup() method and use the INTEGRATIONS\_GROUP constant.

 

![1_ncAMFEHn5lI_4X9oakACXg](https://blog.quali.com/hs-fs/hubfs/1_ncAMFEHn5lI_4X9oakACXg.png?width=1128&name=1_ncAMFEHn5lI_4X9oakACXg.png)

 

[SandboxAdminPage.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/java/com/quali/teamcity/plugins/sandbox/server/admin/SandboxAdminPage.java)

**Important**: Any new resource you add to the project must also be described as a Spring bean so that TeamCity will load it. To include the resource, just add it to the plugin’s XML file. For example:

XML file - missing

#### Handling plugin data on TeamCity server

The **Admin Page** we created will be used only as the presentation layer of our plugin. In order to store and use some logic in the TeamCity server, we will create a new controller that will handle the configuration.

 

![1_qKUvNHKHxAcjrUQ2NyZBuw](https://blog.quali.com/hs-fs/hubfs/1_qKUvNHKHxAcjrUQ2NyZBuw.png?width=832&name=1_qKUvNHKHxAcjrUQ2NyZBuw.png)

 

The **Settings Controller** extends BaseFormXmlController to allow easy HTTP POST and GET XML communication. In our case, only a POST request will be used to post data from the UI to the server.

The controller is added in the following way:

 

![1_s0urMqbQrz8OJ8kZwY6j8w](https://blog.quali.com/hs-fs/hubfs/1_s0urMqbQrz8OJ8kZwY6j8w.png?width=802&name=1_s0urMqbQrz8OJ8kZwY6j8w.png)

 

The controller gets a POST data form the main Admin Page and uses the **Admin Settings** class to save the configuration to a server-side config file.  
In this plugin, we implemented the admin settings class to store the configuration data in a properties file. It is also possible to save the configuration data using built-in functionalities in TeamCity. When you save the configuration on the server, the user is automatically redirected to the Admin Page, which is reloaded with the data from the properties file.z

![null](https://cdn-images-1.medium.com/max/2000/1*s0urMqbQrz8OJ8kZwY6j8w.png)

 

[SandboxSettingsController.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/java/com/quali/teamcity/plugins/sandbox/server/admin/SandboxSettingsController.java)

Admin Page user interface  
The Admin Page UI is implemented using a JSP form that has two main functionalities, depending on whether the **Save** or **Test Connection **button is triggered.  
The form includes a parameter that indicates the user-triggered functionality:

- submitSettings — for saving the configuration.
- testConnection — for test connection button.

In the Admin Page JSP, it looks like this:

![1_J3EvG2H0loynRxggu82T1g](https://blog.quali.com/hs-fs/hubfs/1_J3EvG2H0loynRxggu82T1g.png?width=832&name=1_J3EvG2H0loynRxggu82T1g.png)

[sandboxAdminSettings.jsp in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/resources/buildServerResources/sandboxAdminSettings.jsp)  
Handling passwords securely  
A key capability we wanted to achieve was to encrypt the password value during transmission between the client and the TeamCity server. To achieve this, we implemented an extra field in the form bean that stores a public key. When opening the Admin Page, TeamCity generates a public key on the server and sends it the page. Saving the configuration on the Admin Page encrypts the password (using the public key) in a way that allows the server to then decrypt it when it needs to use the same public key. In the properties configuration file, the password is stored encrypted as well.  
When one of the fields in the form is a passwordField, the value of the field should be described as an encrypedPassword.

![1_sN4kcFPW2z8fZyfEA4SOIQ](https://blog.quali.com/hs-fs/hubfs/1_sN4kcFPW2z8fZyfEA4SOIQ.png?width=832&name=1_sN4kcFPW2z8fZyfEA4SOIQ.png)

[sandboxAdminSettings.jsp in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/resources/buildServerResources/sandboxAdminSettings.jsp)  
To decrypt the value sent from the client and encrypt on the way back, we implemented setter and getter methods called *setEncryptedPassword* and *getEncryptedPassword *that will be called when the bean object is accessed.  
These methods use RSACipher to handle the values for us. The *getHexEncodedPublicKey getter *is implemented to ensure the public key is sent to the client in order to handle the encryption.

![1_i0MtZhT39IZKJKqLR_5qtA](https://blog.quali.com/hs-fs/hubfs/1_i0MtZhT39IZKJKqLR_5qtA.png?width=763&name=1_i0MtZhT39IZKJKqLR_5qtA.png)

[QsSandboxSettingsBean.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/java/com/quali/teamcity/plugins/sandbox/server/admin/QsSandboxSettingsBean.java)Test connection  
After the administrator fills in all the required fields in the Admin Page form, we want to make sure the integration works and the two systems (TeamCity and CloudShell) can communicate with each other. In our case, the test connection sends a login request to CloudShell. This request verifies that CloudShell is accessible and that the user is authorized to use CloudShell.  
TeamCity comes with few built-in options we can utilize to enhance the user experience during the test connection. For example, displaying a progress bar and a nice pop-up message once the test passes or fails.  
In the Admin Page JSP file, we included a link to a javascript file that comes with TeamCity called testConnection.js.  
`//JSP file`  
`<`**bs:linkScript**`>`  
`/js/bs/testConnection.js`  
`/plugins/sandbox/js/sandboxSettings.js`  
`</`**bs:linkScript**`>`  
`<`**script** `type="text/javascript">`  
`$j(function() {`  
`SandboxAdmin.SettingsForm.setupEventHandlers();});`  
`</`**script**`>`  
In order to utilize the built-in testConnection javascript functionality that comes with TeamCity, we implemented sandboxSettings.js. This file extends the base form behavior in TeamCity and registers to TeamCity form events.  
Here are the complete Sandbox settings we implemented:

![1_ernz5WxGok2bF9MV0Kt3Zg](https://blog.quali.com/hs-fs/hubfs/1_ernz5WxGok2bF9MV0Kt3Zg.png?width=795&name=1_ernz5WxGok2bF9MV0Kt3Zg.png)

[sandboxSettings.js in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/resources/buildServerResources/js/sandboxSettings.js)The built-in function *BS.TestConnectionDialog.show() *allows us to display pass/fail messages to the user.

![1_eygwyRfRvCrTEY2LcSLwHg](https://blog.quali.com/hs-fs/hubfs/1_eygwyRfRvCrTEY2LcSLwHg.png?width=832&name=1_eygwyRfRvCrTEY2LcSLwHg.png)

Build Feature  
As previously discussed, the CloudShell build feature was designed to start a Sandbox prior to running the user’s custom build steps and to stop the sandbox just before the build completes. To achieve this, we implemented the *AgentLifeCycleAdapter* class, which includes the *buildStarted* and *beforeBuildFinish* methods. The *AgentLifeCycleAdapter *is implemented on the agent side and will be packaged as another zip in the final plugin.  
The *BuildFeature* registration on the server is added by implementing the *BuildFeature *class. As noted in the Admin Page section, make sure to add the new class to the *plugin.xml* file.  
To implement field validations on the server, use the *getParametersProcessor*method.

![1_b7_r3Yr_LEGQcsqsKv6bDg](https://blog.quali.com/hs-fs/hubfs/1_b7_r3Yr_LEGQcsqsKv6bDg.png?width=832&name=1_b7_r3Yr_LEGQcsqsKv6bDg.png)

[QsSandboxBuildFeature.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/java/com/quali/teamcity/plugins/sandbox/server/feature/QsSandboxBuildFeature.java#L64)  
Passing the plugin configuration info to agent-side operations  
To start our sandbox both in the CloudShell build feature and in the CloudShell Sandbox runner type that will be described below, we need to access the main configuration settings from the agent side. In other words, we need to send CloudShell connectivity details from the server to the agent prior to the build’s execution.  
The *BuildStartContextProcessor *extension point allows us to manipulate the build context and to add additional information that will be accessible in the agent.  
In the example below, we added the CloudShell connectivity settings:

![1_OtgseRhXzUNNJRATSxr4jw](https://blog.quali.com/hs-fs/hubfs/1_OtgseRhXzUNNJRATSxr4jw.png?width=832&name=1_OtgseRhXzUNNJRATSxr4jw.png)

[SandboxBuildStartContextProcessor.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/master/teamcity-cloudshell-plugin-server/src/main/java/com/quali/teamcity/plugins/sandbox/server/runner/SandboxBuildStartContextProcessor.java)  
To access the CloudShell connectivity details from the agent side, we need to retrieve the shared parameter we set on the server *getSharedConfigParameters*method on the *AgentRunningBuild* parameter. In this example, the *buildStarted* method in our build feature just retrieves the shared parameter directly from the *AgentRunningBuild* variable:

![1_2EkJDxOF5BLFE-4JQwebWg](https://blog.quali.com/hs-fs/hubfs/1_2EkJDxOF5BLFE-4JQwebWg.png?width=832&name=1_2EkJDxOF5BLFE-4JQwebWg.png)

[SandboxPropertiesExtension.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/241b466bd90818fdc72808ce120eac540ad5081e/teamcity-cloudshell-plugin-agent/src/main/java/com/quali/teamcity/plugins/sandbox/agent/SandboxPropertiesExtension.java#L31)  
“Start Sandbox” and “Stop sandbox” runner type  
Adding a build step to TeamCity requires implementing a new *RunType* and adding it to the *plugin.xml* file. In our plugin, we wanted to implement a single runner type with two different actions, each with different parameters. For example: the “Start sandbox” action should get a blueprint name while the “Stop sandbox” action should only get the sandbox id to stop.  
Multiple actions in the same runner type  
In our *RunType *JSP file, we added a drop-down that lists the different actions available in the runner type.  
Note that the *currValue* of each of the options is *${modeSelected}. *This way, the form is consistent while the user selection will not change after saving the build step.

![1_oQEVjZQHbSXg2BjuDK-T6w](https://blog.quali.com/hs-fs/hubfs/1_oQEVjZQHbSXg2BjuDK-T6w.png?width=832&name=1_oQEVjZQHbSXg2BjuDK-T6w.png)

[sandboxRunnerParams.jsp in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/b99f11e8aa316a045d5cc3fbc91ceb21ea08fbb6/teamcity-cloudshell-plugin-server/src/main/resources/buildServerResources/sandboxRunnerParams.jsp#L16-L25)  
To control specific fields that should be shown for each of the actions, we added a javascript code that will show and hide the needed fields.

![1_XG-NnDnZ6iHhRdKfh0i5vg](https://blog.quali.com/hs-fs/hubfs/1_XG-NnDnZ6iHhRdKfh0i5vg.png?width=682&name=1_XG-NnDnZ6iHhRdKfh0i5vg.png)

[sandboxRunnerParams.jsp in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/b99f11e8aa316a045d5cc3fbc91ceb21ea08fbb6/teamcity-cloudshell-plugin-server/src/main/resources/buildServerResources/sandboxRunnerParams.jsp#L83-L107)On the agent side, we implemented an *AgentBuildRunner* that will house our custom *BuildProcess* implementation. The *buildProcess* implementation will then use the build parameters to locate and execute the relevant action (start sandbox or stop sandbox).

![1_PstZyBHixR7YHECsjBXd3A](https://blog.quali.com/hs-fs/hubfs/1_PstZyBHixR7YHECsjBXd3A.png?width=832&name=1_PstZyBHixR7YHECsjBXd3A.png)

[SandboxRunnerAgentBuildRunner.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/b99f11e8aa316a045d5cc3fbc91ceb21ea08fbb6/teamcity-cloudshell-plugin-agent/src/main/java/com/quali/teamcity/plugins/sandbox/agent/runner/SandboxRunnerAgentBuildRunner.java#L11-L16)

![1_2Nx6CJi4O768CLTHfWSfyg](https://blog.quali.com/hs-fs/hubfs/1_2Nx6CJi4O768CLTHfWSfyg.png?width=1015&name=1_2Nx6CJi4O768CLTHfWSfyg.png)

[SandboxBuildProcess.java in GitHub](https://github.com/QualiSystems/Sandbox-TeamCIty-Plugin/blob/83421af2f6fed197ef1d7f7566b8fd99852701cf/teamcity-cloudshell-plugin-agent/src/main/java/com/quali/teamcity/plugins/sandbox/agent/runner/SandboxBuildProcess.java#L19)  
Helpful tips

- Like every other TeamCity plugin out there, we started with an empty project, as described in [JetBrains confluence guide](https://confluence.jetbrains.com/display/TCD10/Getting+Started+with+Plugin+Development).
- We realized that the best approach for debugging and building the plugin was to use the [TeamCity-SDK-Maven-plugin](https://github.com/JetBrains/teamcity-sdk-maven-plugin/wiki/Developing-TeamCity-plugin) that can start afresh TeamCity server-agent setup for you directly from command line. This particular plugin was really useful for reloading our project whenever we performed agent-side code changes or changes to the project resources folder (*buildServerResources*).

Debugging TeamCity agent  
During the development process, we needed to debug the TeamCity agent. To do that, we added the following configuration to the *agent.bat* file located in the TeamCity agent folder (On Windows: C:\\TeamCity\\buildAgent\\bin). This code allows you to debug the agent over port 8001.  
`:agent_mem_opts_set_done`  
`SET TEAMCITY_AGENT_OPTS_ACTUAL=-Xdebug -Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=n %TEAMCITY_AGENT_OPTS% -ea %TEAMCITY_AGENT_MEM_OPTS_ACTUAL% -Dlog4j.configuration=file:../conf/teamcity-agent-log4j.xml -Dteamcity_logs=%TEAMCITY_AGENT_LOG_DIR%`

 

 

 

 

 

 

- Posted by Pascal Joly on February 18, 2018
- About Author: Pascal is the Director of Business Development at Quali, providing leadership for strategic business development initiatives with key technology vendors and channel partners. He has over 20 years of experience in large and small companies building and architecting software solutions for complex network and cloud infrastructure deployments.

 Topics: [Dev/Test](https://blog.quali.com/blog/topic/dev-test)

By Sean Harris - 18 February, 2018

#### 4 Major Business Problems Solved by Infrastructure Automation

[![read more](https://cdn2.hubspot.net/hubfs/685080/IMG-TurboSodium/Sodium%20v2/blog/arrow-recent-blog-post.png "read more")](https://blog.quali.com/blog/4-major-business-problems-solved-by-infrastructure-automation)

By Pascal Joly - 18 February, 2018

#### Infrastructure Automation at Scale: Blueprinting vs. Terraform

[![read more](https://cdn2.hubspot.net/hubfs/685080/IMG-TurboSodium/Sodium%20v2/blog/arrow-recent-blog-post.png "read more")](https://blog.quali.com/blog/environment-as-a-service-blueprinting-vs.-terraform)

By Sean Harris - 18 February, 2018

#### Why Infrastructure Automation Is Critical for Cyber Security

[![read more](https://cdn2.hubspot.net/hubfs/685080/IMG-TurboSodium/Sodium%20v2/blog/arrow-recent-blog-post.png "read more")](https://blog.quali.com/blog/why-infrastructure-automation-is-critical-for-cyber-security)

### Recent Posts

### Posts by Topic

- [DevOps (69)](https://blog.quali.com/blog/topic/devops)
- [Sales Demo (24)](https://blog.quali.com/blog/topic/sales-demo)
- [Dev/Test (21)](https://blog.quali.com/blog/topic/dev-test)
- [Automation (12)](https://blog.quali.com/blog/topic/automation)
- [infrastructure automation (12)](https://blog.quali.com/blog/topic/infrastructure-automation)
- [Environment as a Service (11)](https://blog.quali.com/blog/topic/environment-as-a-service)
- [colony (9)](https://blog.quali.com/blog/topic/colony)
- [ci/cd pipeline (6)](https://blog.quali.com/blog/topic/ci-cd-pipeline)
- [demo PoC (6)](https://blog.quali.com/blog/topic/demo-poc)
- [Qualifyi (5)](https://blog.quali.com/blog/topic/qualifyi)
- [Continuous Integration/Delivery (4)](https://blog.quali.com/blog/topic/continuous-integration-delivery)
- [Lab as a Service (4)](https://blog.quali.com/blog/topic/lab-as-a-service)
- [cloudshell pro (4)](https://blog.quali.com/blog/topic/cloudshell-pro)
- [Cloud and Virtualization (3)](https://blog.quali.com/blog/topic/cloud-and-virtualization)
- [Cyber Range (3)](https://blog.quali.com/blog/topic/cyber-range)
- ["infrastructure as code" (2)](https://blog.quali.com/blog/topic/infrastructure-as-code)
- [Sales Clouds (2)](https://blog.quali.com/blog/topic/sales-clouds)
- [Sales Demo/PoC (2)](https://blog.quali.com/blog/topic/sales-demo-poc)
- [Test & Test Lab Automation (2)](https://blog.quali.com/blog/topic/test-test-lab-automation)
- [application release (2)](https://blog.quali.com/blog/topic/application-release)
- ["trial demo" (1)](https://blog.quali.com/blog/topic/trial-demo)
- [DevOps/Agile IT (1)](https://blog.quali.com/blog/topic/devopsagile-it)
- [DevSecOps (1)](https://blog.quali.com/blog/topic/devsecops)
- [Events (1)](https://blog.quali.com/blog/topic/events)
- [JFrog (1)](https://blog.quali.com/blog/topic/jfrog)
- [Product Release (1)](https://blog.quali.com/blog/topic/product-release)
- [SDN & NFV (1)](https://blog.quali.com/blog/topic/sdn-nfv)
- [SDN & NFV & Networking (1)](https://blog.quali.com/blog/topic/sdn-nfv-networking)
- [Security (1)](https://blog.quali.com/blog/topic/security)
- [TechBlog (1)](https://blog.quali.com/blog/topic/techblog)
- [artifactory (1)](https://blog.quali.com/blog/topic/artifactory)
- [continuous testing (1)](https://blog.quali.com/blog/topic/continuous-testing)
- [continuous validation (1)](https://blog.quali.com/blog/topic/continuous-validation)
- [parallel delivery (1)](https://blog.quali.com/blog/topic/parallel-delivery)
- [repository (1)](https://blog.quali.com/blog/topic/repository)
- [salesforce (1)](https://blog.quali.com/blog/topic/salesforce)

View More

 

#### 4 Major Business Problems Solved by Infrastructure Automation

Every company and organization that develops software and applications needs environments. As they race toward innovating new products and...

[Read More](https://blog.quali.com/blog/4-major-business-problems-solved-by-infrastructure-automation)

 

#### Infrastructure Automation at Scale: Blueprinting vs. Terraform

\[This blog was originally published in November of 2019 and updated with new content in May of 2021.\] Whether you are a software architect,...

[Read More](https://blog.quali.com/blog/environment-as-a-service-blueprinting-vs.-terraform)

 

#### Why Infrastructure Automation Is Critical for Cyber Security

Revelations about the recent SolarWinds hack have highlighted the evolving sophistication and growing effectiveness of cyber attacks,...

[Read More](https://blog.quali.com/blog/why-infrastructure-automation-is-critical-for-cyber-security)

##### **Join 11,000+** CIOs, CTOs, ITOps, and DevOps practitioners on our newsletter and blog list

 Emails once or twice a week on cloud automation, infrastructure orchestration, and DevOps 

![](https://blog.quali.com/hs-fs/hubfs/Blue%20Arrow%201.png?width=69&name=Blue%20Arrow%201.png)

![footer-curve](https://blog.quali.com/hubfs/footer-curve.png "footer-curve")

### About Quali

Quali provides the leading platform for Infrastructure Automation at Scale. Global 2000 enterprises and innovators everywhere rely on Quali’s award-winning CloudShell platform to create self-service, on-demand automation solutions that increase engineering productivity, cut cloud costs, and optimize infrastructure utilization.

### Media Contacts

**PR**     pr AT quali.com

![](https://www.quali.com/wp-content/uploads/2019/05/logo-quali.png)

Quali is the industry leader in delivering cloud-agnostic Environment as a Service (EaaS) solutions for development and testing, sales demo/POC, training, and cyber range teams. Global 500 OEMs, ISVs, financial services, retailers, and innovators everywhere rely on Quali’s award-winning CloudShell platform to create self-service, on-demand environments that cut cloud costs, optimize infrastructure utilization, and increase productivity.

SOLUTIONS

[DevOps Cloud Automation](https://blog.quali.com/solutions/devops-environments/)

[Test Environments](https://blog.quali.com/solutions/software-test-environments-as-a-service/)

[Lab as a Service](https://blog.quali.com/solutions/network-and-security-dev-test-lab-as-a-service/)

[Sales Demos/Virtual PoCs](https://blog.quali.com/solutions/sales-demos-virtual-poc-environments/)

[Cyber Range Environments](https://blog.quali.com/solutions/cyber-range-environments/)

[Virtual Training Labs](https://blog.quali.com/solutions/virtual-training-labs/)

INDUSTRY SPOTLIGHT

[Financial Services Application Continuous Delivery](https://blog.quali.com/solutions/financial-services-application-continuous-delivery/)

[Lab as a Service for Banks](https://blog.quali.com/solutions/environment-as-service-for-banks-finserv/)

PRODUCTS

[CloudShell Pro](https://blog.quali.com/cloudshell-pro/)

[- Community](https://blog.quali.com/community/)

[- University](https://blog.quali.com/university/)

[- Support](https://blog.quali.com/community/support/)

[- Integrations](https://community.quali.com/integrations)

[CloudShell Colony](https://blog.quali.com/cloudshell-colony/)

[- Product](https://community.quali.com/integrations)

[- Integrations](https://community.quali.com/integrations)

[- Login](https://community.quali.com/integrations)

[PRICING](https://info.quali.com/pricing)

RESOURCES

[Resource Center](https://blog.quali.com/resource-center/)

[Blog](https://blog.quali.com/blog/)

[FAQ](https://blog.quali.com/faq/)

COMPANY

[About Us](https://blog.quali.com/about-us/)

[Why Quali](https://blog.quali.com/why-quali/)

[Customers](https://blog.quali.com/customers/)

[Leadership](https://blog.quali.com/about-us/#leadership)

[Newsroom](https://blog.quali.com/about-us/newsroom/)

[Locations](https://blog.quali.com/about-us/#locations)

[Careers](https://blog.quali.com/about-us/careers/)

[Awards](https://blog.quali.com/about-us/#awards)

[PARTNERS](https://blog.quali.com/partners/)

LEGAL

[Legal](https://blog.quali.com/legal/)

[Privacy Policy](https://blog.quali.com/qualiprivacypolicy/)

[Cookie Notice](https://blog.quali.com/cookie-notice)

INFO

[Contact Us](https://info.quali.com/contact-us)

**+1 877 QUALI 10**  
**[info@quali.com](mailto:info@quali.com)**

© Qualisystems LTD 2020

![](https://www.bizographics.com/collect/?pid=7400&fmt=gif)