<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Code is a highway]]></title><description><![CDATA[Some thoughts & code samples from my everyday ups and downs playing with code...]]></description><link>https://codeisahighway.com/</link><image><url>https://codeisahighway.com/favicon.png</url><title>Code is a highway</title><link>https://codeisahighway.com/</link></image><generator>Ghost 5.82</generator><lastBuildDate>Sat, 04 Apr 2026 09:30:18 GMT</lastBuildDate><atom:link href="https://codeisahighway.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Automating the extraction of Azure Regions resiliency information]]></title><description><![CDATA[<p>Azure paired regions and zone compatible regions are fundamental for ensuring redundancy and high availability of your applications in the cloud. Understanding the geography, physical regions, and their pairings can help you make informed decisions when architecting solutions on Azure. In this guide, we&apos;ll walk through how you</p>]]></description><link>https://codeisahighway.com/automating-the-extraction-of-azure-regions-resiliency-information/</link><guid isPermaLink="false">679bc55b34fd1400018d9901</guid><category><![CDATA[Azure CLI]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Governance]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Thu, 30 Jan 2025 18:35:11 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1496096265110-f83ad7f96608?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDMxfHxkYXRhJTIwZXh0cmFjdGlvbnxlbnwwfHx8fDE3MzgyNjIwMDl8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1496096265110-f83ad7f96608?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDMxfHxkYXRhJTIwZXh0cmFjdGlvbnxlbnwwfHx8fDE3MzgyNjIwMDl8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Automating the extraction of Azure Regions resiliency information"><p>Azure paired regions and zone compatible regions are fundamental for ensuring redundancy and high availability of your applications in the cloud. Understanding the geography, physical regions, and their pairings can help you make informed decisions when architecting solutions on Azure. In this guide, we&apos;ll walk through how you can automate the extraction of Azure regions information using PowerShell and Azure CLI and format them as you like.</p><h2 id="prerequisites">Prerequisites</h2><ul><li>Azure CLI installed on your machine. You can download it from&#xA0;<a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com" rel="noopener">here</a>.</li><li>PowerShell installed on your machine. You can download it from&#xA0;<a href="https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com" rel="noopener">here</a>.</li><li>You need to be logged in to your Azure account using&#xA0;<code>az login</code>.</li></ul><h2 id="powershell-script-to-extract-azure-paired-regions">PowerShell Script to Extract Azure Paired Regions</h2><p>Below is a PowerShell script that uses Azure CLI to list all the regions, filters them to get physical regions, and formats the output to display the geography group, geography, region name, and paired region.</p><pre><code class="language-powershell"># Retrieve all Azure regions
$results = az account list-locations | ConvertFrom-Json

# Filter only physical regions
$physicalResults = $results | Where-Object { $_.metadata.regionType -eq &apos;Physical&apos; }

# Select and format the desired properties
$formattedResults = $physicalResults | Select-Object `
    @{name=&quot;GeographyGroup&quot;; Expression = {$_.metadata.geographyGroup}}, `
    @{name=&quot;Geography&quot;; Expression = {$_.metadata.geography}}, `
    @{name=&quot;Region&quot;; Expression = {$_.name}}, `
    @{name=&quot;PairedRegion&quot;; Expression = {$_.metadata.pairedRegion[0].name}}

# Convert to JSON format with depth for nested objects
$jsonOutput = $formattedResults | ConvertTo-Json -Depth 5

# Output the JSON result
$jsonOutput</code></pre><h2 id="explanation">Explanation</h2><ul><li><strong>Retrieve Regions</strong>: The command&#xA0;<code>az account list-locations</code>&#xA0;retrieves all the Azure regions available for your subscription. We use&#xA0;<code>ConvertFrom-Json</code>&#xA0;to convert the output into a PowerShell object for easier manipulation.</li><li><strong>Filter Physical Regions</strong>: We filter the regions to include only those with a&#xA0;<code>regionType</code>&#xA0;of &apos;Physical&apos;.</li><li><strong>Select and Format Properties</strong>: We use&#xA0;<code>Select-Object</code>&#xA0;to extract specific properties and rename them for clarity. This includes the geography group, geography, region name, and the name of the paired region.</li><li><strong>Convert to JSON</strong>: Finally, we convert the filtered and formatted data back into JSON format using&#xA0;<code>ConvertTo-Json</code>, allowing for easy consumption in other tools or systems.</li></ul><p>Using that kind of information, we can automate and ease all type of decisions. Here is an example where we could use that strategy to produce Azure Resource Graph statements and augment queries with resiliency information.</p><pre><code class="language-powershell">$results = az account list-locations | ConvertFrom-Json

$physicalResults = $results | Where-Object { $_.metadata.regionType -eq &apos;Physical&apos; }

$results = $physicalResults `
    | Select-Object @{ name = &quot;GeographyGroup&quot;; Expression = { $_.metadata.geographyGroup } }, `
        @{ name = &quot;Geography&quot;; Expression = { $_.metadata.geography } }, `
        @{ name = &quot;region&quot;; Expression = { $_.name } }, `
        @{ name = &quot;paired_region&quot;; Expression = { $_.metadata.pairedRegion[0].name } }, `
        @{ name = &quot;zones&quot;; Expression = { $_.availabilityZoneMappings } } `
    | Where-Object GeographyGroup -in (&apos;US&apos;, &apos;Canada&apos;)


# extract regions that have a paired region
$PairedRegions = $results `
    | Where-Object paired_region -ne $null `
    | Sort-Object Region `
    | Select-Object -ExpandProperty region

$joinedStringValues = &quot;&apos;$($PairedRegions -join &quot;&apos;,&apos;&quot;)&apos;&quot;
# Produce a ARG statement for identifying resources in paired regions
&quot;| extend drp_in_paired_region = case(location in ($joinedStringValues), true, false)&quot;


# extract regions that have a zones support
$RegionsWithZones = $results `
    | Where-Object zones -ne $null `
    | Sort-Object Region `
    | Select-Object -ExpandProperty region    

$joinedStringValues = &quot;&apos;$($RegionsWithZones -join &quot;&apos;,&apos;&quot;)&apos;&quot;
# Produce a ARG statement for identifying resources in regions with zones support
&quot;| extend drp_region_support_az = case(location in ($joinedStringValues), true, false)&quot;    </code></pre><p>This script will produce the following outputs:</p><pre><code class="language-powershell">| extend drp_in_paired_region = case(location in (&apos;canadacentral&apos;,&apos;canadaeast&apos;,&apos;centralus&apos;,&apos;centraluseuap&apos;,&apos;eastus&apos;,&apos;eastus2&apos;,&apos;eastus2euap&apos;,&apos;eastusstg&apos;,&apos;northcentralus&apos;,&apos;southcentralus&apos;,&apos;southcentralusstg&apos;,&apos;westcentralus&apos;,&apos;westus&apos;,&apos;westus2&apos;,&apos;westus3&apos;), true, false)

| extend drp_region_support_az = case(location in (&apos;canadacentral&apos;,&apos;centralus&apos;,&apos;eastus&apos;,&apos;eastus2&apos;,&apos;eastus2euap&apos;,&apos;southcentralus&apos;,&apos;westus2&apos;,&apos;westus3&apos;), true, false)</code></pre><h2 id="conclusion">Conclusion</h2><p>This provides an automated way to extract and use Azure&apos;s regional resiliency information, which can be crucial for planning and deploying resilient and high-available applications. By leveraging Azure CLI and PowerShell, you can easily integrate this process into your existing automation workflows.</p><h2 id="references">References</h2><ul><li><a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com" rel="noopener">Azure CLI - Install and Setup</a></li><li><a href="https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com" rel="noopener">PowerShell - Install and Setup</a></li><li><a href="https://learn.microsoft.com/en-us/azure/best-practices-availability-paired-regions?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com" rel="noopener">Azure Paired Regions Documentation</a></li></ul><p>Feel free to modify the script to suit your specific needs, such as outputting the results to a file or integrating with other systems like Azure Resource Graph (ARG) for further processing. Happy automating!</p>]]></content:encoded></item><item><title><![CDATA[TIFU by Forgetting to Turn Off Microsoft Defender for Storage During a Massive Data Migration]]></title><description><![CDATA[<p>Not long ago, I experienced a classic &quot;Today I Fucked Up&quot; moment while working on a data migration at work. We needed to sync data between Azure storage accounts to set up infrastructure in a new region. Source accounts were cluttered with good and stale data, in the</p>]]></description><link>https://codeisahighway.com/tifu-by-forgetting-to-turn-off-microsoft-defender-for-storage-during-a-massive-data-migration/</link><guid isPermaLink="false">65ba4996b03218000146f437</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Storage]]></category><category><![CDATA[Microsoft Defender]]></category><category><![CDATA[Sharing]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Sun, 04 Feb 2024 14:39:03 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1501526029524-a8ea952b15be?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEwfHxkYXRhfGVufDB8fHx8MTcwNzA1NzMzNXww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1501526029524-a8ea952b15be?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEwfHxkYXRhfGVufDB8fHx8MTcwNzA1NzMzNXww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="TIFU by Forgetting to Turn Off Microsoft Defender for Storage During a Massive Data Migration"><p>Not long ago, I experienced a classic &quot;Today I Fucked Up&quot; moment while working on a data migration at work. We needed to sync data between Azure storage accounts to set up infrastructure in a new region. Source accounts were cluttered with good and stale data, in the case of the latest, accumulated over the years without a proper cleaning routine. The task was daunting: over 1 billion blobs awaited migration.</p><p>Given the scale, traditional migration options like AzCopy were sidelined due to the anticipated manual effort for syncing and monitoring. Instead, I proposed leveraging Azure&apos;s &quot;Object Replication&quot; feature for storage accounts, which promised to replicate containers in the background with minimal manual intervention.</p><h3 id="cost-estimation-misstep">Cost Estimation Misstep</h3><p>Before kicking off the process, and without enough caffeine in my body, I used the Azure cost calculator to estimate the migration cost. However, I mistakenly input 10,000 instead of the correct 100,000 multiplier for write transactions, leading to a gross underestimation. The initial cost seemed reasonable at $1,300 for writes operations, but in reality, I was off by a factor of 10. Nevertheless, the data had to be migrated or purged, nothing much we could do about that cost.</p><h3 id="the-migration-process">The Migration Process</h3><p>The migration began smoothly. By Friday morning, a significant portion of the data was synced, and the cost metrics seemed to align with my (flawed) calculations. By Monday, the metrics indicated that the replication was complete, and I proudly shared the news with my colleagues, pleased with the minimal effort required.</p><h3 id="the-bitter-victory">The Bitter Victory</h3><p>However, the sense of accomplishment was short-lived. Upon checking Azure Cost Management, my heart did a few hiccups as I met with a staggering figure: over $40,000 spent over two days. This was my oversight&#x2014;I had forgotten to account for Microsoft Defender for Storage, which also bills by the transaction volume you perform and can become exorbitantly expensive.</p><h3 id="damage-control">Damage Control</h3><p>After the initial shock subsided, I promptly informed the SRE, Technology, and Finance teams of the error. I then reached out to Azure support, explaining the oversight and asking if any credit for the unintended costs could be given. Thankfully, Azure&apos;s finance department was kind enough to grant a one-time credit for the costs of Defender.</p><h3 id="learnings-and-takeaways">Learnings and Takeaways</h3><p>This incident served as a potent reminder that anyone can make mistakes, regardless of seniority. It&apos;s vital to maintain data hygiene, prioritize data lifecycle management, and be aware of additional cost factors like Microsoft Defender for Storage.</p><p>There is a way to disable Microsoft Defender for Storage (Classic) from scanning storage accounts using a special tag. Before undertaking substantial data transactions, temporarily disabling Defender on target storage accounts, for the time of the migration could help prevent such a costly error.</p><h3 id="migration-stats">Migration Stats</h3><p>The migration resulted in over 10 billion storage transactions and 15.5TB of data movement&#x2014;a testament to the scale of the operation and the importance of meticulous planning and oversight.</p><h2 id="conclusion">Conclusion</h2><p>I chose to share this story to highlight that mistakes are part of the learning process. Owning up to them, sharing the experience, and implementing improvements are crucial steps. As a result, my team is now committed to developing better data management &amp; lifecycle practices to ensure such an oversight does not happen again.</p><p>Remember, always double-check your calculations, consider all cost factors, and maintain clear communication with all relevant parties during significant operations like data migrations.</p><p>Happy coding, and may your migrations always be cost-effective and incident-free!</p><h2 id="references">References</h2><ul><li><a href="https://learn.microsoft.com/en-us/azure/storage/blobs/object-replication-overview?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com">Object replication overview - Azure Storage | Microsoft Learn</a></li><li><a href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-storage-introduction?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com" rel="noreferrer">Microsoft Defender for Storage</a></li><li><a href="https://learn.microsoft.com/en-us/azure/storage/blobs/object-replication-configure?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com">Configure object replication - Azure Storage | Microsoft Learn</a></li><li><a href="https://techcommunity.microsoft.com/t5/azure-paas-blog/monitor-object-replication-status-for-storage-account/ba-p/3766540?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com">Monitor Object Replication Azure Blob Storage</a></li></ul>]]></content:encoded></item><item><title><![CDATA[How to delete an Azure storage account with an unlocked Immutability policy]]></title><description><![CDATA[<p>Recently, I encountered a situation with Azure Storage. We were playing with immutability policy in a storage account in a test environment. We&apos;ve set a policy for tests, we did what we wanted to do, when the time came to delete the environment, I hit a roadblock.</p>
<h2 id="locked-by-an-immutability-policy">Locked</h2>]]></description><link>https://codeisahighway.com/how-to-delete-an-azure-storage-account-with-an-unlocked-immutability-policy/</link><guid isPermaLink="false">65732fcf89488700014bb8ba</guid><category><![CDATA[Storage]]></category><category><![CDATA[Azure CLI]]></category><category><![CDATA[data protection]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Microsoft Azure]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Fri, 08 Dec 2023 15:37:40 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1614750443485-9c2f8fd9dac9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIxfHxsb2NrfGVufDB8fHx8MTcwMjA0OTgxN3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1614750443485-9c2f8fd9dac9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIxfHxsb2NrfGVufDB8fHx8MTcwMjA0OTgxN3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="How to delete an Azure storage account with an unlocked Immutability policy"><p>Recently, I encountered a situation with Azure Storage. We were playing with immutability policy in a storage account in a test environment. We&apos;ve set a policy for tests, we did what we wanted to do, when the time came to delete the environment, I hit a roadblock.</p>
<h2 id="locked-by-an-immutability-policy">Locked by an immutability policy</h2>
<p>The immutability policy on the storage account was preventing deletion. And thinking it back, it is what it is supposed to do.</p>
<p>Azure&apos;s immutability policies are a powerful feature for compliance scenarios, where preventing data from being altered or deleted is crucial. These policies, when locked, enforce retention periods and legal holds which can&apos;t be bypassed easily.</p>
<h2 id="understanding-immutability-policies">Understanding immutability policies</h2>
<p>Immutability policies in Azure Blob storage allow users to store business-critical data objects in a WORM (Write Once, Read Many) state. This means that once written, the data cannot be modified or deleted for a specified retention period. These policies are crucial for scenarios where data needs to be preserved in an unaltered state for compliance with industry regulations or company policies.</p>
<h2 id="the-mitigation-removing-immutability-policies">The Mitigation: Removing immutability policies</h2>
<p>! This works only if your policy is in an <code>Unlocked</code> state. If <code>Locked</code>, you&apos;ll need to wait until the period you set expires. There is nothing to do in a <code>Locked</code> state other than wait.</p>
<p>Luckily for us, we expected that for tests and left the policy <code>Unlocked</code>. But still, I couldn&apos;t just delete the storage account, nor the container in a one-shot operation.</p>
<p>The solution involved programmatically removing the immutability policy from each blob within the storage account&apos;s container. By leveraging Azure CLI, specifically the <code>az storage blob immutability-policy delete</code> command, I was able to loop over all the blobs and remove their respective immutability policies.</p>
<p>Here is an example of the Azure CLI command I used to remove the immutability policy from a blob:</p>
<pre><code class="language-bash">az storage blob immutability-policy delete --account-name &lt;StorageAccountName&gt; --container-name &lt;ContainerName&gt; --name &lt;BlobName&gt;
</code></pre>
<p>This command requires the storage account name, container name, and blob name to identify the blob for which the policy should be removed.</p>
<h2 id="scripting-time">Scripting time</h2>
<p>To expedite the process, I wrote a script that iterated through all blobs under the target container and executed the command to remove the immutability policy for each one. Once the policies were cleared, I was able to delete the container, then the storage account without any further issues.</p>
<p>Here&apos;s a simplified example of how such a script might look:</p>
<pre><code class="language-powershell"># Set variables
$accountName=&quot;&lt;myStorageAccount&gt;&quot;
$containerName=&quot;&lt;ContainerName&gt;&quot;

