{"id":611,"date":"2021-11-16T02:04:13","date_gmt":"2021-11-16T02:04:13","guid":{"rendered":"https:\/\/thecloudmarathoner.com\/?p=611"},"modified":"2021-11-16T13:55:20","modified_gmt":"2021-11-16T13:55:20","slug":"managing-azure-bicep-sensitive-info-with-key-vault","status":"publish","type":"post","link":"https:\/\/thecloudmarathoner.com\/index.php\/2021\/11\/16\/managing-azure-bicep-sensitive-info-with-key-vault\/","title":{"rendered":"What are the good options to manage sensitive info in Azure Bicep?"},"content":{"rendered":"\n<p>Hello Cloud Marathoners,<\/p>\n\n\n\n<p>Every seasoned IT professional knows that sensitive information should not be exposed as a clear text on any code. This is especially true for infrastructure-as-code (aka, IaC) scenarios where passwords and keys are part of the deployment. <\/p>\n\n\n\n<p>One way to stay compliant in accomplishing this goal is the integration of an Azure Key Vault service into your deployment code. This Azure security service is primarily intended to store sensitive information like password, keys, certificates, connections, etc. <\/p>\n\n\n\n<p>In this post, we will look into two different ways how we could integrate Azure Key Vault services in our Azure Bicep code.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"539\" src=\"\/wp-content\/uploads\/2021\/11\/image-3-1024x539.png\" alt=\"\" class=\"wp-image-703\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-3-1024x539.png 1024w, \/wp-content\/uploads\/2021\/11\/image-3-300x158.png 300w, \/wp-content\/uploads\/2021\/11\/image-3-768x405.png 768w, \/wp-content\/uploads\/2021\/11\/image-3-1200x632.png 1200w, \/wp-content\/uploads\/2021\/11\/image-3.png 1490w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><br>Option &#8211; 1: Using getSecret() function  <\/h3>\n\n\n\n<p>Our first option is to delegate this important work to a <code>getSecret()<\/code> function. This option could be used with an existing Azure Key Vault resource that is declared in your Azure Bicep code.<\/p>\n\n\n\n<p>Let&#8217;s look into an example where an existing Azure Key Vault service is referenced to provide administrative password for SQL server deployment. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"901\" height=\"913\" src=\"\/wp-content\/uploads\/2021\/11\/image-4.png\" alt=\"\" class=\"wp-image-708\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-4.png 901w, \/wp-content\/uploads\/2021\/11\/image-4-296x300.png 296w, \/wp-content\/uploads\/2021\/11\/image-4-768x778.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Deploying Azure SQL instance with Azure Key Vault<\/figcaption><\/figure>\n\n\n\n<p>This sample Bicep code is using sqldb.bicep file as a module, where parameters; such as <code>sqlServerName <\/code>and <code>adminLogin<\/code> are passed through with a secret name of  <code>ExamplePassword<\/code>.<\/p>\n\n\n\n<p>The  <code>ExamplePassword<\/code> secret name should be already set and ready in the referenced Key Vault service above. Here is the view of this secret on Azure portal.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"453\" src=\"\/wp-content\/uploads\/2021\/11\/image-5-1024x453.png\" alt=\"\" class=\"wp-image-709\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-5-1024x453.png 1024w, \/wp-content\/uploads\/2021\/11\/image-5-300x133.png 300w, \/wp-content\/uploads\/2021\/11\/image-5-768x340.png 768w, \/wp-content\/uploads\/2021\/11\/image-5.png 1180w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Azure Key Vault with secretes in portal<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Let&#8217;s have a quick view into the <code>sqldb.bicep<\/code> file, as it is referenced&nbsp;in the main Bicep file.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"766\" height=\"916\" src=\"\/wp-content\/uploads\/2021\/11\/image-6.png\" alt=\"\" class=\"wp-image-710\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-6.png 766w, \/wp-content\/uploads\/2021\/11\/image-6-251x300.png 251w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption>sqldb.bicep file<\/figcaption><\/figure>\n\n\n\n<p>Now, let&#8217;s deploy these resources with a secret value from Key Vault resource that has a secret name <code>ExamplePassword<\/code>. <br><br>What happened? I am getting an error on my first deployment execution \ud83d\ude41<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"494\" src=\"\/wp-content\/uploads\/2021\/11\/image-8-1024x494.png\" alt=\"\" class=\"wp-image-712\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-8-1024x494.png 1024w, \/wp-content\/uploads\/2021\/11\/image-8-300x145.png 300w, \/wp-content\/uploads\/2021\/11\/image-8-768x370.png 768w, \/wp-content\/uploads\/2021\/11\/image-8-1200x579.png 1200w, \/wp-content\/uploads\/2021\/11\/image-8.png 1360w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Error on deploying Bicep code with SQL server provisioning<\/figcaption><\/figure>\n\n\n\n<p>Upon carefully analyzing error, I see the following reason for this error: <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>At least one resource deployment operation failed. Please list deployment operations for details. Please see https:\/\/aka.ms\/DeployOperations for usage details.&#8221;,&#8221;details&#8221;:[{&#8220;code&#8221;:&#8221;RegionDoesNotAllowProvisioning&#8221;,&#8221;message&#8221;:&#8221;Location &#8216;East US 2&#8217; is not accepting creation of new Windows Azure SQL Database servers at this time.<\/p><cite>Azure deployment error<\/cite><\/blockquote>\n\n\n\n<p>Based on the error message, we change the location to <code>eastus<\/code> and re-run the script. Now, we got the following positive result in console and portal:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"659\" src=\"\/wp-content\/uploads\/2021\/11\/image-10-1024x659.png\" alt=\"\" class=\"wp-image-715\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-10-1024x659.png 1024w, \/wp-content\/uploads\/2021\/11\/image-10-300x193.png 300w, \/wp-content\/uploads\/2021\/11\/image-10-768x494.png 768w, \/wp-content\/uploads\/2021\/11\/image-10.png 1026w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"268\" src=\"\/wp-content\/uploads\/2021\/11\/image-9-1024x268.png\" alt=\"\" class=\"wp-image-714\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-9-1024x268.png 1024w, \/wp-content\/uploads\/2021\/11\/image-9-300x78.png 300w, \/wp-content\/uploads\/2021\/11\/image-9-768x201.png 768w, \/wp-content\/uploads\/2021\/11\/image-9-1200x314.png 1200w, \/wp-content\/uploads\/2021\/11\/image-9.png 1446w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Deployment results in Azure Portal RG<\/figcaption><\/figure>\n\n\n\n<p>Next, we will attempt to login into a SQL Server instance.<br>A successful login will look like the following screen:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"448\" src=\"\/wp-content\/uploads\/2021\/11\/image-12-1024x448.png\" alt=\"\" class=\"wp-image-717\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-12-1024x448.png 1024w, \/wp-content\/uploads\/2021\/11\/image-12-300x131.png 300w, \/wp-content\/uploads\/2021\/11\/image-12-768x336.png 768w, \/wp-content\/uploads\/2021\/11\/image-12.png 1139w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Successful login into the SQL  instance<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Important Note:<\/strong><\/h3>\n\n\n\n<p>If you are getting an <strong>error <\/strong>during the login then try to check the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>adminLogin <\/code>name is entered correctly<\/li><li>your IP address is added to the SQL server firewall rules<\/li><li>grab a cup of coffee and check back in 5 minutes<\/li><\/ul>\n\n\n\n<p>Description of a typical login error into a SQL server instance is provided below. I checked the firewall rules and made a cup of coffee =&gt; before getting a successful log-in \ud83d\ude42 <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"619\" height=\"587\" src=\"\/wp-content\/uploads\/2021\/11\/image-11.png\" alt=\"\" class=\"wp-image-716\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-11.png 619w, \/wp-content\/uploads\/2021\/11\/image-11-300x284.png 300w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption>Requires your location IP activation <\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Option -2: Referencing as a secretName in parameter<\/h3>\n\n\n\n<p>The second option is pretty straightforward, if you have already used it on ARM template deployments. <\/p>\n\n\n\n<p><strong>Note:<\/strong> Please check out the following post &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/thecloudmarathoner.com\/index.php\/2021\/10\/15\/four-parameterization-options-for-your-azure-bicep-deployments\/\" target=\"_blank\">Four parameterization options for your Azure Bicep deployments<\/a> for detailed information on available options.<\/p>\n\n\n\n<p>We just need to reference Azure Key Vault secret like in the following example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"295\" src=\"\/wp-content\/uploads\/2021\/11\/image-13-1024x295.png\" alt=\"\" class=\"wp-image-722\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-13-1024x295.png 1024w, \/wp-content\/uploads\/2021\/11\/image-13-300x86.png 300w, \/wp-content\/uploads\/2021\/11\/image-13-768x221.png 768w, \/wp-content\/uploads\/2021\/11\/image-13-1536x443.png 1536w, \/wp-content\/uploads\/2021\/11\/image-13-1200x346.png 1200w, \/wp-content\/uploads\/2021\/11\/image-13.png 1710w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n\n\n\n<p>Using a parameter file and referencing the Key Vault <code>secretName<\/code> will do the trick in extracting the value and provisioning your resource.<\/p>\n\n\n\n<p>Let&#8217;s run the bicep file that deploys multiple RGs and an Azure VM that uses <code>VMPassword <\/code>secret.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"77\" src=\"\/wp-content\/uploads\/2021\/11\/image-14-1024x77.png\" alt=\"\" class=\"wp-image-723\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-14-1024x77.png 1024w, \/wp-content\/uploads\/2021\/11\/image-14-300x23.png 300w, \/wp-content\/uploads\/2021\/11\/image-14-768x58.png 768w, \/wp-content\/uploads\/2021\/11\/image-14-1200x91.png 1200w, \/wp-content\/uploads\/2021\/11\/image-14.png 1520w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Running deployment with Bicep parameter file<\/figcaption><\/figure>\n\n\n\n<p>A successful deployment provisions following RG with the VM resources:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"613\" src=\"\/wp-content\/uploads\/2021\/11\/image-15-1024x613.png\" alt=\"\" class=\"wp-image-725\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-15-1024x613.png 1024w, \/wp-content\/uploads\/2021\/11\/image-15-300x180.png 300w, \/wp-content\/uploads\/2021\/11\/image-15-768x460.png 768w, \/wp-content\/uploads\/2021\/11\/image-15.png 1098w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, we should smoke test our deployment by locating the resource group &#8220;rg-demo-vm-1116&#8221; and using deployment parameters to RDP into Windows server:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"589\" src=\"\/wp-content\/uploads\/2021\/11\/image-16-1024x589.png\" alt=\"\" class=\"wp-image-726\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-16-1024x589.png 1024w, \/wp-content\/uploads\/2021\/11\/image-16-300x172.png 300w, \/wp-content\/uploads\/2021\/11\/image-16-768x442.png 768w, \/wp-content\/uploads\/2021\/11\/image-16.png 1167w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Finally, we are able to see that secret and admin user name pair worked as expected <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"532\" src=\"\/wp-content\/uploads\/2021\/11\/image-17-1024x532.png\" alt=\"\" class=\"wp-image-727\" srcset=\"\/wp-content\/uploads\/2021\/11\/image-17-1024x532.png 1024w, \/wp-content\/uploads\/2021\/11\/image-17-300x156.png 300w, \/wp-content\/uploads\/2021\/11\/image-17-768x399.png 768w, \/wp-content\/uploads\/2021\/11\/image-17-1200x623.png 1200w, \/wp-content\/uploads\/2021\/11\/image-17.png 1333w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>Azure VM deployed using Key Vault secret<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Summary<\/h3>\n\n\n\n<p>In this post, we looked into two available options that harden our infrastructure code by removing hard-coded sensitive information and replacing it with Azure Key Vault reference. Thus, avoiding any potential leaks of passwords, secrets, etc. <\/p>\n\n\n\n<p>IMHO, first option is better than the later one, because it does not expose subscription id and other small details. <br><br>What will be your choice? Please, share on <a rel=\"noreferrer noopener\" href=\"https:\/\/www.linkedin.com\/posts\/elkhanyusubov_managing-azure-bicep-sensitive-info-with-activity-6866227619445161984-4wQR\" target=\"_blank\">LinkedIn post comments<\/a> section. <\/p>\n\n\n\n<p>Thank you for your interest my #cloudmarathoner friends! <br>Please, check other <a rel=\"noreferrer noopener\" href=\"https:\/\/thecloudmarathoner.com\/index.php\/category\/azure-bicep\/\" target=\"_blank\">Azure Bicep posts<\/a> and let me know your feedback.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What is next?<\/h3>\n\n\n\n<p>All code samples and presented Bicep files are placed in &#8220;Learn-Bicep&#8221; GitHub repo \ud83d\udc49&nbsp;<a href=\"https:\/\/lnkd.in\/ds-h9VQx\">https:\/\/lnkd.in\/ds-h9VQx<\/a><br><br>Please, join me to learn more about Azure Bicep \ud83d\udcaa on an <a rel=\"noreferrer noopener\" href=\"https:\/\/www.meetup.com\/Omaha-Azure-User-Group\/events\/281869944\/\" target=\"_blank\">Omaha Azure User Group meetup<\/a> scheduled to happen on November 17th.<\/p>\n<div class=\"pvc_clear\"><\/div><p id=\"pvc_stats_611\" class=\"pvc_stats all  \" data-element-id=\"611\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>Hello Cloud Marathoners, Every seasoned IT professional knows that sensitive information should not be exposed as a clear text on any code. This is especially true for infrastructure-as-code (aka, IaC) scenarios where passwords and keys are part of the deployment. One way to stay compliant in accomplishing this goal is the integration of an Azure &hellip; <a href=\"https:\/\/thecloudmarathoner.com\/index.php\/2021\/11\/16\/managing-azure-bicep-sensitive-info-with-key-vault\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;What are the good options to manage sensitive info in Azure Bicep?&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25,4,2,18],"tags":[],"class_list":["post-611","post","type-post","status-publish","format-standard","hentry","category-azure-bicep","category-azure-devops","category-infrastructure-as-code-iac","category-azure"],"_links":{"self":[{"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/posts\/611","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/comments?post=611"}],"version-history":[{"count":20,"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/posts\/611\/revisions"}],"predecessor-version":[{"id":739,"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/posts\/611\/revisions\/739"}],"wp:attachment":[{"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/media?parent=611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/categories?post=611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecloudmarathoner.com\/index.php\/wp-json\/wp\/v2\/tags?post=611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}