Skip to content

Commit

Permalink
Ensure unique bicep names for role assignments and expose principalTy…
Browse files Browse the repository at this point in the history
…pe parameter (#42326)

* Ensure unique bicep names for role assignments and expose principalType parameter

* ref docs
  • Loading branch information
JoshLove-msft authored Mar 1, 2024
1 parent 344ae86 commit 5193809
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ protected Resource(Azure.Provisioning.IConstruct scope, Azure.Provisioning.Resou
public string Version { get { throw null; } }
protected virtual Azure.Provisioning.Resource? FindParentInScope(Azure.Provisioning.IConstruct scope) { throw null; }
protected virtual string GetAzureName(Azure.Provisioning.IConstruct scope, string resourceName) { throw null; }
protected virtual string GetBicepName(Azure.Provisioning.Resource resource) { throw null; }
protected virtual bool NeedsParent() { throw null; }
protected virtual bool NeedsScope() { throw null; }
Azure.Provisioning.Resource System.ClientModel.Primitives.IPersistableModel<Azure.Provisioning.Resource>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
Expand Down Expand Up @@ -157,11 +158,12 @@ namespace Azure.Provisioning.Authorization
{
public static partial class AuthorizationExtensions
{
public static Azure.Provisioning.Authorization.RoleAssignment AssignRole(this Azure.Provisioning.Resource resource, Azure.Provisioning.Authorization.RoleDefinition roleDefinition, System.Guid? principalId = default(System.Guid?)) { throw null; }
public static Azure.Provisioning.Authorization.RoleAssignment AssignRole(this Azure.Provisioning.Resource resource, Azure.Provisioning.Authorization.RoleDefinition roleDefinition, System.Guid? principalId = default(System.Guid?), Azure.ResourceManager.Authorization.Models.RoleManagementPrincipalType? principalType = default(Azure.ResourceManager.Authorization.Models.RoleManagementPrincipalType?)) { throw null; }
}
public partial class RoleAssignment : Azure.Provisioning.Resource<Azure.ResourceManager.Authorization.RoleAssignmentData>
{
internal RoleAssignment() : base (default(Azure.Provisioning.IConstruct), default(Azure.Provisioning.Resource), default(string), default(Azure.Core.ResourceType), default(string), default(System.Func<string, Azure.ResourceManager.Authorization.RoleAssignmentData>)) { }
protected override string GetBicepName(Azure.Provisioning.Resource resource) { throw null; }
protected override bool NeedsParent() { throw null; }
protected override bool NeedsScope() { throw null; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ protected Resource(Azure.Provisioning.IConstruct scope, Azure.Provisioning.Resou
public string Version { get { throw null; } }
protected virtual Azure.Provisioning.Resource? FindParentInScope(Azure.Provisioning.IConstruct scope) { throw null; }
protected virtual string GetAzureName(Azure.Provisioning.IConstruct scope, string resourceName) { throw null; }
protected virtual string GetBicepName(Azure.Provisioning.Resource resource) { throw null; }
protected virtual bool NeedsParent() { throw null; }
protected virtual bool NeedsScope() { throw null; }
Azure.Provisioning.Resource System.ClientModel.Primitives.IPersistableModel<Azure.Provisioning.Resource>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
Expand Down Expand Up @@ -157,11 +158,12 @@ namespace Azure.Provisioning.Authorization
{
public static partial class AuthorizationExtensions
{
public static Azure.Provisioning.Authorization.RoleAssignment AssignRole(this Azure.Provisioning.Resource resource, Azure.Provisioning.Authorization.RoleDefinition roleDefinition, System.Guid? principalId = default(System.Guid?)) { throw null; }
public static Azure.Provisioning.Authorization.RoleAssignment AssignRole(this Azure.Provisioning.Resource resource, Azure.Provisioning.Authorization.RoleDefinition roleDefinition, System.Guid? principalId = default(System.Guid?), Azure.ResourceManager.Authorization.Models.RoleManagementPrincipalType? principalType = default(Azure.ResourceManager.Authorization.Models.RoleManagementPrincipalType?)) { throw null; }
}
public partial class RoleAssignment : Azure.Provisioning.Resource<Azure.ResourceManager.Authorization.RoleAssignmentData>
{
internal RoleAssignment() : base (default(Azure.Provisioning.IConstruct), default(Azure.Provisioning.Resource), default(string), default(Azure.Core.ResourceType), default(string), default(System.Func<string, Azure.ResourceManager.Authorization.RoleAssignmentData>)) { }
protected override string GetBicepName(Azure.Provisioning.Resource resource) { throw null; }
protected override bool NeedsParent() { throw null; }
protected override bool NeedsScope() { throw null; }
}
Expand Down
12 changes: 9 additions & 3 deletions sdk/provisioning/Azure.Provisioning/src/Resource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,19 @@ private string GetAlphaNumeric(string base64Hash, int chars)
return sb.ToString();
}

private static string GetScopedName(Resource resource, string scopedName)
private string GetScopedName(Resource resource, string scopedName)
{
Resource? parent = resource.Parent;

return parent is null || parent is Tenant ? scopedName : GetScopedName(parent, $"{parent.Id.Name}_{scopedName}");
return parent is null || parent is Tenant ? scopedName : GetScopedName(parent, $"{GetBicepName(parent)}_{scopedName}");
}

/// <summary>
/// Gets the name of the resource for Bicep.
/// </summary>
/// <param name="resource">The resource.</param>
/// <returns>The name to use for Bicep</returns>
protected virtual string GetBicepName(Resource resource) => resource.Id.Name;

string IPersistableModel<Resource>.GetFormatFromOptions(ModelReaderWriterOptions options) => "bicep";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using Azure.ResourceManager.Authorization.Models;

namespace Azure.Provisioning.Authorization
{
Expand All @@ -15,10 +16,15 @@ public static class AuthorizationExtensions
/// </summary>
/// <param name="resource">The resource.</param>
/// <param name="roleDefinition">The role definition.</param>
/// <param name="principalId">The principal ID.</param>
public static RoleAssignment AssignRole(this Resource resource, RoleDefinition roleDefinition, Guid? principalId = default)
/// <param name="principalId">The principal ID. If not specified, a principalId parameter will be added to the resulting bicep module.</param>
/// <param name="principalType">The principal type. If not specified, ServicePrincipal is used.</param>
public static RoleAssignment AssignRole(
this Resource resource,
RoleDefinition roleDefinition,
Guid? principalId = default,
RoleManagementPrincipalType? principalType = default)
{
return new RoleAssignment(resource, roleDefinition, principalId);
return new RoleAssignment(resource, roleDefinition, principalId, principalType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,20 @@ public class RoleAssignment : Resource<RoleAssignmentData>
internal RoleAssignment(
Resource resource,
RoleDefinition roleDefinition,
Guid? principalId = default)
Guid? principalId = default,
RoleManagementPrincipalType? principalType = default)
: base(
resource.Scope,
resource,
// will be overriden
resource.Name,
ResourceType,
"2022-04-01",
(name) => ArmAuthorizationModelFactory.RoleAssignmentData(
name: name,
principalId: principalId))
principalId: principalId,
roleDefinitionId: ResourceIdentifier.Parse($"/providers/{RoleDefinitionResourceType}/{roleDefinition}"),
principalType: principalType ?? RoleManagementPrincipalType.ServicePrincipal))
{
if (resource.Scope.Configuration?.UseInteractiveMode != true && principalId == null)
{
Expand All @@ -44,16 +48,24 @@ internal RoleAssignment(

AssignProperty(
data => data.Name,
$"guid('{resource.Name}', {(principalId == null ? "principalId" : "'" + principalId + "'")}," +
$" {SubscriptionResourceIdFunction}({(resource.Scope.Configuration?.UseInteractiveMode != true ? "'" + Id.SubscriptionId + "', ": string.Empty)}" +
$"'{RoleDefinitionResourceType}', '{roleDefinition}'))");
GetBicepName(resource));

AssignProperty(
data => data.RoleDefinitionId,
$"{SubscriptionResourceIdFunction}({(resource.Scope.Configuration?.UseInteractiveMode != true ? "'"+ Id.SubscriptionId + "', ": string.Empty)}" +
$"'{RoleDefinitionResourceType}', '{roleDefinition}')");
}

/// <inheritdoc />
protected override string GetBicepName(Resource resource)
{
var data = (RoleAssignmentData)ResourceData;
return
$"guid('{resource.Name}', {(data.PrincipalId == null ? "principalId" : "'" + data.PrincipalId + "'")}," +
$" {SubscriptionResourceIdFunction}({(resource.Scope.Configuration?.UseInteractiveMode != true ? "'" + Id.SubscriptionId + "', " : string.Empty)}" +
$"'{RoleDefinitionResourceType}', '{data.RoleDefinitionId.Name}'))";
}

/// <inheritdoc />
protected override bool NeedsScope() => true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,32 @@ resource blobService_lnEDXlX5c 'Microsoft.Storage/storageAccounts/blobServices@2
}
}

resource roleAssignment_ZBWGKDk4O 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
resource roleAssignment_MDGXC4QYi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_YRiDhR43q
name: guid('storageAccount_YRiDhR43q', principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')
principalId: principalId
principalType: 'ServicePrincipal'
}
}

resource roleAssignment_4qiHESxvp 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_YRiDhR43q
name: guid('storageAccount_YRiDhR43q', principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')
principalId: principalId
principalType: 'ServicePrincipal'
}
}

resource roleAssignment_eQvFjtjRE 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_YRiDhR43q
name: guid('storageAccount_YRiDhR43q', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'User'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,32 @@ resource blobService_NVMDcYVF9 'Microsoft.Storage/storageAccounts/blobServices@2
}
}

resource roleAssignment_lDOSGTMrV 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
resource roleAssignment_SI6hy0Shx 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_melvnlpF2
name: guid('storageAccount_melvnlpF2', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('00000000-0000-0000-0000-000000000000', 'Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'))
properties: {
roleDefinitionId: subscriptionResourceId('00000000-0000-0000-0000-000000000000', 'Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'ServicePrincipal'
}
}

resource roleAssignment_FiYmmG8xx 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_melvnlpF2
name: guid('storageAccount_melvnlpF2', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('00000000-0000-0000-0000-000000000000', 'Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88'))
properties: {
roleDefinitionId: subscriptionResourceId('00000000-0000-0000-0000-000000000000', 'Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'ServicePrincipal'
}
}

resource roleAssignment_cl79LHWP1 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_melvnlpF2
name: guid('storageAccount_melvnlpF2', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('00000000-0000-0000-0000-000000000000', 'Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'))
properties: {
roleDefinitionId: subscriptionResourceId('00000000-0000-0000-0000-000000000000', 'Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'User'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,32 @@ resource blobService_lnEDXlX5c 'Microsoft.Storage/storageAccounts/blobServices@2
}
}

resource roleAssignment_ZBWGKDk4O 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
resource roleAssignment_S6jH5ugdS 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_YRiDhR43q
name: guid('storageAccount_YRiDhR43q', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'ServicePrincipal'
}
}

resource roleAssignment_7MQXhfyRx 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_YRiDhR43q
name: guid('storageAccount_YRiDhR43q', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'ServicePrincipal'
}
}