# List all blobs in the container
$blobList = az storage blob list --container-name $containerName --account-name $accountName --query &quot;[].name&quot; --output tsv

# Loop through each blob and remove the access policy
foreach ($blob in $blobList) {
    az storage blob immutability-policy delete --container-name $containerName --name $blob --account-name $accountName
}
</code></pre>
<p>Remember to replace <code>&lt;myStorageAccount&gt;</code>, <code>&lt;ContainerName&gt;</code> with your actual resource names.</p>
<h2 id="conclusion">Conclusion</h2>
<p>It is important to understand Azure&apos;s data protection features such as immutability policies, and how they can impact resource management. While these features are excellent for ensuring data integrity and compliance in production, they require additional steps if you play with it in an ephemeral fashion or test environment.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-immutability-policies-manage?wt.mc_id=AZ-MVP-5001613&amp;ref=codeisahighway.com">Overview of immutable storage for Azure Blob storage</a></li>
<li><a href="https://docs.microsoft.com/en-us/cli/azure/storage/blob/immutability-policy?view=azure-cli-latest%3Fwt.mc_id%3DAZ-MVP-5001613&amp;ref=codeisahighway.com">Azure CLI - Storage Blob Immutability-Policy</a></li>
</ul>
<p>Happy cloud computing!</p>
]]></content:encoded></item><item><title><![CDATA[Suggestion: Read GSoft journey tech blog]]></title><description><![CDATA[<p>The articles you find here are more around technical guidance, how-to&apos;s and errors I encountered throughout the year. It&apos;s only been recent for me to write up about decisions &amp; what happens at work. </p><h2 id="gsoft-s-tech-blog">GSoft&apos;s tech blog</h2><p>Some of my colleagues and I have</p>]]></description><link>https://codeisahighway.com/suggestion-read-gsoft-journey-tech-blog/</link><guid isPermaLink="false">64ad86e191f3ba000186595b</guid><category><![CDATA[content suggestion]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Tue, 28 Feb 2023 19:52:50 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1598024055266-e772a5f8c128?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHJlYWRpbmd8ZW58MHx8fHwxNjc3NjE0NzM3&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1598024055266-e772a5f8c128?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHJlYWRpbmd8ZW58MHx8fHwxNjc3NjE0NzM3&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Suggestion: Read GSoft journey tech blog"><p>The articles you find here are more around technical guidance, how-to&apos;s and errors I encountered throughout the year. It&apos;s only been recent for me to write up about decisions &amp; what happens at work. </p><h2 id="gsoft-s-tech-blog">GSoft&apos;s tech blog</h2><p>Some of my colleagues and I have been writing articles to discuss our journey at GSoft. Sometimes it&apos;s from a technical writer standpoint, sometimes from a software architect standpoint, it varies. Quite diverse in the content that lands there.</p><p>Lately, we&apos;ve been opening up more on what we do because we wanted to share with others our experiences and our journey. It materializes in the form of blog articles and we write about what happens in our team, the technology team, and at GSoft in general.</p><p>We share decisions we made and why we ended up going there. It is the kind of content I personally enjoy, more about a process than a &quot;Here&apos;s the answer to your question&quot;. Sometimes it can trigger ideas or reflections about a particular technology. Sometimes just about how we ended up taking a decision itself, helping you in your reality and context.</p><p>I invite you to read us out :)</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://medium.com/gsoft-tech?ref=codeisahighway.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GSoft Tech &#x2013; Medium</div><div class="kg-bookmark-description">GSoft Tech Blog.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://cdn-images-1.medium.com/fit/c/304/304/1*8qQYy-6LuUvjqDpl3YdLiA.jpeg" alt="Suggestion: Read GSoft journey tech blog"><span class="kg-bookmark-author">Medium</span><span class="kg-bookmark-publisher">Eric De Carufel</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://cdn-images-1.medium.com/max/1200/1*8qQYy-6LuUvjqDpl3YdLiA.jpeg" alt="Suggestion: Read GSoft journey tech blog"></div></a></figure><p> Happy reading!</p>]]></content:encoded></item><item><title><![CDATA[How to dynamically set last month date range in KQL query and Log Analytics]]></title><description><![CDATA[<p>I wanted to improve an audit query we are running every month because I hate doing things manually over and over again. Before today, we were setting the date range for the previous month manually and I was searching a way to automate this instead. I found a way...</p><h2 id="manually-setting-query-date-range-in-log-analytics">Manually</h2>]]></description><link>https://codeisahighway.com/how-to-dynamically-set-last-month-date-range-in-kql-query-and-log-analytics/</link><guid isPermaLink="false">64ad86e191f3ba000186595a</guid><category><![CDATA[KQL]]></category><category><![CDATA[Log Analytics]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Tue, 01 Feb 2022 16:49:42 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1502570149819-b2260483d302?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDIyfHxjYWxlbmRhcnxlbnwwfHx8fDE2NDM3MzM3MjQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1502570149819-b2260483d302?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDIyfHxjYWxlbmRhcnxlbnwwfHx8fDE2NDM3MzM3MjQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="How to dynamically set last month date range in KQL query and Log Analytics"><p>I wanted to improve an audit query we are running every month because I hate doing things manually over and over again. Before today, we were setting the date range for the previous month manually and I was searching a way to automate this instead. I found a way...</p><h2 id="manually-setting-query-date-range-in-log-analytics">Manually setting query date range in Log Analytics</h2><p>There are a few ways that you can set a date range for your query in Log Analytics.</p><ol><li>Set the date range using the time range control in the UI</li></ol><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2022/02/image.png" class="kg-image" alt="How to dynamically set last month date range in KQL query and Log Analytics" loading="lazy" width="914" height="457" srcset="https://codeisahighway.com/content/images/size/w600/2022/02/image.png 600w, https://codeisahighway.com/content/images/2022/02/image.png 914w" sizes="(min-width: 720px) 720px"></figure><p>2. Set the date range manually in the query</p><pre><code class="language-KQL">AzureActivity
| where TimeGenerated between (datetime(&apos;2022-01-01&apos;) .. datetime(&apos;2022-01-31&apos;))</code></pre><p>But they all imply manual intervention to update the query (every month) in our case. There must be a better way I asked myself, and there is!</p><h2 id="automatically-determine-last-month-s-date-range">Automatically determine last month&apos;s date range</h2><p>I was searching for a way, in the query itself to set the date to last month relative to the date the query execute. Let&apos;s say I am February 1st and I execute the query, I want the date range to be 2022-01-01 .. 2022-01-31.</p><p>Searching the web sent me directly to <a href="https://stackoverflow.com/questions/69164108/how-to-write-a-kusto-query-to-get-previous-month-logs-in-sentinel?ref=codeisahighway.com">StackOverflow</a>. There was my solution!</p><pre><code class="language-KQL">// StackOverflow code I found at https://stackoverflow.com/questions/69164108/how-to-write-a-kusto-query-to-get-previous-month-logs-in-sentinel

