Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support deploying Azure resources with parameters file described with the Bicep language #21567

Merged
merged 9 commits into from
Apr 20, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
using Microsoft.Azure.Management.ResourceManager;
using Microsoft.Azure.Management.ResourceManager.Models;
using Microsoft.WindowsAzure.Commands.Utilities.Common;

using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Linq;

using System;
Expand Down Expand Up @@ -191,9 +191,19 @@ protected override void OnBeginProcessing()
throw new NotSupportedException($"'-TemplateUri {TemplateUri}' is not supported. Please download the bicep file and pass it using -TemplateFile.");
}

if (BicepUtility.IsBicepparamFile(TemplateParameterFile) && !BicepUtility.IsBicepFile(TemplateFile))
{
throw new NotSupportedException($"Bicepparam file {TemplateParameterFile} is only supported with a Bicep template file");
}

if (BicepUtility.IsBicepFile(TemplateFile))
{
BuildAndUseBicepTemplate();

if (BicepUtility.IsBicepparamFile(TemplateParameterFile))
BuildAndUseBicepParameters();
}

if (!this.IsParameterBound(c => c.SkipTemplateParameterPrompt))
{
// Resolve the static parameter names for this cmdlet:
Expand Down Expand Up @@ -460,5 +470,10 @@ protected void BuildAndUseBicepTemplate()
{
TemplateFile = BicepUtility.BuildFile(this.ResolvePath(TemplateFile), this.WriteVerbose, this.WriteWarning);
}

protected void BuildAndUseBicepParameters()
{
TemplateParameterFile = BicepUtility.BuildParamFile(this.ResolvePath(TemplateParameterFile), this.WriteVerbose, this.WriteWarning);
}
}
}
18 changes: 18 additions & 0 deletions src/Resources/ResourceManager/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/Resources/ResourceManager/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -512,4 +512,10 @@ You can help us improve the accuracy of the result by opening an issue here: htt
<data name="BuildBicepFileToJsonFailed" xml:space="preserve">
<value>Build bicep file '{0}' to json failed.</value>
</data>
<data name="InvalidBicepparamFilePath" xml:space="preserve">
<value>Invalid Bicepparam file path.</value>
</data>
<data name="BuildBicepparamFileToJsonFailed" xml:space="preserve">
<value>Build bicepparam file '{0}' to json failed.</value>
</data>
</root>
26 changes: 26 additions & 0 deletions src/Resources/ResourceManager/Utilities/BicepUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,16 @@ internal static class BicepUtility

private const string MinimalVersionRequirementForBicepPublishWithOptionalDocumentationUriParameter = "0.14.46";

private const string MinimalVersionRequirementForBicepparamFileBuild = "0.16.1";

public delegate void OutputCallback(string msg);

public static bool IsBicepFile(string templateFilePath) =>
".bicep".Equals(Path.GetExtension(templateFilePath), StringComparison.OrdinalIgnoreCase);

public static bool IsBicepparamFile(string parametersFilePath) =>
".bicepparam".Equals(Path.GetExtension(parametersFilePath), StringComparison.OrdinalIgnoreCase);

public static string BuildFile(string bicepTemplateFilePath, OutputCallback writeVerbose = null, OutputCallback writeWarning = null)
{
if (!FileUtilities.DataStore.FileExists(bicepTemplateFilePath))
Expand All @@ -58,6 +63,27 @@ public static string BuildFile(string bicepTemplateFilePath, OutputCallback writ
return buildResultPath;
}

public static string BuildParamFile(string bicepParamFilePath, OutputCallback writeVerbose = null, OutputCallback writeWarning = null)
{
if (!FileUtilities.DataStore.FileExists(bicepParamFilePath))
{
throw new AzPSArgumentException(Properties.Resources.InvalidBicepparamFilePath, "TemplateParameterFile");
}

string tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDirectory);

string buildResultPath = Path.Combine(tempDirectory, Path.GetFileName(bicepParamFilePath)).Replace(".bicepparam", ".json");
RunBicepCommand($"bicep build-params '{bicepParamFilePath}' --outfile '{buildResultPath}'", MinimalVersionRequirementForBicepparamFileBuild, writeVerbose, writeWarning);

if (!FileUtilities.DataStore.FileExists(buildResultPath))
{
throw new AzPSApplicationException(string.Format(Properties.Resources.BuildBicepparamFileToJsonFailed, bicepParamFilePath));
}

return buildResultPath;
}

public static void PublishFile(string bicepFilePath, string target, string documentationUri = null, OutputCallback writeVerbose = null, OutputCallback writeWarning = null)
{
if (!FileUtilities.DataStore.FileExists(bicepFilePath))
Expand Down
1 change: 1 addition & 0 deletions src/Resources/Resources.Test/Resources.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<None Update="Resources\*.json" CopyToOutputDirectory="PreserveNewest" />
<None Update="*.json" CopyToOutputDirectory="PreserveNewest" />
<None Update="*.bicep" CopyToOutputDirectory="PreserveNewest" />
<None Update="*.bicepparam" CopyToOutputDirectory="PreserveNewest" />
<None Update="ScenarioTests\*.pfx" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Expand Down
7 changes: 7 additions & 0 deletions src/Resources/Resources.Test/ScenarioTests/DeploymentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ public void TestTestDeploymentFromBicepFile()
TestRunner.RunTestScript("Test-TestDeploymentFromBicepFile");
}

[Fact]
[Trait(Category.AcceptanceType, Category.LiveOnly)]
public void TestNewDeploymentFromBicepFileAndBicepparamFile()
{
TestRunner.RunTestScript("Test-NewDeploymentFromBicepFileAndBicepparamFile");
}

//Please make sure to re-record this test if any changes are made to WhatIf, QueryString or ResourceGroupDeployments
[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
Expand Down
35 changes: 34 additions & 1 deletion src/Resources/Resources.Test/ScenarioTests/DeploymentTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ function Test-TestDeploymentFromBicepFile
New-AzResourceGroup -Name $rgname -Location $location

$list = Test-AzResourceGroupDeployment -ResourceGroupName $rgname -TemplateFile sampleDeploymentBicepFile.bicep

# Assert
Assert-AreEqual 0 @($list).Count
}
Expand All @@ -854,6 +854,39 @@ function Test-TestDeploymentFromBicepFile
}
}

<#
.SYNOPSIS
Tests deployment via Bicep file.
#>
function Test-NewDeploymentFromBicepFileAndBicepparamFile
{
# Setup
$rgname = Get-ResourceGroupName
$rname = Get-ResourceName
$rglocation = "West US 2"

try
{
# Test
New-AzResourceGroup -Name $rgname -Location $rglocation

$deployment = New-AzResourceGroupDeployment -Name $rname -ResourceGroupName $rgname -TemplateFile sampleDeploymentBicepFileWithoutParamValues.bicep -TemplateParameterFile sampleDeploymentBicepFileParams.bicepparam

# Assert
Assert-AreEqual Succeeded $deployment.ProvisioningState

$subId = (Get-AzContext).Subscription.SubscriptionId
$deploymentId = "/subscriptions/$subId/resourcegroups/$rgname/providers/Microsoft.Resources/deployments/$rname"
$getById = Get-AzResourceGroupDeployment -Id $deploymentId
Assert-AreEqual $getById.DeploymentName $deployment.DeploymentName
}
finally
{
# Cleanup
Clean-ResourceGroup $rgname
}
}

<#
.SYNOPSIS
is running live in target environment
Expand Down
Loading