Skip to main content

How to calculate the cost of CI/CD on top of Azure VSTS

In this post, we tackle the cost estimation of a CI/CD system that is hosted on top of Visual Studio Team Services (VSTS).

Context
We are starting from an on-premises system that has a CI/CD system build on top of Jenkins, which deploys the web application on a local IIS. Beside web application, we have for each project an SQL Server Database that can reach up to 100GB. The source control repository is GitHub, and for task management and tracking, we have JIRA.
In the current environment, we have around 20 projects that need such a migration, but the cost estimation is done project base, allowing us to have a better forecast for each project. We don’t take into consideration any other dependencies that a specific project could have like Windows Services.
Most of the client is already using Azure to host their production environments for their web application. Going into the cloud is more than acceptable for them. Beside this remember that you have the code inside GitHub.
In some cases, we are required to keep the output of the build for 6-12 months. It needs to be taken into consideration because inside VSTS the build output is deleted after a specific period.

Drivers
There are two main drivers that around this migration. The first one is related to on-premises hardware that needs to be upgraded. When you vision for the next 3-5 years is to be a cloud-first company you need to decide if you want to invest in new hardware of you externalize it.
The second driver is related to security and privacy. Clients require dedicated sandboxes where the CI/CD pipelines shall run and isolated testing environment. It is hard and expensive to offer using on-premises systems.
These two drivers make you look at a cloud offer, where you have already configured everything, you pay based on your need. Maintenance cost is lower, and you can grow or shrink depending on how well the business goes.

Mission 
In the scope of the current cost estimation, we have only the CI/CD system and the environment where we deploy our web applications. The rest of the systems (GitHub and JIRA) are hosted outside the organization, and we don’t want to do any changes related to it.

High-level overview
The following Azure Services are required to be able to achieve our mission:

1. Build Machine
For the build machine, the initial phase is to with Microsoft-hosted CI/CD, where you can't change the tier, and you are running in a ‘shared resource pool’ if we can call in this way. The advantage is the cost per month that is flat and affordable (40$). When necessary, Self-Hosted CI/CD is a good option, but only when are required. You don’t want to manage the build agent by yourself.
Each project shall have it’s own Microsoft-hosted CI/CD, giving the flexibility to run their builds when necessary, without waiting for others. It enables us to be isolated complexity the access to each CI/CD per team and not per organization.

2. Website hosting
For web application hosting, there are two interesting locations where we could do this. The first one is inside Azure Web Apps, where we can deploy the web application. There is full control at the project level how we want to configure and setup.
Another approach would be Azure DevTest that support Web Apps. Even if you have more granular access, the lack of an Azure SQL Database option makes us, for now, to look at Web Apps and Azure SQL Database. We don’t want to add extra complexity by using multiple types of resources. In the next section, we will talk more about it.

3. DB Storage
The most appealing one at this moment is Azure SQL Database, where S0 tier is more than enough. There are some cases when Basic tier works as well, but this is more a cost optimization, and I don’t want to tackle this subject for now.
There is full control of the DB, with a small risk that there might be some features that are not supported inside Azure SQL Database.
Azure DevTest is another option, that is appealing. It’s a perfect location where we can run the DBs that are not compatible with Azure SQL Database. The main downside of it is the price, that is more expensive. Yes, even if you have multiple SQL Databases inside SQL Server Web Virtual Machines, it’s not appealing enough. We want to have a sandbox for each project and avoid resource sharing.
On long-run Azure DevTest will become the best place for this scenario, but for now, Azure SQL Databases and Azure Web Apps are the best options for the context presented at the beginning of the article. For now, another advantage is the cost monitoring, that can be made from only one location. If we combined Azure DevTest Labs with other resources, it would become a little more complex.

4. Artifacts History
To be able to store build output for a long period, the most simple solution is Azure Blob Storage, that can be used to store and archive any artifact. With the policy capability that is allowing us to delete automatically content after a specific period, gives us the perfect place to store the build output.
Remark: Once Azure DevTest Labs will have support for PaaS (more specific Azure SQL Database), the migration to Azure DevTest will be smooth and fast. From this perspective, it is just a matter of time.

Cost Inputs
To be able to do a cost estimation as close a possible to reality we need to collect the right data that can affect our monthly cost. The things that I identify and I consider that is relevant in this discussion are the following:

  • Average build duration
  • Number of builds per day
  • Build output size
  • Build storage duration
  • Database size
  • Web app complexity

Each of this item needs to be considered for each environment type of pipeline.

Cost calculation
To simplify the calculation, we are doing the cost calculation only for the development pipeline that deploys the solution to a development environment (Web Application with an Azure SQL Database). The total cost per month of a CI/CD that includes the Development environment would be 63$. If we remove the development environment and focus only on the CI/CD cost, the cost per month would be around 41$ per month. The difference is coming from the Web App instance and Azure SQL Database instance. 
The following requirements were used to calculate the cost:
with the following requirements:

  • Average build duration: 5 minutes
  • Number of builds per day: 50 builds
  • Build output size: 200 MB
  • Build storage duration: 90 days
  • Database size: 5 GB
  • Web app complexity: Low (Web App with Basic tier)

The total number of build minutes per month is around 9.000; this means that we can have a dedicated concurrent job, which cost 40$ per month.
You can easily add 2-3 additional environments or create multiple pipelines when needed. You can even share the same Microsoft-hosted CI/CD job cross pipelines as long as are under the same VSTS project.
It means that if you have 4-5 projects hosted inside GitHub, you could have the same job shared between them and dedicated pipelines for each of them. In this way, you could drastically reduce the cost.

Conclusion
As you can see, the cost per month of CI/CD inside Microsoft Azure it’s more than acceptable. Based on what you want to achieve, the price can go up or down. One of the most important capabilities that Azure is offering around it is the possibility to extend and add complexity to your system as much as you need.

Comments

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(

Azure AD and AWS Cognito side-by-side

In the last few weeks, I was involved in multiple opportunities on Microsoft Azure and Amazon, where we had to analyse AWS Cognito, Azure AD and other solutions that are available on the market. I decided to consolidate in one post all features and differences that I identified for both of them that we should need to take into account. Take into account that Azure AD is an identity and access management services well integrated with Microsoft stack. In comparison, AWS Cognito is just a user sign-up, sign-in and access control and nothing more. The focus is not on the main features, is more on small things that can make a difference when you want to decide where we want to store and manage our users.  This information might be useful in the future when we need to decide where we want to keep and manage our users.  Feature Azure AD (B2C, B2C) AWS Cognito Access token lifetime Default 1h – the value is configurable 1h – cannot be modified

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine: threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration: TeamCity .NET 4.51 EF 6.0.2 VS2013 It see