// The Easy &apos;Manual&apos; Way
AuditLogs
| where TimeGenerated &gt;= datetime(&apos;2021-08-01&apos;) and TimeGenerated &lt;= datetime(&apos;2021-08-31&apos;)
// Automated Way
let lastmonth = getmonth(datetime(now)) -1;
let year = getyear(datetime(now)); 
let monthEnd = endofmonth(datetime(now),-1); 
AuditLogs
| where TimeGenerated &gt;= make_datetime(year,lastmonth,01) and TimeGenerated &lt;= monthEnd</code></pre><p>Not so fast... it is working, sometimes, but not exactly fit my needs. If you run this in January, we want it to shift the range to December of last year and a few small fixes like this. The solution in StackOverflow was a great starting point though.</p><h2 id="let-s-do-this-">Let&apos;s do this!</h2><p>First we determine <code>lastMonthNumber</code>, we determine the current month and subtract <code>1</code> from the number. </p><pre><code class="language-KQL">let lastmonthNumber = getmonth(datetime(now)) - 1;</code></pre><p>This will work for all of the months, except January. In January, <code>getmonth()</code> will return <code>1</code> and we cannot magically switch it to <code>12</code> by subtracting <code>1</code>. We need the help of the <code>iff()</code> function here. If <code>lastMonthNumber == 0</code>, it means we are <em>currently</em> in January, we need to change it to <code>12</code> ourselves to point to December instead.</p><pre><code class="language-KQL">let lastmonth = iff(lastmonthNumber == 0, 12, lastmonthNumber);</code></pre><p>For <code>year</code> we get the current year as of today and subtract <code>1</code> if lastMonth is <code>12</code>, otherwise we subtract nothing, sending it <code>0</code>.</p><pre><code class="language-KQL">let year = getyear(datetime(now)) - iff(lastmonth == 12, 1, 0);
</code></pre><p>From there we have all the information we need to set <code>dateStart</code> and <code>dateEnd</code>. </p><pre><code class="language-KQL">let dateStart = make_datetime(year, lastmonth, 01);
let dateEnd = endofmonth(dateStart);</code></pre><p>We just need to use them against <code>TimeGenerate</code> in our case as follows:</p><p><code>| where TimeGenerated between(dateStart .. dateEnd)</code></p><p>Here is what I ended up with.</p><pre><code class="language-KQL">// Automatic date calc to get full month
let lastmonthNumber = getmonth(datetime(now)) - 1;
let lastmonth = iff(lastmonthNumber == 0, 12, lastmonthNumber);
let year = getyear(datetime(now)) - iff(lastmonth == 12, 1, 0);
let dateStart = make_datetime(year, lastmonth, 01);
let dateEnd = endofmonth(dateStart);
AzureActivity
| where TimeGenerated between(dateStart .. dateEnd)</code></pre><p>Hope it helps! Happy KQL!</p>]]></content:encoded></item><item><title><![CDATA[Looking for activities triggered only by humans in Azure Activities in Kusto or Log Analytics]]></title><description><![CDATA[<p>We wanted to know which actions where done by a human and not a service principal when looking at Azure Activities in Log Analytics queries. We thought of a nice quick way to do it!</p><h2 id="email-vs-guid">Email vs GUID</h2><p>Our assumption is that all humans that trigger something in Azure will</p>]]></description><link>https://codeisahighway.com/looking-for-activities-triggered-only-by-humans-in-azure-activities-in-kusto-or-log-analytics/</link><guid isPermaLink="false">64ad86e191f3ba0001865959</guid><category><![CDATA[KQL]]></category><category><![CDATA[Log Analytics]]></category><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Governance]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Mon, 01 Nov 2021 14:35:49 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1490127252417-7c393f993ee4?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHNlYXJjaHxlbnwwfHx8fDE2MzU3NzcyMzc&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1490127252417-7c393f993ee4?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHNlYXJjaHxlbnwwfHx8fDE2MzU3NzcyMzc&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Looking for activities triggered only by humans in Azure Activities in Kusto or Log Analytics"><p>We wanted to know which actions where done by a human and not a service principal when looking at Azure Activities in Log Analytics queries. We thought of a nice quick way to do it!</p><h2 id="email-vs-guid">Email vs GUID</h2><p>Our assumption is that all humans that trigger something in Azure will have an email instead of a guid for service principals in the <code>Caller</code> field.</p><p>My first thought was to do something with regex validation to check if it&apos;s a guid format or not.</p><p>I started to look at the documentation for <code>matches regex</code> and said to myself that they&apos;re might be already something to convert a string to a guid scalar. There is something! it&apos;s called <code>toguid()</code>. In the documentation, <code>toguid()</code> will return a guid if the value is really in the proper format, otherwise <code>null</code>. Bingo!</p><p>We now just have to check if the value does not convert properly, remember, only service principals have a guid as value, otherwise it&apos;s an email.</p><p>We can combine functions together and write <code>| where isnull(toguid(Caller))</code> to perform this check.</p><p>The query will look something like this:</p><pre><code class="language-kusto">AzureActivity
| where Category has &quot;Administrative&quot;
| where OperationName has &quot;Firewall Rule&quot;
| where ActivityStatus has &quot;Succeeded&quot;
| where isnull(toguid(Caller))
| project OperationName, OperationNameValue, Caller, _ResourceId, TimeGenerated</code></pre><p>Hope it helps!</p><p>Happy Kusto log query!</p>]]></content:encoded></item><item><title><![CDATA[List all subscriptions under a management group with Azure Resource Graph]]></title><description><![CDATA[<p>It is not a secret anymore that I really like Azure Resource Graph. Today I wanted to list all the subscriptions under a management group and had to adjust because I was leveraging hidden tags before on subscriptions. This data is now gone in ARG, let see how I now</p>]]></description><link>https://codeisahighway.com/list-all-subscriptions-under-a-management-group-with-azure-resource-graph/</link><guid isPermaLink="false">64ad86e191f3ba0001865958</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Azure Resource Graph]]></category><category><![CDATA[Azure CLI]]></category><category><![CDATA[PowerShell]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Thu, 21 Oct 2021 12:45:42 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1533742173920-8f24563546c8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDQxfHxzZWFyY2h8ZW58MHx8fHwxNjM0ODIwMDU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1533742173920-8f24563546c8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDQxfHxzZWFyY2h8ZW58MHx8fHwxNjM0ODIwMDU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="List all subscriptions under a management group with Azure Resource Graph"><p>It is not a secret anymore that I really like Azure Resource Graph. Today I wanted to list all the subscriptions under a management group and had to adjust because I was leveraging hidden tags before on subscriptions. This data is now gone in ARG, let see how I now do it.</p><h2 id="meet-managementgroupancestorschain">Meet managementGroupAncestorsChain</h2><p>For the <code>subscriptions</code> and <code>managementgroups</code> under <code>resourcecontainers</code> you have access to a property called <code>managementGroupAncestorsChain</code>. This array will give you a list of the parent management groups in reversed order, from the immediate parent to the root.</p><p>This is exactly what I need to filter subscriptions for a certain parent management group. Since we cannot search into indexed properties directly, we need to expand it using <code>mv-expand</code>. Doing this will create a new row in the ARG results for each item in <code>managementGroupAncestorsChain</code>. From there we can filter on the <code>name</code> property which correspond to the management group id of that ancestor.</p><p>Here is the query I ended up with:</p><pre><code class="language-azureresourcegraph">resourcecontainers
| where type == &apos;microsoft.resources/subscriptions&apos;
| mv-expand managementGroupParent = properties.managementGroupAncestorsChain
| where managementGroupParent.name =~ &apos;moamg&apos;
| project name, id
| sort by name asc</code></pre><p>This is useful in the portal but like mentioned in the past, the advantage with ARG is that it is well integrated with Azure CLI &amp; Azure PowerShell.</p><p><strong>!</strong> make sure you replace <code>moag</code> in the segment <code>where managementGroupParent.name =~ &apos;moamg&apos;</code> to target the right management group id.</p><p>You can position yourself at any place in the management group hierarchy by providing the management group scope at the command line. In the example below, I target the root management group using <code>$tenantId</code>. The management group id for the root management is the id of your AAD tenant.</p><h2 id="azure-cli-az-powershell-examples">Azure CLI &amp; Az PowerShell examples</h2><pre><code class="language-powershell">$query = &quot;resourcecontainers | where type == &apos;microsoft.resources/subscriptions&apos; | mv-expand managementGroupParent = properties.managementGroupAncestorsChain | where managementGroupParent.name =~ &apos;moamg&apos; | project name, id | sort by name asc&quot;

# Azure CLI
$tenantId = az account show --query tenantId -o tsv
az graph query -q $query --management-groups $tenantId | ConvertFrom-Json