resource roleAssignment_eQvFjtjRE 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount_YRiDhR43q
name: guid('storageAccount_YRiDhR43q', '00000000-0000-0000-0000-000000000000', subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')
principalId: '00000000-0000-0000-0000-000000000000'
principalType: 'User'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Azure.Provisioning.AppConfiguration;
using Azure.Provisioning.Authorization;
using Azure.ResourceManager;
using Azure.ResourceManager.Authorization.Models;
using Azure.ResourceManager.Resources;
using Azure.ResourceManager.Resources.Models;
using Azure.ResourceManager.Storage.Models;
Expand Down Expand Up @@ -217,6 +218,8 @@ public async Task RoleAssignmentWithParameter()
var storageAccount = infra.AddStorageAccount(name: "photoAcct", sku: StorageSkuName.PremiumLrs, kind: StorageKind.BlockBlobStorage);
infra.AddBlobService();
storageAccount.AssignRole(RoleDefinition.StorageBlobDataContributor);
storageAccount.AssignRole(RoleDefinition.StorageQueueDataContributor);
storageAccount.AssignRole(RoleDefinition.StorageTableDataContributor, Guid.Empty, RoleManagementPrincipalType.User);
infra.Build(GetOutputPath());

await ValidateBicepAsync(BinaryData.FromObjectAsJson(new { principalId = new { value = Guid.Empty }}), interactiveMode: true);
Expand All @@ -229,6 +232,8 @@ public async Task RoleAssignmentWithoutParameter()
var storageAccount = infra.AddStorageAccount(name: "photoAcct", sku: StorageSkuName.PremiumLrs, kind: StorageKind.BlockBlobStorage);
infra.AddBlobService();
storageAccount.AssignRole(RoleDefinition.StorageBlobDataContributor, Guid.Empty);
storageAccount.AssignRole(RoleDefinition.StorageQueueDataContributor, Guid.Empty);
storageAccount.AssignRole(RoleDefinition.StorageTableDataContributor, Guid.Empty, RoleManagementPrincipalType.User);
infra.Build(GetOutputPath());

await ValidateBicepAsync();
Expand All @@ -241,6 +246,8 @@ public async Task RoleAssignmentWithoutParameterInteractiveMode()
var storageAccount = infra.AddStorageAccount(name: "photoAcct", sku: StorageSkuName.PremiumLrs, kind: StorageKind.BlockBlobStorage);
infra.AddBlobService();
storageAccount.AssignRole(RoleDefinition.StorageBlobDataContributor, Guid.Empty);
storageAccount.AssignRole(RoleDefinition.StorageQueueDataContributor, Guid.Empty);
storageAccount.AssignRole(RoleDefinition.StorageTableDataContributor, Guid.Empty, RoleManagementPrincipalType.User);
infra.Build(GetOutputPath());

await ValidateBicepAsync(interactiveMode: true);
Expand Down

0 comments on commit 5193809

Please sign in to comment.