<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aammir Mirza</title>
    <description>The latest articles on DEV Community by Aammir Mirza (@aammir_mirza).</description>
    <link>https://dev.to/aammir_mirza</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F896824%2Ff254d09f-99c3-4d9a-9a94-e3cb0d09110c.png</url>
      <title>DEV Community: Aammir Mirza</title>
      <link>https://dev.to/aammir_mirza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aammir_mirza"/>
    <language>en</language>
    <item>
      <title>Azure DevOps Cost Savings</title>
      <dc:creator>Aammir Mirza</dc:creator>
      <pubDate>Thu, 28 Jul 2022 09:55:01 +0000</pubDate>
      <link>https://dev.to/aammir_mirza/azure-devops-cost-savings-1jji</link>
      <guid>https://dev.to/aammir_mirza/azure-devops-cost-savings-1jji</guid>
      <description>&lt;p&gt;Lots of organization with DevOps practices using ADO (Azure DevOps) are likely dealing with the new reality of a contracting and uncertain economy. Ah !!! It is too much on my plate. So busy to focus on areas where I can squeeze few $$ from Azure services. Now is a good time to deliver value by turning your attention toward identifying some cost-saving measures for the various systems you are using.&lt;/p&gt;

&lt;p&gt;What if we have a automation in place that keep track of users licenses within the organization that are not active from 1,2,3…n months and downgrade them back to ‘Stakeholder’.&lt;br&gt;
An extension to ‘Audit Your License Usage’ and downgrade them if they are not active from past few months or so.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=AammirMirza.CP-ADOLicenseManagementpublic"&gt;Extension Azure DevOps License Management Tasks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first step to evaluate your cloud spend is to audit your license usage within Azure DevOps. Azure DevOps has three or four different tiers of license usage.&lt;/p&gt;

&lt;p&gt;Stakeholder — Free&lt;br&gt;
Basic — First five users free, then $6 per user&lt;br&gt;
Basic + Test Plans — $52 per user&lt;br&gt;
Visual Studio Subscriber — $45 — $250 a month&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ref.: &lt;a href="https://azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/"&gt;https://azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It make no sense to discuss who should have what type of license in this blog because that is more dependent on how your team works.&lt;br&gt;
For example:&lt;/p&gt;

&lt;p&gt;Some employees may have Visual Studio subscriptions.&lt;br&gt;
Some may have basic licenses.&lt;br&gt;
Anyone else in your org that needs visibility have a stakeholder license (these licenses are free).&lt;br&gt;
Any team members outside of Visual Studio subscribers who need to review or access test plans on a regular basis might have the Test Plan add-on license. This would typically include product owners and possibly support engineers who are subject matter experts.&lt;br&gt;
I would recommend taking a close look at the number of Visual Studio subscribers you have and making sure that everyone is actively using their license.&lt;/p&gt;