# Azure PowerShell
$tenantId = (Get-AzContext).Tenant.Id
Search-AzGraph -Query $query -ManagementGroup $tenantId</code></pre><p>Happy coding!</p>]]></content:encoded></item><item><title><![CDATA[Workaround for error 'utf-8' codec can't decode byte 0x82 using Azure CLI deployment and Bicep]]></title><description><![CDATA[<p>We migrated most of our automation from ARM Templates to Bicep in the recent months and things have been good so far. We ran into an issue deploying a bicep file containing French characters using Azure CLI. The message was: <code>&apos;utf-8&apos; codec can&apos;t decode byte 0x82</code></p>]]></description><link>https://codeisahighway.com/workaround-for-error-utf-8-codec-cant-decode-byte-0x82-using-azure-cli-deployment-and-bicep/</link><guid isPermaLink="false">64ad86e191f3ba0001865956</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Azure CLI]]></category><category><![CDATA[Bicep]]></category><category><![CDATA[Bug]]></category><category><![CDATA[HowTo]]></category><category><![CDATA[Infrastructure As Code]]></category><category><![CDATA[Azure Resource Manager]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Tue, 11 May 2021 10:34:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1620629228754-6ed8b519bd0f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8YWxsfDMzfHx8fHx8Mnx8MTYyMDcyOTEyMw&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1620629228754-6ed8b519bd0f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8YWxsfDMzfHx8fHx8Mnx8MTYyMDcyOTEyMw&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Workaround for error &apos;utf-8&apos; codec can&apos;t decode byte 0x82 using Azure CLI deployment and Bicep"><p>We migrated most of our automation from ARM Templates to Bicep in the recent months and things have been good so far. We ran into an issue deploying a bicep file containing French characters using Azure CLI. The message was: <code>&apos;utf-8&apos; codec can&apos;t decode byte 0x82 in position 1197: invalid start byte</code></p><h2 id="the-problem">The problem</h2><p>I usually write things in English when I code so this was a non-issue for us until... We wanted to write non-compliant messages in French in our Azure Policy. Here is an example that contains the French character <strong>&#xE9;</strong> and reproduce my error:</p><pre><code class="language-bicep">targetScope = &apos;managementGroup&apos;

var policyAssignmentName = substring(replace(guid(&apos;testassignment-#01&apos;), &apos;-&apos;, &apos;&apos;), 0, 23)

resource policyAssignment &apos;Microsoft.Authorization/policyAssignments@2020-09-01&apos; = {
  name: policyAssignmentName
  properties: {
    policyDefinitionId: &apos;/providers/Microsoft.Authorization/policyDefinitions/0473574d-2d43-4217-aefe-941fcdf7e684&apos;
    displayName: &apos;AzCLI and Bicep encoding bug&apos;
    description: &apos;AzCLI and Bicep encoding bug&apos;
    enforcementMode: &apos;Default&apos;
    parameters: {
      listOfAllowedLocations: {
        value: [
          &apos;canadaeast&apos;
          &apos;canadacentral&apos;
        ]
      }
    }
    nonComplianceMessages:[
      {
        message: &apos;La r&#xE9;gion qui a &#xE9;t&#xE9; choisi n\&apos;est pas valide...&apos;
      }
    ]
  }
}
</code></pre><p>As you can see, I get the error mentioned at the top when invoking the following command:</p><pre><code class="language-powershell">az deployment mg create --management-group-id experimental --location canadaeast -f .\azcli-bicep-bug.bicep

&apos;utf-8&apos; codec can&apos;t decode byte 0x82 in position 1179: invalid start byte</code></pre><p>The error is that the character <strong>&#xE9;</strong> is badly handled. UTF-8 is used instead of Unicode in the Bicep wrapper _bicep.py.</p><p>An issue has been filled on the GitHub repo of Azure CLI <a href="https://github.com/Azure/azure-cli/issues/18029?ref=codeisahighway.com">#18029</a></p><h2 id="the-workaround">The workaround</h2><p>So... this is not working as a one-time operation, calling <code>az deployment</code>. Bicep can convert to and from ARM Templates. What I ended up doing until this issue is fixed is:</p><p>Generate an ARM template from my bicep file and deploy that ARM template. Two steps instead of one.</p><pre><code class="language-powershell">az bicep build -f .\azcli-bicep-bug.bicep

az deployment mg create --management-group-id experimental --location canadaeast -f .\azcli-bicep-bug.json</code></pre><p>Hope it can help some of you!</p><h2 id="references">References</h2><ul><li><a href="https://github.com/Azure/azure-cli?ref=codeisahighway.com">Microsoft Azure CLI</a></li><li><a href="https://github.com/Azure/azure-cli/issues/18029?ref=codeisahighway.com">Azure deployment using Bicep and French characters: &apos;utf-8&apos; codec can&apos;t decode byte 0x82</a></li><li><a href="https://github.com/Azure/bicep?ref=codeisahighway.com">Bicep</a></li><li><a href="https://bicepdemo.z22.web.core.windows.net/?ref=codeisahighway.com">Bicep Playground</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Effective ways to delete resources in a resource group on Azure in 2021]]></title><description><![CDATA[<p>In Azure, resource groups are very helpful to logically hold together a set of resources. For many reasons, at some point, you&apos;ll want to get rid of these resources but how can you achieve this and what are the pros and cons of each?</p><p><strong>This is an actualized</strong></p>]]></description><link>https://codeisahighway.com/effective-ways-to-delete-resources-in-a-resource-group-on-azure-in-2021/</link><guid isPermaLink="false">64ad86e191f3ba0001865955</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Azure Resource Manager]]></category><category><![CDATA[PowerShell]]></category><category><![CDATA[ARM Template]]></category><category><![CDATA[Best Practices]]></category><category><![CDATA[HowTo]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Bicep]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Sat, 24 Apr 2021 13:03:54 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1529220502050-f15e570c634e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE1fHxjbGVhbmluZ3xlbnwwfHx8fDE2MTkyNjg3NDc&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1529220502050-f15e570c634e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE1fHxjbGVhbmluZ3xlbnwwfHx8fDE2MTkyNjg3NDc&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Effective ways to delete resources in a resource group on Azure in 2021"><p>In Azure, resource groups are very helpful to logically hold together a set of resources. For many reasons, at some point, you&apos;ll want to get rid of these resources but how can you achieve this and what are the pros and cons of each?</p><p><strong>This is an actualized version of my popular post:</strong><br><em><a href="https://codeisahighway.com/effective-ways-to-delete-resources-in-a-resource-group-on-azure">Effective ways to delete resources in a resource group on Azure</a></em></p><p>We&apos;ll cover Az PowerShell modules, Azure CLI, ARM template and Bicep. In my previous article I was speaking about three ways of doing this, in this article I&apos;ll stick with two, I dropped custom scripting. You have the link above, feel free to go check it if you&apos;re after a custom way to delete resources within a resource group. </p><p>You have basically two options depending on the end result you want. Both are effortless, it simply comes to: Do you want to delete it? Or only purge the resources inside?</p><h2 id="delete-the-resource-group">Delete the resource group</h2><p>It is the simplest, it deletes everything.</p><p><strong>Advantages</strong></p><ul><li>No custom logic is required</li></ul><p><strong>To consider</strong></p><ul><li>All resources inside the resource group will be deleted</li><li>The resource group will be deleted (losing RBAC &amp; Tags)</li></ul><pre><code class="language-powershell">Remove-AzResourceGroup -Name MyResourceGroup -Verbose
</code></pre><p>After a few minutes, your resources and their container will be deleted.</p><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2021/04/Remove-AzResourceGroup-1.png" class="kg-image" alt="Effective ways to delete resources in a resource group on Azure in 2021" loading="lazy" width="2000" height="843" srcset="https://codeisahighway.com/content/images/size/w600/2021/04/Remove-AzResourceGroup-1.png 600w, https://codeisahighway.com/content/images/size/w1000/2021/04/Remove-AzResourceGroup-1.png 1000w, https://codeisahighway.com/content/images/size/w1600/2021/04/Remove-AzResourceGroup-1.png 1600w, https://codeisahighway.com/content/images/2021/04/Remove-AzResourceGroup-1.png 2160w" sizes="(min-width: 720px) 720px"></figure><h2 id="wait-what-if-i-don-t-want-to-delete-the-resource-group">Wait... What if I don&apos;t want to delete the resource group?</h2><p>Deleting the resource group directly is the quickest way to remove all the resources inside it but you&apos;ll also delete the container itself. What are your options if you want to preserve the resource group ?</p><h2 id="purge-the-resource-group">Purge the resource group</h2><p>If you are looking for a way to keep the resource group but want all the resources inside it deleted, this last option is for you.</p><p><strong>Advantages</strong></p><ul><li>No custom logic or dependency walking is required</li><li>Keep the resource group intact (including RBAC &amp; Tags)</li><li>Native parallel delete support of non-dependent resources</li></ul><p><strong>To consider</strong></p><ul><li>All resources inside the resource group will be deleted</li></ul><p>In Azure, you have the option of deploying resources using a template. You have two modes available when initiating a deployment:</p><p><strong>Incremental</strong>: You can see this mode as &quot;Additive&quot;. What I mean is that non-existing resources declared in your template will be added. Existing resources will be modified only if there is a difference between the actual version and what is declared in your template. Finally, if there&apos;s a resource in the resource group that is not present in the template, it will be ignored and left untouched.</p><p><strong>Complete</strong>: You can see this mode as &quot;Exact match&quot;. What I mean is that after your deployment is done, only the resources declared in your template will exist in the resource group. If there are existing resources in the resource group that are not present in the template, they will be deleted automatically.</p><p>Now that we understand what happens in &quot;Complete&quot; mode, we can use that to our advantage. We are looking for a way to purge all the resources in a resource group, without having to handle the complexity of resolving dependencies and parallel delete of resources. The trick, simple when you think about it, just ask the ARM engine to deploy an empty template (no resources) in an existing resource group in &quot;Complete&quot; mode. You&apos;ll end up exactly with the behavior we want.</p><p>We can do this with an ARM template containing no resources or an empty Bicep file.</p><h3 id="empty-arm-template">Empty ARM template</h3><pre><code class="language-json">{
  &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#&quot;,
  &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
  &quot;parameters&quot;: {   },
  &quot;variables&quot;: {  },
  &quot;resources&quot;: [  ],
  &quot;outputs&quot;: {  }
}</code></pre><p>Now, let&apos;s pretend the name of the ARM template is &quot;ResourceGroupCleanup.template.jsonc&quot;.</p><p>A JSONC file is just a JSON file format that supports comments. Azure and Visual Studio code support this.</p><h3 id="empty-bicep-file">Empty Bicep file</h3><p>Bicep is a DSL that is easier and compact to author than ARM templates (they are now considered more as an intermediate language - IL).</p><p>Knowing this, you don&apos;t have to remember the empty format of the ARM template. We just need to create an empty file, give it a bicep extension and you now have a lightweight ARM template.</p><pre><code class="language-powershell">$null &gt; ResourceGroupCleanup.bicep
</code></pre><blockquote>In order to deploy bicep files thru PowerShell or Azure CLI, you&apos;ll need a recent, 2021 version of them. In this article I&apos;ve used <a href="https://github.com/Azure/azure-powershell/releases/tag/v5.8.0-April2021?ref=codeisahighway.com">Az 5.8.0</a> and <a href="https://github.com/Azure/azure-cli/releases/tag/azure-cli-2.22.1?ref=codeisahighway.com">Azure CLI 2.22.1</a></blockquote><h3 id="powershell">Powershell</h3><p>Here is how to invoke the deployment in &quot;Complete&quot; mode in PowerShell.</p><pre><code class="language-powershell"># ARM template
New-AzResourceGroupDeployment -ResourceGroupName MyResourceGroup -Mode Complete -TemplateFile .\ResourceGroupCleanup.template.json -Force -Verbose

# Bicep
New-AzResourceGroupDeployment -ResourceGroupName MyResourceGroup -Mode Complete -TemplateFile .\ResourceGroupCleanup.bicep -Force -Verbose</code></pre><p>After you run this command, you should have something similar to the following:</p><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2021/04/Empty-ResourceGroup-With-Deployment-1.png" class="kg-image" alt="Effective ways to delete resources in a resource group on Azure in 2021" loading="lazy" width="1989" height="1690" srcset="https://codeisahighway.com/content/images/size/w600/2021/04/Empty-ResourceGroup-With-Deployment-1.png 600w, https://codeisahighway.com/content/images/size/w1000/2021/04/Empty-ResourceGroup-With-Deployment-1.png 1000w, https://codeisahighway.com/content/images/size/w1600/2021/04/Empty-ResourceGroup-With-Deployment-1.png 1600w, https://codeisahighway.com/content/images/2021/04/Empty-ResourceGroup-With-Deployment-1.png 1989w" sizes="(min-width: 720px) 720px"></figure><h3 id="azure-cli">Azure-CLI</h3><p>Here is how to invoke the deployment in &quot;Complete&quot; mode on a resource group in Azure CLI v2.22.1 or later.</p><pre><code class="language-powershell">az deployment group create -g MyResourceGroup -f .\ResourceGroupCleanup.bicep --mode Complete</code></pre><p>After you run this command, you should have something similar to the following:</p><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2021/04/Empty-ResourceGroup-With-Deployment-AzureCLI.png" class="kg-image" alt="Effective ways to delete resources in a resource group on Azure in 2021" loading="lazy" width="1989" height="1300" srcset="https://codeisahighway.com/content/images/size/w600/2021/04/Empty-ResourceGroup-With-Deployment-AzureCLI.png 600w, https://codeisahighway.com/content/images/size/w1000/2021/04/Empty-ResourceGroup-With-Deployment-AzureCLI.png 1000w, https://codeisahighway.com/content/images/size/w1600/2021/04/Empty-ResourceGroup-With-Deployment-AzureCLI.png 1600w, https://codeisahighway.com/content/images/2021/04/Empty-ResourceGroup-With-Deployment-AzureCLI.png 1989w" sizes="(min-width: 720px) 720px"></figure><p>Hope you have fun with Azure Resource Manager and automation!</p><h2 id="references">References</h2><ul><li><a href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-authoring-templates/?ref=codeisahighway.com">Authoring Azure Resource Manager templates</a></li><li><a href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/bicep-overview?ref=codeisahighway.com">What is Bicep?</a></li><li><a href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-modes?ref=codeisahighway.com">Azure Resource Manager deployment modes</a></li><li><a href="https://github.com/Azure/azure-powershell/releases/latest?ref=codeisahighway.com">Latest Microsoft Azure PowerShell release</a></li><li><a href="https://github.com/Azure/azure-cli/releases?ref=codeisahighway.com">Latest Azure-CLI release</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Stop wasting money in Azure - ShareGate webinar]]></title><description><![CDATA[One of the main issues facing IT management in 2020 is uncontrolled cloud spending. Learn how to gain the visibility and insights you need to take control of your cloud environment, and implement a team-wide Azure cost management strategy. ]]></description><link>https://codeisahighway.com/stop-wasting-money-in-azure-sharegate-webinar/</link><guid isPermaLink="false">64ad86e191f3ba0001865953</guid><category><![CDATA[Cost Management]]></category><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[ShareGate]]></category><category><![CDATA[Speaker]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Thu, 26 Nov 2020 18:26:22 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1556761175-129418cb2dfe?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1556761175-129418cb2dfe?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Stop wasting money in Azure - ShareGate webinar"><p>One of the main issues facing IT management in 2020 is uncontrolled cloud spending. Learn how to gain the visibility and insights you need to take control of your cloud environment, and implement a team-wide Azure cost management strategy. </p><p>During this ShareGate webinar on <strong>December 8, 1:30pm EST</strong>, I will cover:</p><ul><li><strong>Why cloud cost management is so important&#x2014;and so difficult. </strong>According to our data, approximately 30% of money spent in Azure is on resources and services that could be optimized. We&#x2019;ll explain why so many people are wasting so much of their money in the cloud.</li><li><strong>Actionable steps to creating an effective Azure cost management strategy. </strong>We can take you through the steps that will help you gain visibility over your Azure spending so that you know what to optimize.</li><li><strong>Automated solutions that can help with ongoing Azure management. </strong>Manual monitoring of spending, identifying changes, and analyzing your Azure costs is time consuming and probably not why you and your team got into cloud engineering. We&#x2019;ll discuss some tools that allow you to spend your time where it counts&#x2014;leading a team in building better products and services.</li></ul><p>You can register here, it is free: <a href="https://sharegate.com/resource/azure-cost-management-webinar?ref=codeisahighway.com">https://sharegate.com/resource/azure-cost-management-webinar</a></p>]]></content:encoded></item><item><title><![CDATA[My ScriptCenter's Azure scripts has moved to Github]]></title><description><![CDATA[<p>Over the years I posted a few scripts that have been useful for me in Azure on ScriptCenter. Time has come to move them on a newer platform since ScriptCenter is now obsolete and is retiring.</p><h3 id="bye-bye-scriptcenter">Bye Bye ScriptCenter</h3><p>ScriptCenter will continue to operate in read-only mode, no new contributions</p>]]></description><link>https://codeisahighway.com/my-scriptcenters-azure-scripts-has-moved-to-github/</link><guid isPermaLink="false">64ad86e191f3ba0001865950</guid><category><![CDATA[PowerShell]]></category><category><![CDATA[Microsoft Azure]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Fri, 31 Jul 2020 17:27:16 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1590595906931-81f04f0ccebb?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1590595906931-81f04f0ccebb?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="My ScriptCenter&apos;s Azure scripts has moved to Github"><p>Over the years I posted a few scripts that have been useful for me in Azure on ScriptCenter. Time has come to move them on a newer platform since ScriptCenter is now obsolete and is retiring.</p><h3 id="bye-bye-scriptcenter">Bye Bye ScriptCenter</h3><p>ScriptCenter will continue to operate in read-only mode, no new contributions but existing one can be updated from what I know. Still it has been a useful platform for the last 10 years or so.</p><p>Here are the scripts I posted over the years:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://gallery.technet.microsoft.com/scriptcenter/site/search?f%5B0%5D.Type=User&amp;f%5B0%5D.Value=s_lapointe&amp;ref=codeisahighway.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Powershell, VB Script, SQL and JavaScript - TechNet IT Pro&#x2019;s and Scripting Guys</div><div class="kg-bookmark-description">Download resources and applications for Windows 8, Windows 7, Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, SharePoint, System Center, Office, and other products.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://i1.gallery.technet.s-msft.com/scriptcenter/GlobalResources/images/Technet/favicon.ico" alt="My ScriptCenter&apos;s Azure scripts has moved to Github"><span class="kg-bookmark-author">Script Center</span></div></div></a></figure><p>Some has been very popular over the years, like:</p><h3 id="easily-obtain-accesstoken-bearer-from-an-existing-az-azurerm-powershell-session"><a href="https://gallery.technet.microsoft.com/scriptcenter/Easily-obtain-AccessToken-3ba6e593?redir=0&amp;ref=codeisahighway.com">Easily obtain AccessToken(Bearer) from an existing Az/AzureRM PowerShell session</a></h3><blockquote>You&apos;ll find in this function an easy way to extract the information required for you to build a Bearer token and all this from YOUR credentials within an authenticated PowerShell Azure session. You can then use this token to talk to Azure Resource Manager REST API</blockquote><p>It got almost 8K downloads at the time of writing this. Several others were downloaded in the thousands also. Knowing that these script helped and continue to help people, I decided to move them before they are no longer accessible at all.</p><h3 id="hello-github-">Hello GitHub!</h3><p>I decided to move all these scripts to a repository in GitHub. I made a first release with what is exactly on ScriptCenter. You can download the release here: </p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/slapointe/azure-scripts/releases/tag/v1.0?ref=codeisahighway.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Release Snapshot from ScriptCenter &#xB7; slapointe/azure-scripts</div><div class="kg-bookmark-description">Same as downloading all of my scripts from ScriptCenter and starting point for their evolution on Github: Easily obtain AccessToken(Bearer) from an existing Az/AzureRM PowerShell sessionList all ...</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/favicons/favicon.svg" alt="My ScriptCenter&apos;s Azure scripts has moved to Github"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">slapointe</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://avatars2.githubusercontent.com/u/1054412?s=400&amp;v=4" alt="My ScriptCenter&apos;s Azure scripts has moved to Github"></div></a></figure><p>Hope it helps, if you want to contribute on this repo, you are more than welcome :)</p><h3 id="reference">Reference</h3><ul><li><a href="https://github.com/slapointe/azure-scripts?ref=codeisahighway.com">Stephane Lapointe&apos;s Azure Scripts on GitHub</a></li></ul>]]></content:encoded></item><item><title><![CDATA[How-to use customer-managed keys with Azure Key Vault and Azure Storage encryption using ARM Template]]></title><description><![CDATA[<p>I got a question from a reader asking how to use the Managed Identity of a storage account against Azure Key Vault to enable storage encryption using <a href="https://docs.microsoft.com/en-us/azure/storage/common/encryption-customer-managed-keys?ref=codeisahighway.com">customer-managed keys</a>. The documentation doesn&apos;t say storage accounts can have an identity. Testing a solution made me realize I was wrong,</p>]]></description><link>https://codeisahighway.com/how-to-use-customer-managed-keys-with-azure-key-vault-and-azure-storage-encryption-using-arm-template/</link><guid isPermaLink="false">64ad86e191f3ba0001865952</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Storage]]></category><category><![CDATA[Azure Key Vault]]></category><category><![CDATA[ARM Template]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Thu, 30 Jul 2020 17:01:28 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1582970816926-c8b60f417661?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1582970816926-c8b60f417661?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="How-to use customer-managed keys with Azure Key Vault and Azure Storage encryption using ARM Template"><p>I got a question from a reader asking how to use the Managed Identity of a storage account against Azure Key Vault to enable storage encryption using <a href="https://docs.microsoft.com/en-us/azure/storage/common/encryption-customer-managed-keys?ref=codeisahighway.com">customer-managed keys</a>. The documentation doesn&apos;t say storage accounts can have an identity. Testing a solution made me realize I was wrong, today I learned!</p><h3 id="genesis">Genesis</h3><p>It all started with this article on my blog for the best way to reference Managed Identity using ARM templates - <a href="https://codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template/">there-is-a-new-way-to-reference-managed-identity-in-arm-template/</a></p><p>I always say that others&apos; problems can make you grow in knowledge and it&apos;s exactly what happened with Soniya&apos;s <a href="https://codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template/#comment-5010449677">question</a> yesterday.</p><blockquote>Hi Stephane, I am trying to use this method to get storage account Managed Identity and pass it to existing Keyvault&apos;s Access policy in the same template where Storage account needs to be provisioned. In the same template this storage account needs to access the keyvault to get key for user managed Storage encryption and hence the need to add the Manage identity to Keyvault access policy. I am trying to deploy it the way you have referenced the Managed Identity. But its failing. Any idea?</blockquote><p>I wasn&apos;t aware that storage accounts could have a Managed Identity, I double-checked the documentation before answering her that it was not supported. It is available for Azure Data Lake so I was kinda intrigued. She replied that she was doing it in PowerShell but wanted a way to do it via ARM templates. Nothing more was required to trigger me and try to find the answer myself.</p><h3 id="managed-identity-on-storage-account">Managed Identity on Storage Account</h3><p>After a quick test in with an ARM template, it turns out it IS possible to assign a Managed Identity to a storage account and it is fairly easy.</p><p>If you need more background on Managed Identity and how to use them in ARM templates, I have an article for you here: <a href="https://codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template/">There is a new way to reference managed identity in ARM template</a></p><p>Like for any other resources, I only had to add the identity property to my resource like this:</p><pre><code class="language-json">&quot;identity&quot;: {
                &quot;type&quot;: &quot;SystemAssigned&quot;
            }</code></pre><p>It worked, the deployment was successful! Now my storage account has a Managed Identity, awesome!</p><h3 id="updating-key-vault-access">Updating Key Vault Access</h3><p>I wrote another article recently, <a href="https://codeisahighway.com/how-to-incrementally-update-keyvault-access-policies-with-arm-templates/">How to incrementally update KeyVault access policies with ARM templates</a>. Go read it if you weren&apos;t aware, it is a good trick to have in your toolbox.</p><p>There are 2 properties that you need to set on your vault if &#xA0;you want to use customer-managed keys with Azure Key Vault to manage Azure Storage encryption. Microsoft documentation says:</p><blockquote>Using customer-managed keys with Azure Storage encryption requires that two properties be set on the key vault, <strong>Soft Delete</strong> and <strong>Do Not Purge</strong>. These properties are not enabled by default, but can be enabled using either PowerShell or Azure CLI on a new or existing key vault.</blockquote><p>You can also do it in the Portal if you want. That being said, you need to update Key Vault to set those two properties. If you don&apos;t want to mess around with retrieving access policy via a script and injecting them into an ARM template, use PowerShell, Azure CLI or the Azure Portal. If you still want to update this via template, here are the two properties.</p><pre><code class="language-json">{
  &quot;type&quot;: &quot;Microsoft.KeyVault/vaults&quot;,
  &quot;name&quot;: &quot;[variables(&apos;uniqueResourceNameBase&apos;)]&quot;,
  &quot;apiVersion&quot;: &quot;2016-10-01&quot;,
  &quot;location&quot;: &quot;[parameters(&apos;location&apos;)]&quot;,
  &quot;properties&quot;: {
    &quot;sku&quot;: {
      &quot;family&quot;: &quot;A&quot;,
      &quot;name&quot;: &quot;standard&quot;
    },
    &quot;tenantId&quot;: &quot;[subscription().tenantid]&quot;,
    &quot;accessPolicies&quot;: [...],
    &quot;enableSoftDelete&quot;: true,
    &quot;enablePurgeProtection&quot;: true
  }
}</code></pre><p>We now have a properly configured Key Vault to support storage encryption, we still need a key for that encryption. There&apos;s several ways to do this, the simpliest is via the portal. It is not possible &quot;natively&quot; via template without going through a complicated plumbing. Still interested to create keys via template? I found this <a href="https://medium.com/@jorge.cotillo/create-key-vault-keys-using-arm-templates-and-azure-blueprints-77086ae02b3e?ref=codeisahighway.com">little gem from Jorge Cotillo</a></p><p>Let stick to the portal for simplicity</p><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2020/07/generate-keyvault-key.png" class="kg-image" alt="How-to use customer-managed keys with Azure Key Vault and Azure Storage encryption using ARM Template" loading="lazy" width="1634" height="974" srcset="https://codeisahighway.com/content/images/size/w600/2020/07/generate-keyvault-key.png 600w, https://codeisahighway.com/content/images/size/w1000/2020/07/generate-keyvault-key.png 1000w, https://codeisahighway.com/content/images/size/w1600/2020/07/generate-keyvault-key.png 1600w, https://codeisahighway.com/content/images/2020/07/generate-keyvault-key.png 1634w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2020/07/create-keyvault-key.png" class="kg-image" alt="How-to use customer-managed keys with Azure Key Vault and Azure Storage encryption using ARM Template" loading="lazy" width="755" height="931" srcset="https://codeisahighway.com/content/images/size/w600/2020/07/create-keyvault-key.png 600w, https://codeisahighway.com/content/images/2020/07/create-keyvault-key.png 755w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2020/07/keyvault-key-created.png" class="kg-image" alt="How-to use customer-managed keys with Azure Key Vault and Azure Storage encryption using ARM Template" loading="lazy" width="1183" height="353" srcset="https://codeisahighway.com/content/images/size/w600/2020/07/keyvault-key-created.png 600w, https://codeisahighway.com/content/images/size/w1000/2020/07/keyvault-key-created.png 1000w, https://codeisahighway.com/content/images/2020/07/keyvault-key-created.png 1183w" sizes="(min-width: 720px) 720px"></figure><h3 id="add-the-new-access-policy">Add the new access policy</h3><p>The storage account needs access to Key Vault. Let&apos;s add a new access policy, the access need to be <code>wrapkey</code>, <code>unwrapkey</code> and <code>get</code> permissions on <code>keys</code>.</p><pre><code class="language-json">{
  &quot;type&quot;: &quot;Microsoft.KeyVault/vaults/accessPolicies&quot;,
  &quot;name&quot;: &quot;[concat(variables(&apos;uniqueResourceNameBase&apos;), &apos;/add&apos;)]&quot;,
  &quot;apiVersion&quot;: &quot;2019-09-01&quot;,
  &quot;properties&quot;: {
    &quot;accessPolicies&quot;: [
      {
        &quot;tenantId&quot;: &quot;[subscription().tenantid]&quot;,
        &quot;objectId&quot;: &quot;[reference(resourceId(&apos;Microsoft.Storage/storageAccounts&apos;, variables(&apos;uniqueResourceNameBase&apos;)),&apos;2019-06-01&apos;, &apos;full&apos;).identity.principalId]&quot;,
        &quot;permissions&quot;: {
          &quot;keys&quot;: [
            &quot;wrapkey&quot;,
            &quot;unwrapkey&quot;,
            &quot;get&quot;
          ],
          &quot;secrets&quot;: [],
          &quot;certificates&quot;: []
        }
      }
    ]
  }
}</code></pre><h3 id="configuring-the-encryption-key-on-the-storage-account">Configuring the encryption key on the storage account</h3><p>Now that we have our key and appropriate permission in Key Vault. We need to reference and configure the key to use on the storage account.</p><p>We need to set the <code>keySource</code> to <code>Microsoft.Keyvault</code> and fill Key Vault and key details. If <code>keyVersion</code> is left blank, it will use the latest version of the key. You can also set it to a specific version if you prefer that.</p><pre><code class="language-json">{
  &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
  &quot;sku&quot;: {
    &quot;name&quot;: &quot;Standard_LRS&quot;,
    &quot;tier&quot;: &quot;Standard&quot;
  },
  &quot;kind&quot;: &quot;Storage&quot;,
  &quot;name&quot;: &quot;[variables(&apos;uniqueResourceNameBase&apos;)]&quot;,
  &quot;apiVersion&quot;: &quot;2019-06-01&quot;,
  &quot;location&quot;: &quot;[parameters(&apos;location&apos;)]&quot;,
  &quot;identity&quot;: {
    &quot;type&quot;: &quot;SystemAssigned&quot;
  },
  &quot;properties&quot;: {
    &quot;encryption&quot;: {
      &quot;services&quot;: {
        &quot;file&quot;: {
          &quot;enabled&quot;: true
        },
        &quot;blob&quot;: {
          &quot;enabled&quot;: true
        }
      },
      &quot;keySource&quot;: &quot;Microsoft.Keyvault&quot;,
      &quot;keyvaultproperties&quot;: {
        &quot;keyvaulturi&quot;: &quot;[reference(resourceId(&apos;Microsoft.KeyVault/vaults&apos;, variables(&apos;uniqueResourceNameBase&apos;)),&apos;2016-10-01&apos;, &apos;full&apos;).properties.vaultUri]&quot;,
        &quot;keyname&quot;: &quot;[parameters(&apos;keyName&apos;)]&quot;,
        &quot;keyversion&quot;: &quot;[parameters(&apos;keyversion&apos;)]&quot;
      }
    }
  }
}</code></pre><h2 id="complete-example">Complete example</h2><p>Here is a complete and functional ARM template that you need to deploy 2 times to fully configure it all. The first run will create the Key Vault and storage account. You then need to manually create the key in Key Vault and run the deployment again to let it do the rest of the work.</p><p>This template use a nested deployment to seperate the configuration of the storage account with key information from the creation of the 2 resources to have a complete example.</p><pre><code class="language-json">{
  &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#&quot;,
  &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
  &quot;parameters&quot;: {
    &quot;keyName&quot;: {
      &quot;type&quot;: &quot;string&quot;,
      &quot;defaultValue&quot;: &quot;storage-enc-test&quot;
    },
    &quot;keyVersion&quot;: {
      &quot;type&quot;: &quot;string&quot;,
      &quot;defaultValue&quot;: &quot;&quot;
    },
    &quot;location&quot;: {
      &quot;type&quot;: &quot;string&quot;,
      &quot;defaultValue&quot;: &quot;[resourceGroup().location]&quot;
    },
    &quot;configureEncryptionKey&quot;: {
      &quot;type&quot;: &quot;bool&quot;,
      &quot;defaultValue&quot;: false
    }
  },
  &quot;variables&quot;: {
    &quot;uniqueResourceNameBase&quot;: &quot;[uniqueString(resourceGroup().id, parameters(&apos;location&apos;), deployment().name)]&quot;
  },
  &quot;resources&quot;: [
    {
      &quot;condition&quot;: &quot;[not(parameters(&apos;configureEncryptionKey&apos;))]&quot;,
      &quot;type&quot;: &quot;Microsoft.KeyVault/vaults&quot;,
      &quot;name&quot;: &quot;[variables(&apos;uniqueResourceNameBase&apos;)]&quot;,
      &quot;apiVersion&quot;: &quot;2016-10-01&quot;,
      &quot;location&quot;: &quot;[parameters(&apos;location&apos;)]&quot;,
      &quot;properties&quot;: {
        &quot;sku&quot;: {
          &quot;family&quot;: &quot;A&quot;,
          &quot;name&quot;: &quot;standard&quot;
        },
        &quot;tenantId&quot;: &quot;[subscription().tenantid]&quot;,
// !BEWARE! Running this property with an empty bracket will remove all your existing access policies
// If you need to update the required properties for storage encryption,
// you can fetch existing access policies via script and pass them as template parameter
        &quot;accessPolicies&quot;: [],
        &quot;enableSoftDelete&quot;: true,
        &quot;enablePurgeProtection&quot;: true
      },
      &quot;dependsOn&quot;: [
        &quot;[resourceId(&apos;Microsoft.Storage/storageAccounts&apos;, variables(&apos;uniqueResourceNameBase&apos;))]&quot;
      ]
    },
    {
      &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
      &quot;sku&quot;: {
        &quot;name&quot;: &quot;Standard_LRS&quot;,
        &quot;tier&quot;: &quot;Standard&quot;
      },
      &quot;kind&quot;: &quot;Storage&quot;,
      &quot;name&quot;: &quot;[variables(&apos;uniqueResourceNameBase&apos;)]&quot;,
      &quot;apiVersion&quot;: &quot;2019-06-01&quot;,
      &quot;location&quot;: &quot;[parameters(&apos;location&apos;)]&quot;,
      &quot;identity&quot;: {
        &quot;type&quot;: &quot;SystemAssigned&quot;
      },
      &quot;properties&quot;: {
        &quot;supportsHttpsTrafficOnly&quot;: true
      },
      &quot;dependsOn&quot;: []
    },
    {
      &quot;condition&quot;: &quot;[parameters(&apos;configureEncryptionKey&apos;)]&quot;,
      &quot;type&quot;: &quot;Microsoft.Resources/deployments&quot;,
      &quot;apiVersion&quot;: &quot;2019-07-01&quot;,
      &quot;name&quot;: &quot;updateStorageAccount&quot;,
      &quot;dependsOn&quot;: [
        &quot;[resourceId(&apos;Microsoft.KeyVault/vaults&apos;, variables(&apos;uniqueResourceNameBase&apos;))]&quot;
      ],
      &quot;properties&quot;: {
        &quot;mode&quot;: &quot;Incremental&quot;,
        &quot;template&quot;: {
          &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#&quot;,
          &quot;contentVersion&quot;: &quot;0.1.0.0&quot;,
          &quot;resources&quot;: [
            {
              &quot;type&quot;: &quot;Microsoft.KeyVault/vaults/accessPolicies&quot;,
              &quot;name&quot;: &quot;[concat(variables(&apos;uniqueResourceNameBase&apos;), &apos;/add&apos;)]&quot;,
              &quot;apiVersion&quot;: &quot;2019-09-01&quot;,
              &quot;properties&quot;: {
                &quot;accessPolicies&quot;: [
                  {
                    &quot;tenantId&quot;: &quot;[subscription().tenantid]&quot;,
                    &quot;objectId&quot;: &quot;[reference(resourceId(&apos;Microsoft.Storage/storageAccounts&apos;, variables(&apos;uniqueResourceNameBase&apos;)),&apos;2019-06-01&apos;, &apos;full&apos;).identity.principalId]&quot;,
                    &quot;permissions&quot;: {
                      &quot;keys&quot;: [
                        &quot;wrapkey&quot;,
                        &quot;unwrapkey&quot;,
                        &quot;get&quot;
                      ],
                      &quot;secrets&quot;: [],
                      &quot;certificates&quot;: []
                    }
                  }
                ]
              }
            },
            {
              &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
              &quot;sku&quot;: {
                &quot;name&quot;: &quot;Standard_LRS&quot;,
                &quot;tier&quot;: &quot;Standard&quot;
              },
              &quot;kind&quot;: &quot;Storage&quot;,
              &quot;name&quot;: &quot;[variables(&apos;uniqueResourceNameBase&apos;)]&quot;,
              &quot;apiVersion&quot;: &quot;2019-06-01&quot;,
              &quot;location&quot;: &quot;[parameters(&apos;location&apos;)]&quot;,
              &quot;identity&quot;: {
                &quot;type&quot;: &quot;SystemAssigned&quot;
              },
              &quot;properties&quot;: {
                &quot;encryption&quot;: {
                  &quot;services&quot;: {
                    &quot;file&quot;: {
                      &quot;enabled&quot;: true
                    },
                    &quot;blob&quot;: {
                      &quot;enabled&quot;: true
                    }
                  },
                  &quot;keySource&quot;: &quot;Microsoft.Keyvault&quot;,
                  &quot;keyvaultproperties&quot;: {
                    &quot;keyvaulturi&quot;: &quot;[reference(resourceId(&apos;Microsoft.KeyVault/vaults&apos;, variables(&apos;uniqueResourceNameBase&apos;)),&apos;2016-10-01&apos;, &apos;full&apos;).properties.vaultUri]&quot;,
                    &quot;keyname&quot;: &quot;[parameters(&apos;keyName&apos;)]&quot;,
                    &quot;keyversion&quot;: &quot;[parameters(&apos;keyversion&apos;)]&quot;
                  }
                }
              },
              &quot;dependsOn&quot;: [
                &quot;[resourceId(&apos;Microsoft.KeyVault/vaults/accessPolicies&apos;, variables(&apos;uniqueResourceNameBase&apos;), &apos;add&apos;)]&quot;
              ]
            }
          ]
        }
      }
    }
  ]
}</code></pre><p>1 - First run</p><pre><code class="language-powershell">Connect-AzAccount

