-
Notifications
You must be signed in to change notification settings - Fork 128
Enhance Dapr integration with managed identity support and role assig… #882
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
base: main
Are you sure you want to change the base?
Changes from all commits
2f894c5
8b0e34f
db4d465
d6f0cb1
1277861
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"appHostPath": "../CommunityToolkit.Aspire.Hosting.Azure.Dapr.AppHost.csproj" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,10 +4,12 @@ | |
using Azure.Provisioning.AppContainers; | ||
using Azure.Provisioning.Expressions; | ||
using Azure.Provisioning.KeyVault; | ||
using Azure.Provisioning.Redis; | ||
using Azure.Provisioning.Roles; | ||
using CommunityToolkit.Aspire.Hosting.Azure.Dapr; | ||
using CommunityToolkit.Aspire.Hosting.Dapr; | ||
using AzureRedisResource = Azure.Provisioning.Redis.RedisResource; | ||
using CdkRedisResource = Azure.Provisioning.Redis.RedisResource; | ||
using RedisResource = Aspire.Hosting.ApplicationModel.RedisResource; | ||
|
||
namespace Aspire.Hosting; | ||
|
||
|
@@ -91,16 +93,12 @@ | |
|
||
private static void ConfigureForManagedIdentityAuthentication(this IResourceBuilder<IDaprComponentResource> builder, IResourceBuilder<AzureRedisCacheResource> redisBuilder, string componentType) | ||
{ | ||
var principalIdParam = new ProvisioningParameter(AzureBicepResource.KnownParameters.PrincipalId, typeof(string)); | ||
|
||
var configureInfrastructure = (AzureResourceInfrastructure infrastructure) => | ||
var configureInfrastructure = (AzureResourceInfrastructure infrastructure, UserAssignedIdentity daprIdentity) => | ||
{ | ||
var redisHostParam = redisBuilder.GetOutput(daprConnectionStringKey).AsProvisioningParameter(infrastructure, redisHostKey); | ||
|
||
var provisionableResources = infrastructure.GetProvisionableResources(); | ||
if (provisionableResources.OfType<ContainerAppManagedEnvironment>().FirstOrDefault() | ||
is ContainerAppManagedEnvironment managedEnvironment && | ||
provisionableResources.OfType<UserAssignedIdentity>().FirstOrDefault() is UserAssignedIdentity identity) | ||
if (provisionableResources.OfType<ContainerAppManagedEnvironment>().FirstOrDefault() is ContainerAppManagedEnvironment managedEnvironment) | ||
{ | ||
var daprComponent = AzureDaprHostingExtensions.CreateDaprComponent( | ||
builder.Resource.Name, | ||
|
@@ -115,7 +113,7 @@ | |
new() { Name = redisHostKey, Value = redisHostParam }, | ||
new() { Name = "enableTLS", Value = "true" }, | ||
new() { Name = "useEntraID", Value = "true" }, | ||
new() { Name = "azureClientId", Value = identity.PrincipalId } | ||
new() { Name = "azureClientId", Value = daprIdentity.PrincipalId } | ||
}; | ||
|
||
// Add state-specific metadata | ||
|
@@ -124,6 +122,25 @@ | |
metadata.Add(new ContainerAppDaprMetadata { Name = "actorStateStore", Value = "true" }); | ||
} | ||
|
||
if (redisBuilder.Resource.AddAsExistingResource(infrastructure) is CdkRedisResource redis) | ||
{ | ||
var redisBicepIdentifier = redisBuilder.Resource.GetBicepIdentifier(); | ||
var policyBicepIdentifier = $"{redisBicepIdentifier}_contributor"; | ||
if (!infrastructure.GetProvisionableResources().OfType<RedisCacheAccessPolicyAssignment>().Any(r => r.BicepIdentifier == policyBicepIdentifier)) | ||
{ | ||
|
||
infrastructure.Add(new RedisCacheAccessPolicyAssignment($"{redisBicepIdentifier}_contributor") | ||
{ | ||
Name = BicepFunction.CreateGuid(redis.Id, daprIdentity.PrincipalId, "Data Contributor"), | ||
Parent = redis, | ||
AccessPolicyName = "Data Contributor", | ||
ObjectId = daprIdentity.PrincipalId, | ||
ObjectIdAlias = daprIdentity.Name | ||
}); | ||
} | ||
|
||
} | ||
|
||
daprComponent.Metadata = [.. metadata]; | ||
|
||
// Add scopes if any exist | ||
|
@@ -132,15 +149,18 @@ | |
infrastructure.Add(daprComponent); | ||
|
||
infrastructure.TryAdd(redisHostParam); | ||
|
||
} | ||
}; | ||
|
||
|
||
//builder.WithRoleAssignments(redisBuilder, RedisBuiltInRole.GetBuiltInRoleName, [RedisBuiltInRole.RedisCacheContributor]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this for a todo or can we drop the commented out code? |
||
builder.WithAnnotation(new AzureDaprComponentPublishingAnnotation(configureInfrastructure)); | ||
|
||
// Configure the Redis resource to output the connection string | ||
redisBuilder.ConfigureInfrastructure(infrastructure => | ||
{ | ||
var redisResource = infrastructure.GetProvisionableResources().OfType<AzureRedisResource>().SingleOrDefault(); | ||
var redisResource = infrastructure.GetProvisionableResources().OfType<CdkRedisResource>().SingleOrDefault(); | ||
var outputExists = infrastructure.GetProvisionableResources().OfType<ProvisioningOutput>().Any(o => o.BicepIdentifier == daprConnectionStringKey); | ||
|
||
if (redisResource is not null && !outputExists) | ||
|
@@ -162,7 +182,7 @@ | |
// Configure Key Vault secret store component - this adds the annotation to the same resource | ||
builder.ConfigureKeyVaultSecretsComponent(kvNameParam); | ||
|
||
var configureInfrastructure = (AzureResourceInfrastructure infrastructure) => | ||
var configureInfrastructure = (AzureResourceInfrastructure infrastructure, UserAssignedIdentity daprIdentity) => | ||
{ | ||
var redisHostParam = redisBuilder.GetOutput(daprConnectionStringKey).AsProvisioningParameter(infrastructure, redisHostKey); | ||
|
||
|
@@ -183,6 +203,7 @@ | |
new() { Name = "redisPassword", SecretRef = "redis-password" } | ||
}; | ||
|
||
// TODO: Make this configurable - perhaps AddDaprStateStore().AsActorStateStore() or similar | ||
FullStackChef marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Add state-specific metadata | ||
if (componentType == "state.redis") | ||
{ | ||
|
@@ -208,7 +229,7 @@ | |
// Configure the Redis resource to output the connection string and set up Key Vault secret | ||
redisBuilder.ConfigureInfrastructure(infrastructure => | ||
{ | ||
var redisResource = infrastructure.GetProvisionableResources().OfType<AzureRedisResource>().SingleOrDefault(); | ||
Check failure on line 232 in src/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis/AzureRedisCacheDaprHostingExtensions.cs
|
||
if (redisResource is not null) | ||
{ | ||
var keyVault = infrastructure.GetProvisionableResources().OfType<KeyVaultService>().SingleOrDefault(); | ||
|
@@ -224,7 +245,7 @@ | |
Name = "redis-password", | ||
Properties = new SecretProperties | ||
{ | ||
Value = redisResource.GetKeys().PrimaryKey | ||
Check failure on line 248 in src/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis/AzureRedisCacheDaprHostingExtensions.cs
|
||
} | ||
}; | ||
|
||
|
@@ -237,7 +258,7 @@ | |
|
||
infrastructure.Add(new ProvisioningOutput(daprConnectionStringKey, typeof(string)) | ||
{ | ||
Value = BicepFunction.Interpolate($"{redisResource.HostName}:{redisResource.SslPort}") | ||
Check failure on line 261 in src/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis/AzureRedisCacheDaprHostingExtensions.cs
|
||
}); | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's drop this file. I kinda of want to work out how we could do better aspire cli support, but until then we should avoid adding the files.