&lt;p&gt;Extension is taking care of pulling this information across all organization.&lt;br&gt;
As we can see in the pipeline if fetches users and there entitlements for individual organization. As shown in the below screen shot.&lt;br&gt;
As, it runs the organization, organization mv-e….. (#1)&lt;br&gt;
Extension finds 2 users those who not logged-in since 2-months (#2)&lt;br&gt;
And then downgrade the license type from Basic or Basic+Test to Stakeholder (#3 and #4)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sILUsHX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynm54o17rlux3h18xo7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sILUsHX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynm54o17rlux3h18xo7g.png" alt="Image description" width="880" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the same way,we can have explicit email address to skip the license auditing and they will be excluded from the action of downgrade.&lt;br&gt;
As you can see in below image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P59-CNMZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gw27bxyz277oau70pic5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P59-CNMZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gw27bxyz277oau70pic5.png" alt="Image description" width="880" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally it generates the log (csv) which can be artifact of the pipeline for reference. As you see in the below image the list of action performed&lt;br&gt;
1 : gives the error for downgrade because either the user in owner of organization or the user is added thru ‘Group rule’&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--btjXnucq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wl3y2tz035mg3sbx79q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--btjXnucq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wl3y2tz035mg3sbx79q.png" alt="Image description" width="880" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Evidence of cost savings for 30+ organization (without multi-org feature enabled) and 1000+ users&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l7OkcV9r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3cs4li604jiecmk5qoek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l7OkcV9r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3cs4li604jiecmk5qoek.png" alt="Image description" width="880" height="219"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;November-2021 cost (without license management automation)&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Cost for user licenses : 3867 EURO&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---N0dJBXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8mybrdupspi92wg331dx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---N0dJBXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8mybrdupspi92wg331dx.png" alt="Image description" width="880" height="233"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;December-2021 cost (with license management automation)&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Cost for user licenses : 2364 EURO with savings of 1500+ Euro&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Extension is available at &lt;a href="https://marketplace.visualstudio.com/items?itemName=AammirMirza.CP-ADOLicenseManagementpublic"&gt;link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>optimization</category>
      <category>azuredevops</category>
    </item>
    <item>
      <title>Azure Compute Cost savings</title>
      <dc:creator>Aammir Mirza</dc:creator>
      <pubDate>Thu, 28 Jul 2022 09:36:51 +0000</pubDate>
      <link>https://dev.to/aammir_mirza/azure-compute-cost-savings-4c32</link>
      <guid>https://dev.to/aammir_mirza/azure-compute-cost-savings-4c32</guid>
      <description>&lt;h2&gt;
  
  
  Start/Stop VMs and Scale-sets during off-hours or Non-working hours.
&lt;/h2&gt;

&lt;p&gt;The Start/Stop VMs or VM Scalesets during off-hours (for development, test, lab env) feature start or stops enabled Azure VMs and VM Scaliest (VMSS).&lt;/p&gt;

&lt;p&gt;It is nothing new or something similar to a out of the box idea.&lt;/p&gt;

&lt;p&gt;We all are already practising it with Runbook (Automation account), Azure provided feature within VM scope or via pipelines.&lt;/p&gt;

&lt;p&gt;But I have experience only complexity to make it more flexible as parameterized that can be changed anytime and whenever required.&lt;/p&gt;

&lt;p&gt;For example if my RG consist of 14 VMs but I just want to enable STOP schedule for 12 VMs, how I can exclude the rest of 2 from the schedule ?&lt;/p&gt;

&lt;p&gt;Every time change in schedule requires to go and change the parameters or schedules for the automation in Runbooks or Azure internal feature.&lt;/p&gt;

&lt;p&gt;How to set the same schedule for 50+ VMs across 7 subscription and 15 different RGs, with a single pipeline and automation schedule.&lt;/p&gt;

&lt;p&gt;Etc etc…&lt;/p&gt;

&lt;p&gt;What if we have a single extension for Azure DevOps or GitHub that take care of all such small cosmetics changes to keep the Start/Stop schedule more flexible.&lt;/p&gt;

&lt;p&gt;Extension link for Azure VM(s) Start/Stop schedule Link&lt;/p&gt;

&lt;p&gt;Extension link for Azure VMSS (Scale set) Start/Stop Link&lt;/p&gt;

&lt;p&gt;Introducing Azure VM Start/Stop extension&lt;/p&gt;

&lt;p&gt;It starts or stops machines on user-defined schedules. The feature can be enabled on Azure Resource Manager VMs for most scenarios.&lt;/p&gt;

&lt;h4&gt;
  
  
  Microsoft best practice (recommendation) for cost saving
&lt;/h4&gt;

&lt;p&gt;Optimize virtual machine spend by resizing or shutting down under-utilized instances Although certain application scenarios can result in low utilization by design, you can often save money by scheduling shutdown of your virtual machines.&lt;/p&gt;

&lt;p&gt;The recommended actions are shut down or resize, specific to the resource being evaluated.&lt;/p&gt;

&lt;p&gt;The advanced evaluation model in Advisor considers shutting down virtual machines when all of these statements are true:&lt;/p&gt;

&lt;p&gt;The current load doesn’t go above 80% utilization for workloads that aren’t user facing. The load doesn’t go above 40% for user-facing workloads. Here, Advisor determines the type of workload by analyzing the CPU utilization characteristics of the workload.&lt;/p&gt;

&lt;p&gt;Also, extension supports Startup of the VMs which can be schedules as the same way like Shut down&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Automate schedule with Azure DevOps pipeline using AzureVMStart/Stop task. It can reduce the overhead of maintaining / modifying individual Virtual Machine schedules every now and then from Portal or AzCLI. By scheduling the AzDO pipeline with this extension we can Shutdown / Startup computes based on requirement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Extension also provides flexibility to manage VMs based on below possible condition:
&lt;/h4&gt;

&lt;p&gt;Run for all VMs within the listed ResourceGroup(s), using the resource group field, with exclude list of VMs option (if required) for exclusion of VMs in the RG.&lt;br&gt;
Run for all VMs listed in VM List (applicable for single RG only)&lt;br&gt;
If no arguments (neither ResourceGroup nor VM List) is provided, it will run for all the RGs and VMs within the scope of Service Connection with exclude list of VMs option (if required)&lt;/p&gt;
&lt;h4&gt;
  
  
  Sample evaluation of cost saving within a week
&lt;/h4&gt;

&lt;p&gt;How much could you save shutting down Non-Production VMs ?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ZKl3mbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ajm5o5pm9u7jtm3ts9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ZKl3mbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ajm5o5pm9u7jtm3ts9y.png" alt="Image description" width="880" height="301"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Pipeline and execution example
&lt;/h3&gt;

&lt;p&gt;Running a Start schedule for the Azure VMs within multiple RGs, including exclusion on some VMs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schedules:
- cron: "0 18, * * *" #Run pipeline to STOP the VMs at 06PM
  displayName: Daily turnoff schedule
  branches:
include:
- main
always: true
name: $(Build.BuildId)_STOP_VMs  # build numbering format
parameters:
- name: Action
  displayName: Action
  type: string
  default: Stop
values:
- Start
- Stop
- Restart
trigger:
- main
pool:
vmImage: windows-latest
steps:
- task: AzureVMStartStop@1
  inputs:
   ResourceGroupName: $(ResourceGroupName)
   Action: 'Stop'
   ConnectedServiceName: 'sc-cbsed-lab'
   Simulate: false
   vmsExcludedFromAction: '$(vmsExcludedFromAction)'
  displayName: 'VM - Stop Schedule'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variables for pipeline&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tAZXT0Ec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hng9jnobw7zxlunbq93b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tAZXT0Ec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hng9jnobw7zxlunbq93b.png" alt="Image description" width="880" height="449"&gt;&lt;/a&gt;&lt;br&gt;
ResourceGroupName: list of RGs, for which cost saving accross VMs is running. In my case all the 3 RGs are from lower environment and I don't want them running after evening 1800, so I created a single pipeline for all of them.&lt;/p&gt;

&lt;p&gt;vmsExcludedFromAction: list of VMs for which you don't want to take any action. Which means that they will be continue running.&lt;/p&gt;

&lt;h3&gt;
  
  
  GIF for reference
&lt;/h3&gt;

&lt;h4&gt;
  
  
  STOP VMs schedule
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qvJMSIlo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj9cddocb5fctbg6rivz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qvJMSIlo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj9cddocb5fctbg6rivz.gif" alt="Image description" width="879" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  STAR VMs schedule
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ybKv3PG6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wy77jj2ww57u3l3z0jn4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ybKv3PG6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wy77jj2ww57u3l3z0jn4.gif" alt="Image description" width="879" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>azureapril</category>
      <category>cost</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