New-AzResourceGroup -name mi-storage -location eastus

New-AzResourceGroupDeployment -ResourceGroupName mi-storage -TemplateFile C:\temp\deploy.json -Verbose

VERBOSE: Performing the operation &quot;Creating Deployment&quot; on target &quot;mi-storage&quot;.
VERBOSE: 11:30:12 AM - Template is valid.
VERBOSE: 11:30:14 AM - Create template deployment &apos;deploy&apos;
VERBOSE: 11:30:14 AM - Checking deployment status in 5 seconds
VERBOSE: 11:30:19 AM - Resource Microsoft.Storage/storageAccounts &apos;ic626scfz2hba&apos; provisioning status is running
VERBOSE: 11:30:19 AM - Checking deployment status in 17 seconds
VERBOSE: 11:30:37 AM - Checking deployment status in 5 seconds
VERBOSE: 11:30:42 AM - Resource Microsoft.KeyVault/vaults &apos;ic626scfz2hba&apos; provisioning status is running
VERBOSE: 11:30:42 AM - Resource Microsoft.Storage/storageAccounts &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:30:42 AM - Resource Microsoft.Storage/storageAccounts &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:30:42 AM - Checking deployment status in 15 seconds
VERBOSE: 11:30:57 AM - Resource Microsoft.KeyVault/vaults &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:30:57 AM - Resource Microsoft.KeyVault/vaults &apos;ic626scfz2hba&apos; provisioning status is succeeded

