--- layout: post title: "Caylent brings their build, deployment, and management of container-based apps to Azure with Azure Resource Manager (ARM)" author: "Martin Schray" author-link: "https://twitter.com/mschray" #author-image: "{{ site.baseurl }}/images/authors/photo.jpg" date: 2017-07-28 categories: [DevOps] color: "blue" image: "images/Caylent/caylent-logo-header.png" excerpt: This project brings Caylent's container management offering and DevOps capabilities to Azure by using Azure Resource Manager (ARM) templates, REST APIs, and Azure Functions. language: [English] verticals: [Professional Services] geolocation: [North America] --- [![Caylent Logo]({{ site.baseurl }}/images/Caylent/caylent-logo.png)](https://caylent.com) Caylent is a container management platform that helps software teams automate containers, cloud services, and microservices. Although containers are now widely popular, they continue to present myriad challenges to both enterprises and startups alike. Configuring, scaling, and managing containers and their underlying infrastructure can be time-consuming and demanding. Caylent's platform alleviates much of the heavy lifting by automating infrastructure provisioning, configuration management, and deployment of containers. Additionally, DevOps practices are revolutionizing and increasing information technology's impact on the businesses they are integrated with. Because Caylent's container solution requires deep integration with a cloud platform to deploy, modify, monitor, maintain, and scale users' containers and underlying infrastructure, Caylent is adding Microsoft Azure as a supported cloud provider and deployment option for their customers. This project focused on enabling Caylent's solution to deploy, scale, and manage container environments on Azure while bolstering a customer's DevOps practices, specifically: - Integrating with Azure's mechanisms to: - Authenticate and authorize Caylent's solution to operate on behalf of their customers. - Receive logging (success or failure), performance, and deployment status (started, pending, running, complete). - Receive notification of scaling operations. - Integrating with Azure's REST APIs to create, deploy, modify, and maintain deployed container solutions. - Integrating Caylent's model for generating and creating cloud, network, and stack layers within the Azure platform. - Building a multi-tenant solution that could operate through an event-oriented architecture. - Leveraging DevOps practices such as Infrastructure as Code (IaC) and continuous delivery (CD). ### Key technologies used - [Azure Resource Manager](https://azure.microsoft.com/en-us/features/resource-manager/) - [Azure Resource Manager templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview#template-deployment) - [Azure Resource Manager REST API](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-deploy-rest) - [Azure Service Bus](https://azure.microsoft.com/en-us/services/service-bus/) - [Azure Functions](https://azure.microsoft.com/en-us/services/functions/) - Azure Functions continuous delivery capabilities ### Core team - [JP La Torre](https://twitter.com/josephlatorre) – CEO/Co-Founder, Caylent - [Stefan Thorpe](https://twitter.com/stefanthorpe) – CTO/Co-Founder, Caylent - [Julia Pearson](https://twitter.com/juliakpearson) – Software Engineer, Caylent - [Martin Schray](https://twitter.com/mschray) – Senior Technical Evangelist, Microsoft - [Kwadwo Nyarko](https://twitter.com/KJNyarko) – Technical Evangelist, Microsoft ## Customer profile [Caylent](https://caylent.com) is a container management platform that helps software teams automate containers, cloud services, and microservices. Caylent delivers solutions for DevOps-oriented teams that need automation and integration across the DevOps pipeline. Caylent's core product is a software as a service (SaaS) platform that allows users to deploy container-based applications and stacks to high availability infrastructure inside their own cloud provider. Container orchestration, infrastructure, and deployment automation is abstracted and fully managed, which allows software teams to focus solely on the application. Caylent is a remote team with offices in New York, NY. ## Problem statement In a container environment, setting up, configuring, managing, and maintaining container-centric infrastructure can be time-consuming and demanding. Containerized environments also require other tasks such as monitoring and scaling, which means less time developing solutions and products. Additionally, to enable DevOps best practices such as Infrastructure as Code (IaC), it is necessary to capture the script and templates used to create infrastructure. The automation of high availability cloud infrastructure deployment often requires companies to tediously script and manage the configuration of virtual networks, load balancers, virtual network interface cards, storage accounts, virtual machines, public IP addresses, and firewall rules. Caylent's platform solves this by automating multi-host container deployment across hardened infrastructure. Caylent wanted to bring their powerful container management offering to Azure, so that Azure customers could benefit from their simplified automation platform and achieve the same repeatable enterprise-grade infrastructure without needing to build it themselves, while enabling the customer to participate in DevOps best practices such as IaC. ### Challenge Caylent wanted to bring their container management solution to Azure to extend their footprint across the enterprise. They had to look for integration points and approaches to create and manage a multi-tenant optimized cloud infrastructure that could eventually support hundreds of thousands of nodes across many customers. Because Caylent was already fully deployed and integrated with another cloud provider, the Azure customer experience needed to match the experience on the other platform, while integrating with Azure's unique capabilities. ### Customer testimonial > "Caylent's deployment automation solution makes developing in the cloud a possibility for our team. We are able to eliminate the overhead of specific cloud ecosystems and APIs, letting our developers focus on application code while improving the speed and quality of our releases. Every developer works within a "production-like" environment, reducing release-night deployment faults and focusing our tech resources on delivering business value. I truly feel that their solution will evolve how distributed systems are written, tested, and deployed." —Stefan Kutko, VP Engineering, Electronifie
## Solution and steps Our joint goal was to extend the Caylent platform capabilities to create an automated Caylent reference architecture on Azure (as shown in Figure 1). This architecture implements redundancy, scaling, and failover best practices, and includes powerful monitoring capabilities. It also allows for DevOps best practices such as automation, Infrastructure as Code (IaC), and continuous delivery.
*Figure 1. Caylent's deployed container architecture* ![Figure 1. Caylent's deployed container architecture]({{ site.baseurl }}/images/Caylent/deployed-architecture-4.png)
The team decided to use [value stream mapping](https://en.wikipedia.org/wiki/Value_stream_mapping) (VSM), used initially in lean manufacturing and now prevalent in DevOps cultures. We used VSM as a mechanism for understanding the time and effort required to create an environment similar to the Caylent reference architecture: - Manually via the Azure portal - Using Azure Resource Manager (ARM) templates - Using Caylent's container management solution - Using Azure Functions This allowed us to evaluate and compare each approach in terms of targeting and eliminating redundancy and waste, and seeking increased efficiency through automation. ### Current state: manual creation of deployed environment Caylent and Microsoft started our project with an overview walkthrough to determine how Caylent's solution worked. We built a current state VSM to represent the process, steps, and necessary effort to approximate the *manual effort* required to create a container solution similar to the one Caylent creates for their customers. Figure 2 shows that, depending on the complexity and superintendency of what is being created, it could take many hours to create a minimum container solution if we used the Azure portal to create each component separately. This solution would not be easily repeatable and would lack the monitoring and scaling capabilities that Caylent provides.
*Figure 2. Current state: manual creation of deployed environment* ![Figure 2. Current state: manual creation of deployed environment]({{ site.baseurl }}/images/Caylent/current-state-manual-2.png)
In Figure 2, time is spread fairly uniformly throughout the creation process. The diagram also shows that there is a significant amount of wasted time waiting for resources to be created and repeating that process over and over until all of the related and dependent resources are created. Additionally, this approach does not lend itself to reasonably allow for the created infrastructure to be saved as code for later reuse, which would be a reasonable DevOps goal. Given these shortcomings, we next explored a VSM leveraging Azure Resource Manager (ARM) templates. ### Current state: ARM template creation of deployed environment We constructed a current state VSM using [Azure Resource Manager (ARM) templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authoring-templates) to approximate the effort required to create a container solution similar to the one Caylent creates for their customers. By using ARM templates, we could construct reusable JSON templates to programmatically generate Azure resources. We could save these JSON templates by using the DevOps practice of Infrastructure as Code (IaC), which was an improvement over the manual process covered earlier. The VSM in Figure 3 shows (depending on how complex and superintendent the container solution is) that it would take many hours to create a minimum container solution, and the solution wouldn't have Caylent's solution monitoring and scaling capabilities.
*Figure 3. Current state: ARM template creation of deployed environment* ![Figure 3. Current state: ARM template creation of deployed environment]({{ site.baseurl }}/images/Caylent/current-state-arm-template-2.png)
While ARM templates are a fine approach for creating infrastructure, they did not allow us the dynamic capabilities that Caylent's solution would provide. We realized that using ARM templates was not a good way to build a dynamic and automated solution. As the VSM shows, the majority of the template creation time is spent building and testing the template itself. While this approach yields a reusable, somewhat flexible template, it must be maintained over time and does not cover required features such as configuration management, container orchestration, and deployments. While there is a growing set of user-contributed ARM templates available to create environments, they don't offer the speed and flexibility offered by Caylent's Blueprints, which allow you to select standardized, hardened, best practice container solutions. ### Future state: Caylent creation of deployed environment Having used the current state VSMs to explore Azure portal and ARM template creation of a containerized infrastructure, we then envisioned the use of Caylent's container solution to create an automated Caylent reference architecture on Azure. To that end, we constructed a future state VSM that reflects Caylent's container solution deploying to Azure, based on their container automation environment. Figure 4 shows the effects of standardization and automation on the process of creating a containerized infrastructure on Azure. The Caylent Blueprint is selected, needed parameters (such as names) are provided in the Caylent portal, and the creation process is started. The user is notified when the creation process is complete so they can do other work while their containerized environment is created.
*Figure 4: Future state: Caylent creation of deployed environment* ![Figure 4: Future state: Caylent creation of deployed environment]({{ site.baseurl }}/images/Caylent/future-state-2.png)
In summary, using Caylent's unique Application Wizard (via the Caylent portal), resource creation is automated, repeatable, and efficient. While Caylent's solution uses ARM templates and the Azure Resource Manager REST APIs, the Blueprints that represent predefined container environments are the key to Caylent's speed and flexibility. Because we could export and save the ARM template that was used to create the containerized environment, we could achieve the DevOps practice of IaC. ### Current state: Azure Functions deployment Initially, we were doing local development and testing work with our implementation for Azure Functions. As the current state VSM in Figure 5 depicts, we used manual steps to push to version control, pull from version control, and use FTP for Azure Functions staging. With many changes happening during development, these manual steps could take up to five minutes of developer time for each deployment to staging. Figure 5 shows that each deployment took 4–5 minutes, meaning that five deployments could take 20–25 minutes, and the developers' time was consumed by these deployments. We quickly decided to leverage the continuous delivery capabilities of Azure Functions.
*Figure 5. Current state: Azure Functions deployment* ![Figure 5. Current state: Azure Functions deployment]({{ site.baseurl }}/images/Caylent/deploy-azure-functions-current-state-2.png)
### Future state: Azure Functions deployment In Figure 6, we depict the future state VSM for continuous delivery to Azure. The benefits include removing the nearly five minutes required to push, pull, and use FTP to send the files to Azure Functions. As we will share in detail later in the writeup, we used Azure continuous delivery to connect Bitbucket to Azure Functions, so our push to Bitbucket immediately deployed our code to staging. During the iterative development process, this introduction of automation saves a considerable amount of time for each deployment. Our future state VSM shows that each deployment took one minute to a minute and thirty seconds, meaning that five deployments could take at most 10 minutes, a 50% improvement over the manual process. More importantly, due to automation, developer time was completely free after the deployment was triggered with the push to version control.
*Figure 6. Future state: Azure Functions deployment* ![Figure 6. Future state: Azure Functions deployment]({{ site.baseurl }}/images/Caylent/deploy-azure-functions-future-state-2.png)
## Technical delivery Several implementation components enabled Caylent to bring their powerful container management solution to Azure: - The extension of Caylent's core platform and capabilities to target Azure as a supported and optimized cloud deployment platform - Building Azure REST APIs in PHP for Azure Resource Manager - Building Azure Functions to monitor status and scaling operations on Azure resources Each of these components will be discussed in turn in the following sections. ### Extension of Caylent core platform Caylent abstracts the cloud containerization environment in a cloud provider (such as Azure), network (virtual private network, network security rules, ...) and stack (containers, load balancer, ...). Figure 7 shows a generalization of Caylent's Cloud Abstraction Model. Caylent has abstracted the cloud provider, network, and stack, which generates the authentication, appropriate API bindings, templates, or scripts to create an implementation on a cloud provider's system.
*Figure 7. Caylent Cloud Abstraction Model generalization* ![Figure 7. Caylent Cloud Abstraction Model generalization]({{ site.baseurl }}/images/Caylent/general-container-abstraction-2.png)
For this project, Caylent implemented a specific Cloud Provider Abstraction Model designed for Azure. The implementation provided an Azure-specific (Azure plus Azure's approach to authentication and authorization) cloud provider implementation, a network (network security groups, virtual private networks, and network interface cards), and a stack (containers, load balancer, operating systems, and web server). Figure 8 shows an Azure-specific implementation of Caylent's Cloud Abstraction Model, in which Caylent has implemented Azure as the cloud provider, network, and stack. ARM templates create a Caylent container management solution on Azure. As Figure 8 illustrates, Caylent generates the ARM templates, which are submitted (via Azure Resource Manager REST APIs) and monitored by Caylent's solution.
*Figure 8. Caylent Cloud Abstraction Model specific implementation* ![Figure 8. Caylent Cloud Abstraction Model specific implementation]({{ site.baseurl }}/images/Caylent/azure-container-abstraction-2.png)
#### Architecture A Blueprint is Caylent's predefined industry best practice "template" for quickly deploying a container solution. A Caylent customer can sign in to Caylent's Container Management Software as a Service (SaaS) portal to create an Application Collection from either a Blueprint or a custom container set; these can be deployed across any number of environments and centrally managed. The Blueprint deploys to Azure through Caylent's Cloud Abstraction Model, the generated ARM template, and the Azure Resource Manager REST API. Depending on what the ARM template indicates, Azure Resource Manager either creates an Azure Resource Group or uses an existing one. The Resource Group is the logical underlying resource (network and stack) that forms the core of a Caylent Application Collection or Blueprint. Caylent monitors the status, scaling operations, and health of the deployment resources. Caylent uses Azure alerts delivered via Webhook for the deployment status and scaling operations. Azure Functions and Azure Service Bus play important roles that will be discussed later in this study.
*Figure 9. Caylent architecture* ![Figure 9. Caylent architecture]({{ site.baseurl }}/images/Caylent/caylent-architecture-2.png)
#### Infrastructure as Code (IaC) Caylent's offering can be part of the solution for startups or enterprises looking to increase their performance by implementing DevOps practices. One practice that Caylent can immediately contribute to is the idea of Infrastructure as Code (IaC). Why use IaC? > "Virtualization, cloud, containers, server automation, and software-defined networking should simplify IT operations work. It should take less time and effort to provision, configure, update, and maintain services. Problems should be quickly detected and resolved, and systems should all be consistently configured and up to date. IT staff should spend less time on routine drudgery, having time to rapidly make changes and improvements to help their organizations meet the ever-changing needs of the modern world." —Keif Morris, author of *[Infrastructure as Code](https://www.safaribooksonline.com/library/view/infrastructure-as-code/9781491924334/ch04.html)*
Caylent's container management solution allows for the capture and storage of the JSON ARM template used to create a containerized environment on Azure. This allows the user to quickly and easily store, retrieve, and create consistent configurations for their containerized solutions. ### Azure REST API Caylent uses a PHP framework called Laravel on their backend. At implementation time, the [Microsoft Azure SDK for PHP](https://github.com/Azure/azure-sdk-for-php) did not provide [Azure Resource Manager REST API](https://docs.microsoft.com/en-us/rest/api/resources/) client APIs, so we implemented a number of the API methods for our use. When the Microsoft Azure SDK for PHP implements these capabilities, the Caylent team will migrate and use these new capabilities rather than maintaining a separate implementation. In addition to building out authentication via Azure Active Directory, the Microsoft team contributed PHP code for the Azure Resource Manager implementation, which includes [Deployment Operations](https://docs.microsoft.com/en-us/rest/api/resources/deploymentoperations), [Deployments](https://docs.microsoft.com/en-us/rest/api/resources/deployments), and [Resource Groups](https://docs.microsoft.com/en-us/rest/api/resources/resourcegroups). While the Microsoft team created these implementations, the Caylent team built out abstractions for cloud provider, network, and stack on Azure as seen in [Figure 8](#extension-of-caylent-core-platform). Caylent's abstraction can be thought of as a container deployment object model. The model knows (in real terms) how to render (for various cloud providers) these abstractions in code, scripts, or templates to power the containerized infrastructure deployment, maintenance, and monitoring in a multi-tenant environment. For Azure, these abstractions render themselves in ARM template format JSON files. With the Azure Resource Manager API PHP implementation in place, and with Caylent's cloud containerization abstraction layer generating ARM templates, we could generate and maintain the Azure-based, Caylent infrastructure solution. > View a [sample ARM template](https://github.com/mschray/AzureVMCreate), *Create 2 virtual machines in an availability set and configure NAT rules through the load balancer*.
Next, based on real-world usage patterns, we needed to bring notifications, monitoring, and lifecycle hooks to these environments and autoscale definitions. To do this, we turned to Azure Functions. ### Azure Functions After Caylent's platform triggers resource deployment, scaling, or removal, it relies on a notification and events system to monitor waiting, in process, and completed jobs along with created items and any failed resource operations. Azure has several mechanisms to get this type of information, but (like polling) many require repeatedly calling an API, which is not resource efficient. However, Azure can fire a Webhook endpoint to efficiently deliver deployment and scaling status information notifications. The Caylent team decided to use Azure Functions as the Webhook endpoint for these deployment and scaling notifications and alerts. While [Azure WebJobs](https://docs.microsoft.com/en-us/azure/app-service-web/websites-webjobs-resources) would have worked as well, we choose Azure Functions because it allowed us to: - Be productive right away because it provided a serverless development experience. - Start writing code (in languages such as C#, Node.js, PHP, Python, and Bash) without setting up server infrastructure or application frameworks. - Select from a robust set of event triggers, such as the Webhook endpoint that we used for alerts and notifications. - Support a rich set of data bindings, such as Azure Service Bus, which made use of durable message processing. - Only pay for what we used because we are billed based on resource consumption and executions. - Write and test our code, log outputs and errors, and monitor execution from a single user interface without installing and configuring additional developer tools. Additionally, Azure Functions enables Caylent to quickly: - Bind to various triggers, such as schedules, REST or Webhook, blob storage, events, queues, timers, and Service Bus queues or topics. - Read from inputs, such as blob storage, tables, Service Bus queues, and DocumentDB. - Bind to various outputs, such as tables, DocumentDB, and push notifications. We choose to write our Azure Functions in JavaScript. Azure Functions allowed the team to easily incorporate shared code (code that can be used across several functions). The following example shows the shared-code component (`AzureLogAnalyticsHelper`) loading by using the standard Node.js required syntax. `AzureLogAnalyticsHelper` is shared code that provided logging services for each of our Azure Functions (find source code at [AzureLogAnalyticsHelper](https://github.com/mschray/AzureLogAnalyticsHelper)). ```javascript // setup the message to the logger var jsonMessage = JSON.parse("{}"); var uuid = require('node-uuid'); **var logger = require('../Shared/AzureLogAnalyticsHelper.js');** var gcontext; ```
Caylent wanted to further enhance the reliability of Webhook and Azure Functions with durable messaging to store alerts and notifications until they were processed. To do this, we used the Azure Service Bus, which provides a reliable message-delivery service. Azure Service Bus is a brokered communication mechanism allowing messages to be thought of as asynchronous, or "temporally decoupled." We used a producer (sender) and consumer (recipient) pattern to decouple our Webhook output (producer) and Azure Functions (consumer) by writing outputs to a Service Bus topic. This effectively allowed the producer and the consumer to operate and be scaled independently. Figure 10 shows the Webhook, Azure Functions, and Service Bus portions of the architecture.
*Figure 10. Caylent architecture Azure Functions view* ![Figure 10. Caylent architecture Azure Functions view]({{ site.baseurl }}/images/Caylent/CaylentArchitectureAzureFunctions.png)
Figure 11 shows how Azure Functions made it easy to bind to the Webhook, which is acting as a trigger to this function, and to a Service Bus topic, which is acting as an output to this function.
*Figure 11. Azure Service Bus trigger* ![Figure 11. Azure Service Bus trigger]({{ site.baseurl }}/images/Caylent/AzureFunctionTrigger.png)
We defined an Azure function (`CaylentNotifierWebHook`) to serve as the endpoint for our alerts Webhook. When the Webhook was used, it fired `CaylentNotiferWebHook`, which checked for null input; if the input wasn't null, `CaylentNotiferWebHook` wrote the data from the Webhook to the Service Bus topic as the following code shows: ```javascript const logger = require('../shared/AzureLogAnalyticsHelper.js'); module.exports = function (context, data) {        context.log('Webhook  was  triggered!'); logger.writeLogEntry(context, "{message: 'Wehbook was triggered!'}");          if(data  !==  null)  {                context.log(JSON.stringify(data,  null,  4));                context.bindings.outputSbMsg  =  data;        }        context.done(); } ```
When a message is written to the Service Bus, it triggers the `CaylentBusDequerer` Azure function. `CaylentBusDequerer` takes the Service Bus topic message that triggered it and sends the alert to the Caylent system, passing the message that triggered it in the `mySbMsg` argument. In the following partial code snippet, we set up the Caylent endpoint to reach alerts from Azure relating to deployment status and scale operations. > Note: `process.env` allows us to read the loaded Azure app settings so we can access them.
```javascript const logger = require('../shared/AzureLogAnalyticsHelper.js'); module.exports  =  function(context,  mySbMsg)  {        context.log('JavaScript  ServiceBus  queue  trigger  function  processed  message'); logger.writeLogEntry(context, "{message: 'JavaScript ServiceBus queue trigger function processed message'}");        context.bindings.outDoc  =  mySbMsg;            //send  post  request  to  caylent  endpoint        const  https  =  require('https');        let  options  =  {                hostname:  process.env.CAYLENT_NOTIFIER_HOSTNAME,                path:  process.env.CAYLENT_NOTIFIER_PATH,                method:  process.evn.CAYLENT_NOTIFIER_METHOD,                port:  prorcess.env.CAYLENT_NOTIFIER_PORT,                headers:  {                        'Content-Type':'application/json',                }        };          let  req  =  https.request(options,  (res)=>  {                context.log('statusCode',  res.statusCode);                context.log('headers',  res.headers);                res.on('data',  (d)=>  {                        context.log('data:',  d); logger.writeLogEntry(context, `{data: '${d}'}`);                });        });          req.on('error',  (e)=>{ ```
Figure 12 illustrates how to navigate your Azure Functions to app settings.
*Figure 12. Caylent architecture Azure Functions to app settings view* ![Figure 12. Caylent architecture Azure Functions to app settings view]({{ site.baseurl }}/images/Caylent/AppSettings.png)
Azure Functions has many triggers, inputs, and outputs. In the earlier example, one of those outputs is DocumentDB, which allowed us to create a permanent logging store for update notifications. Azure Functions allows us to easily include libraries with the project.json file. By adding project.json to our various Azure Functions, we could pull in [npm](https://www.npmjs.com/) packages. Npm provides package management for Node.js apps, so our team leveraged its pre-built functionality. Similarly, for .NET Azure Functions, you can use package.json with [NuGet](https://www.nuget.org/) packages. NuGet provides package management for .NET apps. Caylent didn't need to pull in any npm packages, but it was great to know the capability was available. #### Continuous delivery A DevOps practice that was used by the Caylent and Microsoft teams was continuous delivery: > "Continuous delivery is a series of practices designed to ensure that code can be rapidly and safely deployed to production by delivering every change to a production-like environment and ensuring business applications and services function as expected through rigorous automated testing." —Carl Caum, author of *[Continuous Delivery vs. Continuous Deployment: What's the Diff?](https://puppet.com/blog/continuous-delivery-vs-continuous-deployment-what-s-diff)*
Caylent wanted to deploy directly from their Bitbucket version control system into their staging environment for more complete testing before making the decision to deploy to production (continuous delivery). As shown in Figure 13, using the Azure portal, we used the Azure Functions app we had created for Caylent in the previous step and added a web deployment slot for staging, which at the time of this writing was in preview. The same virtual machines managed by Azure host both the production and any additional web deployment slots, including the one we had set up for staging.
*Figure 13. Azure Functions app web deployment slot* ![Figure 13. Azure Functions app web deployment slot]({{ site.baseurl }}/images/Caylent/DeploymentSlot.png)
After we had created the staging web deployment slot (Figure 14), we used the Azure portal for a staging slot to set up Azure continuous delivery. We selected Bitbucket as the deployment source, and the Caylent team provided their credentials and selected the repo to deploy from.
*Figure 14. Azure Functions app deployment options* ![Figure 14. Azure Functions app deployment options]({{ site.baseurl }}/images/Caylent/DeploymentOptions.png)
The Caylent team wanted to use continuous delivery, which the Caylent team defined as deploying to staging from version control after every check-in. This allowed them to execute automated tests on staging before making the decision to deploy to production. The benefits of this approach were: - Replacing a time-consuming manual process that used a developer's time to check in, check out, and use FTP to deploy code changes to staging. - Using Azure continuous delivery to automate deployment to staging after code changes were checked in. - Using a staging environment that closely mirrored production that allowed automated and manual testing after every check-in. - Saving four to five minutes of developer time for each automated deployment. Figure 15 illustrates this approach.
*Figure 15. Azure Functions app deployment diagram* ![Figure 15. Azure Functions app deployment diagram]({{ site.baseurl }}/images/Caylent/azure-functions-app-deployment-2.png)
## Conclusion ## While containers are being adopted by many software development teams, the things to consider before doing so include cloud architecture, infrastructure deployment repeatability, container orchestration, configuration management, and toolchain maintenance. Containers make life easier for those that adopt them, but also present unique challenges. A container management solution such as Caylent's reduces operational and deployment complexity, increases release velocity, and shrinks infrastructure costs. Caylent benefited by extending their container management SaaS offering to Azure. Caylent's customer benefited by the fact that Caylent's container management solution now supports Azure. Why? As the [current state VSM](#current-state-manual-creation-of-deployed-environment) illustrates, Caylent's solution shortens the time required to deploy a container management solution from many hours to minutes. Providing their solution to Microsoft Azure customers is an important business opportunity to grow Caylent's customer base. Caylent's customers and potential customers benefit from the powerful container management capabilities that Caylent now delivers to the Azure platform. Organizations can select from Caylent predefined Blueprints to create, maintain, and scale containers and high availability infrastructure inside their own Microsoft Azure cloud. Additionally, the team came away with these insights: - VSMs were a powerful way to explore the current state and future (anticipated) state to understand where to focus energy and effort to remove inefficient and manual effort; using VSMs allowed us to easily: - Quantify the benefits of bringing Caylent's container management solution to Azure. - Identify that removing the manual movement of code from source control to Azure Functions would free almost four minutes of developer time *each* time the developer wanted to deploy code from source control to staging. During a sprint, this can happen hundreds of times, so small time savings that happen frequently can have a significant impact. - With some initial planning, we were able to identify several DevOps practices such as IaC that would be beneficial to Caylent's customers, or practices such as continuous delivery that were very useful to our team. - Azure comprehensive REST APIs and ARM templates provided ample integration capabilities allowing the Caylent team to bring their solution to Azure. - Our hackfest team was made up of local and remote team members in different geographic locations, including different continents. By carefully and thoughtfully defining our approaches, desired goals, and outcomes before we started, along with designing small testable tasks, and establishing predefined team check-ins, the distributed hackfest team was very effective and productive. - While containers are a powerful mechanism and approach for managing your cloud-native applications, they still require attention and management, such as the capabilities that Caylent provides. Caylent will continue to add to their offering by extending integration points within the Azure platform and ecosystem. > "We had a fantastic experience working with the team at Microsoft. Collaborating with them throughout this process has been an absolute pleasure. From a technical standpoint, they brought resources and domain expertise that made our Azure integration so much easier. Special thanks are owed to Martin Schray, Tereza Nemessanyi, and Kwadwo Nyarko who all went above and beyond to ensure this project was a success for us and treated us so well. We could not be more pleased and look forward to working with Microsoft again in the future." —JP La Torre, Co-Founder and CEO, Caylent
## Additional resources **Documentation** - [Azure Resource Manager overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview) - [Best practices for creating Azure Resource Manager templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-template-best-practices) - [Create your first Azure Resource Manager template](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-create-first-template) - [Azure Load Balancer overview](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-overview) - [Azure Load Balancer differences](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-overview#load-balancer-differences) - [Understanding outbound connections in Azure](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections) - [Continuous Deployment to Azure App Service](https://azure.microsoft.com/en-us/documentation/articles/app-service-continous-deployment/) - [Setting Continuous Deployment](https://github.com/projectkudu/kudu/wiki/Continuous-deployment) - [Azure Functions triggers and bindings concepts](https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings) - [Create your first Azure function in the Azure portal](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function) - [What is Log Analytics?](https://azure.microsoft.com/en-us/services/log-analytics/) - [Get started with a Log Analytics workspace](https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-get-started) - [AzureLogAnalyticsHelper](https://github.com/mschray/AzureLogAnalyticsHelper) **Books and blogs** - [Azure Functions JavaScript developer guide](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node) - [Azure Functions developers guide](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference) - [Phoenix Project DevOps Book](http://itrevolution.com/books/phoenix-project-devops-book/) - [Phoenix Project DevOps Blog - The Three Ways: The Principles Underpinning DevOps](http://itrevolution.com/the-three-ways-principles-underpinning-devops/) **Videos** - [Channel 9 DevOps Fundamentals Video Series - DevOps Fundamentals Home](https://channel9.msdn.com/Series/DevOps-Fundamentals/) - [Channel 9 DevOps Fundamentals Video Series - Continuous Integration](https://channel9.msdn.com/Series/DevOps-Fundamentals/Continuous-Integration/) - [Channel 9 DevOps Fundamentals Video Series - Continuous Deployment and Release Management](https://channel9.msdn.com/Series/DevOps-Fundamentals/Continuous-Deployment-and-Release-Management) - [Serverless applications with Azure Functions and Logic Apps - Part 1 (video)](https://azure.microsoft.com/en-us/resources/videos/build-and-deploy-serverless-part-1/)