Skip to content

Commit

Permalink
Fixes conditional secret as parameter or placeholder Azure#2054 (Azur…
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Oct 12, 2024
1 parent ddeb333 commit d6471e6
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 1 deletion.
2 changes: 2 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ What's changed since pre-release v1.39.0:
[#3062](https://github.com/Azure/PSRule.Rules.Azure/issues/3062)
- Fixed `Azure.AppGw.AvailabilityZone` passes when a zonal configuration is used by @BernieWhite.
[#3061](https://github.com/Azure/PSRule.Rules.Azure/issues/3061)
- Fixed conditional secret as parameter or placeholder by @BernieWhite.
[#2054](https://github.com/Azure/PSRule.Rules.Azure/issues/2054)

## v1.39.0

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/2054

param prefix string = 'super'
param deployed bool = true

resource vault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
name: 'vault1'
}

module withSecret 'Tests.Bicep.1.child.bicep' = {
name: 'withSecret'
params: {
name: '1'
secret: deployed ? vault.getSecret('${prefix}secret1') : 'placeholder'
}
}

module withPlaceholder 'Tests.Bicep.1.child.bicep' = {
name: 'withPlaceholder'
params: {
name: '2'
secret: !deployed ? vault.getSecret('${prefix}secret1') : 'placeholder'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

param name string

@secure()
param secret string

resource secretToSet 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = {
name: 'vault1/toSet${name}'
properties: {
value: secret
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "6760857410189558623"
}
},
"parameters": {
"prefix": {
"type": "string",
"defaultValue": "super"
},
"deployed": {
"type": "bool",
"defaultValue": true
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "withSecret",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"name": {
"value": "1"
},
"secret": "[if(parameters('deployed'), createObject('reference', createObject('keyVault', createObject('id', resourceId('Microsoft.KeyVault/vaults', 'vault1')), 'secretName', format('{0}secret1', parameters('prefix')))), createObject('value', 'placeholder'))]"
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "15661998235342522313"
}
},
"parameters": {
"name": {
"type": "string"
},
"secret": {
"type": "securestring"
}
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2022-07-01",
"name": "[format('vault1/toSet{0}', parameters('name'))]",
"properties": {
"value": "[parameters('secret')]"
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "withPlaceholder",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"name": {
"value": "2"
},
"secret": "[if(not(parameters('deployed')), createObject('reference', createObject('keyVault', createObject('id', resourceId('Microsoft.KeyVault/vaults', 'vault1')), 'secretName', format('{0}secret1', parameters('prefix')))), createObject('value', 'placeholder'))]"
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "15661998235342522313"
}
},
"parameters": {
"name": {
"type": "string"
},
"secret": {
"type": "securestring"
}
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2022-07-01",
"name": "[format('vault1/toSet{0}', parameters('name'))]",
"properties": {
"value": "[parameters('secret')]"
}
}
]
}
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@
<None Update="Bicep\ExtensibilityTestCases\Tests.Bicep.1.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Bicep\SecretTestCases\Tests.Bicep.1.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
21 changes: 20 additions & 1 deletion tests/PSRule.Rules.Azure.Tests/TemplateVisitorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,7 @@ public void ProcessTemplate_WhenConditionalExistingReference_IgnoresExpand()
}

[Fact]
public void ProcessTemplate_WhenParented_ScopeIsExpected()
public void ProcessTemplate_WhenParented_ShouldReturnExpectedScope()
{
var resources = ProcessTemplate(GetSourcePath("sql.tests.json"), null, out _);

Expand Down Expand Up @@ -1366,6 +1366,25 @@ public void ProcessTemplate_WhenMicrosoftGraphType_ShouldIgnoreExtensibilityReso
Assert.Equal("ps-rule-test-deployment", actual["name"].Value<string>());
}

/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/2054
/// </summary>
[Fact]
public void ProcessTemplate_WhenConditionalSecretParameter_ShouldReturnSecretsPlaceholders()
{
var resources = ProcessTemplate(GetSourcePath("Bicep/SecretTestCases/Tests.Bicep.1.json"), null, out _);

Assert.NotNull(resources);

var actual = resources.Where(r => r["name"].Value<string>() == "vault1/toSet1").FirstOrDefault();
Assert.Equal("Microsoft.KeyVault/vaults/secrets", actual["type"].Value<string>());
Assert.Equal("{{SecretReference:supersecret1}}", actual["properties"]["value"].Value<string>());

actual = resources.Where(r => r["name"].Value<string>() == "vault1/toSet2").FirstOrDefault();
Assert.Equal("Microsoft.KeyVault/vaults/secrets", actual["type"].Value<string>());
Assert.Equal("placeholder", actual["properties"]["value"].Value<string>());
}

#region Helper methods

private static string GetSourcePath(string fileName)
Expand Down

0 comments on commit d6471e6

Please sign in to comment.