DeploymentName          : deploy
ResourceGroupName       : mi-storage
ProvisioningState       : Succeeded
Timestamp               : 7/30/2020 3:30:55 PM
Mode                    : Incremental
TemplateLink            :
Parameters              :
Name                      Type                       Value
========================  =========================  ==========
keyName                   String                     storage-enc-test
keyVersion                String
location                  String                     eastus
configureEncryptionKey    Bool                       False

Outputs                 :
DeploymentDebugLogLevel :</code></pre><p>2 - Create your key manually.</p><p>3 - Last, run with the special flag <code>configureEncryptionKey</code> set to true to run the configuration step on the storage account. There is a condition on the nested deployment that will only execute if that template parameter is set to true.</p><p>See below</p><pre><code class="language-json">{
  &quot;condition&quot;: &quot;[parameters(&apos;configureEncryptionKey&apos;)]&quot;,
  &quot;type&quot;: &quot;Microsoft.Resources/deployments&quot;,
  &quot;apiVersion&quot;: &quot;2019-07-01&quot;,
  &quot;name&quot;: &quot;updateStorageAccount&quot;,
  ...
}</code></pre><p>Trigger the second deployment like this:</p><pre><code class="language-powershell">New-AzResourceGroupDeployment -ResourceGroupName mi-storage -TemplateFile C:\temp\deploy.json -configureEncryptionKey $true -Verbose

VERBOSE: Performing the operation &quot;Creating Deployment&quot; on target &quot;mi-storage&quot;.
VERBOSE: 11:34:10 AM - Template is valid.
VERBOSE: 11:34:11 AM - Create template deployment &apos;deploy&apos;
VERBOSE: 11:34:11 AM - Checking deployment status in 5 seconds
VERBOSE: 11:34:17 AM - Resource Microsoft.Resources/deployments &apos;updateStorageAccount&apos; provisioning status is running
VERBOSE: 11:34:17 AM - Resource Microsoft.KeyVault/vaults/accessPolicies &apos;ic626scfz2hba/add&apos; provisioning status is succeeded
VERBOSE: 11:34:17 AM - Resource Microsoft.KeyVault/vaults &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:34:17 AM - Resource Microsoft.KeyVault/vaults &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:34:17 AM - Resource Microsoft.Storage/storageAccounts &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:34:17 AM - Resource Microsoft.Storage/storageAccounts &apos;ic626scfz2hba&apos; provisioning status is succeeded
VERBOSE: 11:34:17 AM - Checking deployment status in 5 seconds
VERBOSE: 11:34:22 AM - Checking deployment status in 5 seconds
VERBOSE: 11:34:28 AM - Checking deployment status in 6 seconds
VERBOSE: 11:34:34 AM - Checking deployment status in 6 seconds

DeploymentName          : deploy
ResourceGroupName       : mi-storage
ProvisioningState       : Succeeded
Timestamp               : 7/30/2020 3:34:39 PM
Mode                    : Incremental
TemplateLink            :
Parameters              :
Name                      Type                       Value
========================  =========================  ==========
keyName                   String                     storage-enc-test
keyVersion                String
location                  String                     eastus
configureEncryptionKey    Bool                       True

Outputs                 :
DeploymentDebugLogLevel :</code></pre><p></p><p>If I take a look in the Azure portal, we can see that the key has been correctly configured.</p><figure class="kg-card kg-image-card"><img src="https://codeisahighway.com/content/images/2020/07/encryption-configured.png" class="kg-image" alt="How-to use customer-managed keys with Azure Key Vault and Azure Storage encryption using ARM Template" loading="lazy" width="1912" height="1111" srcset="https://codeisahighway.com/content/images/size/w600/2020/07/encryption-configured.png 600w, https://codeisahighway.com/content/images/size/w1000/2020/07/encryption-configured.png 1000w, https://codeisahighway.com/content/images/size/w1600/2020/07/encryption-configured.png 1600w, https://codeisahighway.com/content/images/2020/07/encryption-configured.png 1912w" sizes="(min-width: 720px) 720px"></figure><p>Hope you liked this article, again, thank you <a href="https://www.linkedin.com/in/soniya-sutar/?ref=codeisahighway.com">Soniya</a>, today you made me learned something new, storage can have an identity :)</p><p>Happy ARM template!</p><h3 id="references">References</h3><ul><li><a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-encryption-keys-portal?ref=codeisahighway.com">Configure customer-managed keys with Azure Key Vault by using the Azure portal</a></li><li><a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-encryption-keys-powershell?ref=codeisahighway.com">Configure customer-managed keys with Azure Key Vault by using PowerShell</a></li><li><a href="https://docs.microsoft.com/en-us/rest/api/storagerp/storageaccounts/create?ref=codeisahighway.com#keytype">Storage Account KeyVault KeyType reference documentation</a></li><li><a href="https://medium.com/@jorge.cotillo/create-key-vault-keys-using-arm-templates-and-azure-blueprints-77086ae02b3e?ref=codeisahighway.com">Create Key Vault keys using ARM templates and Azure Blueprints</a></li></ul>]]></content:encoded></item><item><title><![CDATA[How to incrementally update KeyVault access policies with ARM templates]]></title><description><![CDATA[<p>I was recently asked how to give access to an existing KeyVault to a managed identity that already have access policies configured. It&apos;s not a secret but not all know about this little trick that will enable you to incrementally process permissions to KeyVault over time using ARM</p>]]></description><link>https://codeisahighway.com/how-to-incrementally-update-keyvault-access-policies-with-arm-templates/</link><guid isPermaLink="false">64ad86e191f3ba0001865951</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[ARM Template]]></category><category><![CDATA[Azure Key Vault]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Tue, 30 Jun 2020 23:24:18 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1562362832-b10b5ae95cec?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1562362832-b10b5ae95cec?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="How to incrementally update KeyVault access policies with ARM templates"><p>I was recently asked how to give access to an existing KeyVault to a managed identity that already have access policies configured. It&apos;s not a secret but not all know about this little trick that will enable you to incrementally process permissions to KeyVault over time using ARM templates.</p><h3 id="genesis">Genesis</h3><p>It all started with this article on the best way to reference Managed Identity using ARM templates - <a href="https://codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template/">there-is-a-new-way-to-reference-managed-identity-in-arm-template/</a></p><p>One of my readers (<a href="https://disqus.com/by/disqus_XuNXkX4KEU/?ref=codeisahighway.com">Sam</a> not to name it :)) reached out with a question I got asked several times over the years. So I decided to write an article about it.</p><p>The question was:</p><blockquote>Thanks for the article. I&apos;m trying to assign keyvault access policies to the system-assigned identity of my webapp. However in your example a new keyvault is created. How can do that for an existing keyvault ?</blockquote><p>My understading with this question is that he wants to update his existing KeyVault without messing with the existing acess policies. The good news is there&apos;s a way to do this, let&apos;s see how.</p><h3 id="incremental-access-policy-update">Incremental Access Policy update</h3><p>The way to perform an incremental update of KeyVault AccessPolicies is by using a resource type named <code>Microsoft.KeyVault/vaults/accessPolicies</code></p><p>You have three choice of name for the resource: <code>add</code>, <code>replace</code> or <code>remove</code>. As you can guess they will perform different actions on the access policy you are defining. I used <code>add</code> in the example below but let me summarize them rapidly.</p><ul><li><code>add</code> will add a new set of permission or merge them with existing if any exists for the pair objectId and tenantId.<br><br>In the case of <code>add</code> if the principal had the <code>list</code> permission and you call <code>add</code> with the <code>get</code> permission, the end result will be <code>list, get</code>.<br></li><li><code>replace</code> will create or override any existing permission with what is expressed in the template for the pair objectId and tenantId. <br><br>In the case of <code>replace</code> if the principal had <code>list, get</code> permissions and you call <code>replace</code> with the <code>get</code> permission, the end result will be <code>get</code>.<br></li><li><code>delete</code> will delete the access policyfor the pair objectId and tenantId.</li></ul><h3 id="complete-example">Complete example</h3><p>Here is a complete and functional ARM template that use <code>vaulName</code>, <code>principalId</code>and optional <code>tenantId</code> parameters to populate add/merge (1) access policy because of the resource name <code>add</code> on KeyVault <code>vaulName</code>.</p><pre><code class="language-json">{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;vaultName&quot;: {
            &quot;type&quot;: &quot;string&quot;
        },
        &quot;principalId&quot;: {
            &quot;type&quot;: &quot;string&quot;
        },
        &quot;tenantId&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;[subscription().tenantId]&quot;
        }
    },
    &quot;resources&quot;: [
        {
            &quot;type&quot;: &quot;Microsoft.KeyVault/vaults/accessPolicies&quot;,
            &quot;name&quot;: &quot;[concat(parameters(&apos;vaultName&apos;), &apos;/add&apos;)]&quot;,
            &quot;apiVersion&quot;: &quot;2019-09-01&quot;,
            &quot;properties&quot;: {
                &quot;accessPolicies&quot;: [
                    {
                        &quot;tenantId&quot;: &quot;[parameters(&apos;tenantId&apos;)]&quot;,
                        &quot;objectId&quot;: &quot;[parameters(&apos;principalId&apos;)]&quot;,
                        &quot;permissions&quot;: {
                            &quot;keys&quot;: [&quot;all&quot;],
                            &quot;secrets&quot;: [&quot;all&quot;],
                            &quot;certificates&quot;: [&quot;all&quot;],
                            &quot;storage&quot;: [&quot;all&quot;]
                        }
                    }
                ]
            }
        }
    ],
    &quot;outputs&quot;: {
    }
}</code></pre><p>Hope you like this article, and Sam, that it answer your question!</p><p>Happy ARM template!</p><h3 id="references">References</h3><ul><li><a href="https://docs.microsoft.com/en-us/azure/templates/microsoft.keyvault/2019-09-01/vaults/accesspolicies?ref=codeisahighway.com">Microsoft.KeyVault vaults/accessPolicies template reference</a></li><li><a href="https://codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template">There is a new way to reference managed identity in ARM template</a></li></ul>]]></content:encoded></item><item><title><![CDATA[2020-05-07: ShareGate Deploy Azure online event]]></title><description><![CDATA[<p>Before COVID-19 started to force a global shutdown everywhere, we were already thinking about this event. The long term goal? Help cloud engineers being more successful with Microsoft Azure. ShareGate Deploy is a free event, one of the several to come onto this journey!</p><h2 id="a-full-day-focused-on-microsoft-azure-governance-and-best-practices">A full day focused on Microsoft</h2>]]></description><link>https://codeisahighway.com/2020-05-07-sharegate-deploy-azure-online-event/</link><guid isPermaLink="false">64ad86e191f3ba000186594f</guid><category><![CDATA[Community]]></category><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Governance]]></category><category><![CDATA[Best Practices]]></category><category><![CDATA[Speaker]]></category><category><![CDATA[Azure Resource Manager]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Tue, 21 Apr 2020 21:37:46 GMT</pubDate><media:content url="https://codeisahighway.com/content/images/2020/04/deploy-og2x-1024x536-1-.png" medium="image"/><content:encoded><![CDATA[<img src="https://codeisahighway.com/content/images/2020/04/deploy-og2x-1024x536-1-.png" alt="2020-05-07: ShareGate Deploy Azure online event"><p>Before COVID-19 started to force a global shutdown everywhere, we were already thinking about this event. The long term goal? Help cloud engineers being more successful with Microsoft Azure. ShareGate Deploy is a free event, one of the several to come onto this journey!</p><h2 id="a-full-day-focused-on-microsoft-azure-governance-and-best-practices">A full day focused on Microsoft Azure governance and best practices</h2><p>ShareGate Deploy is a <u>free event</u> will take place online on <em>Thursday, May 7 from 9am-5pm ET</em>. There will be 8 sessions total given by Microsoft Most Valuable Professionals (MVPs) and Microsoft employees.</p><p>From the event page:</p><blockquote>Deploy is a virtual event in which Azure experts share their experiences and insights to help you identify best practices to increase efficiency and visibility in the cloud.</blockquote><p><strong>The idea behind this event is to share other people&apos;s experiences, best practices and governance tips to enable you to be more successful with Microsoft Azure.</strong></p><p>Register here:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://sharegate.com/deploy-event?ref=codeisahighway.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Deploy: An expert-led online event focused on Microsoft Azure governance - ShareGate</div><div class="kg-bookmark-description">Deploy is a virtual event where experts share their experiences and insights to help you optimize your Azure environment. Join us to learn Azure governance best practices.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://sharegate.com/app/themes/sharegate/img/favicons/ShareGate_Favicon_192X192.png" alt="2020-05-07: ShareGate Deploy Azure online event"><span class="kg-bookmark-author">ShareGate</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://sharegate.com/app/uploads/2020/03/deploy-og2x-1024x536.png" alt="2020-05-07: ShareGate Deploy Azure online event"></div></a></figure><h2 id="speakers-and-session-lineup">Speakers and session lineup</h2><p>Here is the list of speakers and session details</p><ul><li><strong>Bulletproofing your Azure subscriptions</strong> - <a href="https://twitter.com/JussiRoine?ref=codeisahighway.com">Jussi Roine</a></li><li><strong>Governance: The forgotten key to managing the cloud</strong> - <a href="https://twitter.com/rikhepworth?ref=codeisahighway.com">Rik Hepworth</a></li><li><strong>Securing Serverless Applications in Azure</strong> - <a href="https://twitter.com/SjoukjeZaal?ref=codeisahighway.com">Sjoukje Zaal</a></li><li><strong>Manage and govern your hybrid servers using Azure Arc</strong> - <a href="https://twitter.com/ThomasMaurer?ref=codeisahighway.com">Thomas Maurer</a></li><li><strong>Azure Resource Manager templates tips, tricks, and advanced techniques</strong> - <a href="https://twitter.com/samcogan?ref=codeisahighway.com">Sam Cogan</a></li><li><strong>Exploring Azure with Resource Graph</strong> - <a href="https://twitter.com/alexandair?ref=codeisahighway.com">Aleksandar Nikolic</a></li><li><strong>Lessons learned: Improving visibility, accountability and cost in Azure</strong> - <a href="https://twitter.com/s_lapointe?ref=codeisahighway.com">Stephane Lapointe</a></li><li><strong>Implementing control and governance at-scale using Azure Policy and Azure governance</strong> - <a href="https://twitter.com/lizkim101?ref=codeisahighway.com">Liz Kim</a> and <a href="https://twitter.com/jochan_msft?ref=codeisahighway.com">Joseph Chan</a></li></ul><p>All the details below: </p><h3 id="bulletproofing-your-azure-subscriptions">Bulletproofing your Azure subscriptions</h3><p>In this session we&apos;ll do a lap around Microsoft Azure to understand how to best monitor what&apos;s happening within your Azure subscriptions, how to manage these subscriptions, and how best to configure security for your services.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/jussi.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Jussi Roine</strong><br>Azure Developer Audience Lead at Microsoft</p><h3 id="governance-the-forgotten-key-to-managing-the-cloud">Governance: The forgotten key to managing the cloud</h3><p>We all want to use the cloud in our projects, and every customer I talk to has developers that want to pioneer their company&apos;s adoption of the latest and coolest stuff. But for every success story there is a painful admission: Crazy costs from unconstrained adoption, sensitive data suddenly stored somewhere it shouldn&apos;t be, technology gone wild as every project tries something new.<br><br>The solution is governance, and making sure you, the developers and IT pros who are advocating cloud in you organizations, understand the management needed for successful adoption is key: When you convince your team to move to Azure you can get extra credit for helping your organization move to the cloud without the pain.<br><br>Whilst governance does not need tooling per se, Microsoft has a range of great tools in the Azure arsenal to help you. In this session I&apos;ll talk about the kinds of things that can go wrong, the simple things you can do to avoid them, and I&apos;ll show you the Azure tooling, some of it brand new, that will help you.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/rik.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Rik Hepworth</strong><br>Chief Consulting Officer at Black Marble</p><h3 id="securing-serverless-applications-in-azure">Securing Serverless Applications in Azure</h3><p>Serverless is all about unleashing developer productivity by reducing the management burden and allowing you to focus on the application logic. But even for serverless applications, security is key!<br><br>In this session Sjoukje will guide you on how to secure your serverless applications. We are going to take a look at the different options for securing your serverless apps, such as using Azure Key Vault, ClaimsPrincipal binding data for Azure Functions and much more.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/sjoukje.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Sjoukje Zaal</strong><br>CTO Microsoft at Capgemini</p><h3 id="manage-and-govern-your-hybrid-servers-using-azure-arc">Manage and govern your hybrid servers using Azure Arc</h3><p>Thomas Maurer shows you how you can manage and govern your Windows and Linux machines hosted outside of Azure on your corporate network or other cloud provider, similarly to how you manage native Azure virtual machines. When a hybrid machine is connected to Azure, it becomes a connected machine and is treated as a resource in Azure. Azure Arc provides you with the familiar cloud-native Azure management experience, like RBAC, Tags, Azure Policy, Log Analytics and more.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/thomas.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Thomas Maurer</strong><br>Senior Cloud Advocate at Microsoft</p><h3 id="azure-resource-manager-templates-tips-tricks-and-advanced-techniques">Azure Resource Manager templates tips, tricks, and advanced techniques</h3><p>A technical discussion of some more advanced techniques to take your Azure Resource Manager templates to the next level. Covering techniques such as T-Shirt sizes, functions and testing as well as some brand new tools fresh into preview. Intended for those who have used basic ARM templates to deploy Azure resources but now want to learn more advanced techniques and overcome problems they may be facing.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/sam.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Sam Cogan</strong><br>Solution Architect at Willis Towers Watson</p><h3 id="exploring-azure-with-resource-graph">Exploring Azure with Resource Graph</h3><p>Azure Resource Graph is a service that is designed to enable us to explore all of our Azure resources and effectively manage our cloud inventory at scale. There is no better way to learn about powerful querying capabilities to get deeper insights from our resources than analyzing various query examples. We use Azure Resource Graph Explorer to run queries, and build inventory dashboards and Azure Monitor workbooks to visualize our Azure resources or take advantage of the scripting and automate queries using Azure PowerShell and Azure CLI.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/aleksandar.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Aleksandar Nikolic</strong><br>Co-founder of PowerShellMagazine.com<br></p><h3 id="lessons-learned-improving-visibility-accountability-and-cost-in-azure">Lessons learned: Improving visibility, accountability and cost in Azure</h3><p>The cloud promises many great things, but they won&apos;t magically happen without any adjustment on your part. In a democratized model, giving more power to more users comes at a price. Visibility, accountability, and cost control now become crucial aspects of a good cloud governance.<br><br>Maybe are you already asking yourself if your resource usage and cost are optimal or if you could do better? Are you able to tell who owns what very easily? Are your resources configured the way you require them across your organization? In all cases, being proactive regarding resource configuration, categorization, usage, and cost in Azure will bring you great benefits.<br><br>In a very transparent way, learn about our cloud journey at ShareGate. Our good&#x2014;and less good&#x2014;moves regarding all the topics above as we continue to adapt and evolve in an ever-changing cloud world.[read less]</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/slap.png" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Stephane Lapointe</strong><br>Cloud Solutions Architect at ShareGate</p><h3 id="implementing-control-and-governance-at-scale-using-azure-policy-and-azure-governance">Implementing control and governance at-scale using Azure Policy and Azure governance</h3><p>In this session, we will go over how Azure makes it easy to get better visibility and control into your environment using Azure Governance. This will be an in-depth session on Azure Governance capabilities, Azure Policy architecture, and best practices on implementing governance.</p><figure class="kg-card kg-image-card"><img src="https://sharegate.com/app/uploads/2020/03/joseph_liz.gif" class="kg-image" alt="2020-05-07: ShareGate Deploy Azure online event" loading="lazy"></figure><p><strong>Liz Kim and Joseph Chan</strong><br>Liz is Product manager, Azure Policy and ARM RBAC at Microsoft<br>Joseph is Head of Products, Azure ARM Control Plane &amp; Governance team at Microsoft</p><h2 id="conclusion">Conclusion</h2><p>If you want to be proactive, learn new tips and growth your expertise, this is a great (did I mention free?!) event to attend to.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://sharegate.com/deploy-event?ref=codeisahighway.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Deploy: An expert-led online event focused on Microsoft Azure governance - ShareGate</div><div class="kg-bookmark-description">Deploy is a virtual event where experts share their experiences and insights to help you optimize your Azure environment. Join us to learn Azure governance best practices.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://sharegate.com/app/themes/sharegate/img/favicons/ShareGate_Favicon_192X192.png" alt="2020-05-07: ShareGate Deploy Azure online event"><span class="kg-bookmark-author">ShareGate</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://sharegate.com/app/uploads/2020/03/deploy-og2x-1024x536.png" alt="2020-05-07: ShareGate Deploy Azure online event"></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Azure Policy essentials webinar resources]]></title><description><![CDATA[<p>I had the pleasure to co-host a webinar with Jussi Roine around Azure Policy and governance in Azure at the end of March 2020 for ShareGate. It was a good event and we had a lot of registrations but if you missed it, or would like a chance to listen</p>]]></description><link>https://codeisahighway.com/azure-policy-essentials-webinar-resources/</link><guid isPermaLink="false">64ad86e191f3ba000186594e</guid><category><![CDATA[Microsoft Azure]]></category><category><![CDATA[Governance]]></category><category><![CDATA[Best Practices]]></category><category><![CDATA[Azure Policy]]></category><category><![CDATA[Azure ARC]]></category><category><![CDATA[Management Groups]]></category><category><![CDATA[Azure Blueprints]]></category><category><![CDATA[Community]]></category><category><![CDATA[ShareGate]]></category><dc:creator><![CDATA[Stephane Lapointe]]></dc:creator><pubDate>Tue, 07 Apr 2020 11:24:04 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1518406432532-9cbef5697723?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1518406432532-9cbef5697723?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Azure Policy essentials webinar resources"><p>I had the pleasure to co-host a webinar with Jussi Roine around Azure Policy and governance in Azure at the end of March 2020 for ShareGate. It was a good event and we had a lot of registrations but if you missed it, or would like a chance to listen to it again or get the highlights of this event, follow me.</p><h2 id="video-and-recap-of-highlights">Video and recap of highlights</h2><p>If you missed or want to watch the webinar again, you can do so by going here:</p><p><a href="https://sharegate.com/resource/webinar-azure-policy-governance-best-practices?ref=codeisahighway.com">https://sharegate.com/resource/webinar-azure-policy-governance-best-practices</a></p><p>If you want a recap of highlights of this webinar in a 10-15 minutes readable format, Elle Crosby at ShareGate got you covered here:</p><figure class="kg-card kg-embed-card"><blockquote class="wp-embedded-content"><a href="https://sharegate.com/blog/azure-policy-essentials-highlights?ref=codeisahighway.com">Azure Policy essentials: Highlights from our expert-led webinar</a></blockquote>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
		!function(d,l){"use strict";var e=!1,o=!1;if(l.querySelector)if(d.addEventListener)e=!0;if(d.wp=d.wp||{},!d.wp.receiveEmbedMessage)if(d.wp.receiveEmbedMessage=function(e){var t=e.data;if(t)if(t.secret||t.message||t.value)if(!/[^a-zA-Z0-9]/.test(t.secret)){var r,a,i,s,n,o=l.querySelectorAll('iframe[data-secret="'+t.secret+'"]'),c=l.querySelectorAll('blockquote[data-secret="'+t.secret+'"]');for(r=0;r<c.length;r++)c[r].style.display="none";for(r=0;r<o.length;r++)if(a=o[r],e.source===a.contentWindow){if(a.removeAttribute("style"),"height"===t.message){if(1e3<(i=parseInt(t.value,10)))i=1e3;else if(~~i<200)i=200;a.height=i}if("link"===t.message)if(s=l.createElement("a"),n=l.createElement("a"),s.href=a.getAttribute("src"),n.href=t.value,n.host===s.host)if(l.activeElement===a)d.top.location.href=t.value}}},e)d.addEventListener("message",d.wp.receiveEmbedMessage,!1),l.addEventListener("DOMContentLoaded",t,!1),d.addEventListener("load",t,!1);function t(){if(!o){o=!0;var e,t,r,a,i=-1!==navigator.appVersion.indexOf("MSIE 10"),s=!!navigator.userAgent.match(/Trident.*rv:11\./),n=l.querySelectorAll("iframe.wp-embedded-content");for(t=0;t<n.length;t++){if(!(r=n[t]).getAttribute("data-secret"))a=Math.random().toString(36).substr(2,10),r.src+="#?secret="+a,r.setAttribute("data-secret",a);if(i||s)(e=r.cloneNode(!0)).removeAttribute("security"),r.parentNode.replaceChild(e,r)}}}}(window,document);
//--><!]]]]><![CDATA[>
</script><iframe sandbox="allow-scripts" security="restricted" src="https://sharegate.com/blog/azure-policy-essentials-highlights/embed" width="600" height="338" title="&#x201C;Azure Policy essentials: Highlights from our expert-led webinar&#x201D; &#x2014; ShareGate" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe></figure><h2 id="interested-by-governance-in-azure">Interested by Governance in Azure?</h2><p>We&apos;ll hold a full day online conference THURSDAY, MAY 7 2020 | 9AM-5PM ET around governance and best practices in Azure for a total of 8 great sessions. It is called <strong>Deploy</strong>, it&apos;s a free event and you can reserve your seat here: </p><p><a href="https://sharegate.com/deploy-event?ref=codeisahighway.com">https://sharegate.com/deploy-event</a></p>]]></content:encoded></item></channel></rss>