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

[release/8.0-preview5] Ensure logAnalyticsWorkspaceId parameter is present in Aspire manifest. #3302

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion playground/bicep/BicepSample.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@
var cosmosDb = builder.AddAzureCosmosDB("cosmos")
.AddDatabase("db3");

var appInsights = builder.AddAzureApplicationInsights("ai");
var logAnalytics = builder.AddAzureLogAnalyticsWorkspace("lawkspc");
var appInsights = builder.AddAzureApplicationInsights("ai", logAnalytics);

// To verify that AZD will populate the LAW parameter.
builder.AddAzureApplicationInsights("aiwithoutlaw");

// Redis takes forever to spin up...
var redis = builder.AddRedis("redis")
Expand Down
29 changes: 29 additions & 0 deletions playground/bicep/BicepSample.AppHost/aiwithoutlaw.module.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
targetScope = 'resourceGroup'

@description('')
param location string = resourceGroup().location

@description('')
param applicationType string = 'web'

@description('')
param kind string = 'web'

@description('')
param logAnalyticsWorkspaceId string


resource applicationInsightsComponent_YlZN71uia 'Microsoft.Insights/components@2020-02-02' = {
name: toLower(take(concat('aiwithoutlaw', uniqueString(resourceGroup().id)), 24))
location: location
tags: {
'aspire-resource-name': 'aiwithoutlaw'
}
kind: kind
properties: {
Application_Type: applicationType
WorkspaceResourceId: logAnalyticsWorkspaceId
}
}

output appInsightsConnectionString string = applicationInsightsComponent_YlZN71uia.properties.ConnectionString
19 changes: 17 additions & 2 deletions playground/bicep/BicepSample.AppHost/aspire-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"test0": {
"type": "azure.bicep.v0",
"path": "../../../../../../Users/davifowl/AppData/Local/Temp/tmppj1k21.tmp.bicep"
"path": "test0.bicep"
},
"kv3": {
"type": "azure.bicep.v0",
Expand Down Expand Up @@ -118,10 +118,25 @@
"keyVaultName": ""
}
},
"lawkspc": {
"type": "azure.bicep.v0",
"path": "lawkspc.module.bicep"
},
"ai": {
"type": "azure.bicep.v0",
"connectionString": "{ai.outputs.appInsightsConnectionString}",
"path": "ai.module.bicep"
"path": "ai.module.bicep",
"params": {
"logAnalyticsWorkspaceId": "{lawkspc.outputs.logAnalyticsWorkspaceId}"
}
},
"aiwithoutlaw": {
"type": "azure.bicep.v0",
"connectionString": "{aiwithoutlaw.outputs.appInsightsConnectionString}",
"path": "aiwithoutlaw.module.bicep",
"params": {
"logAnalyticsWorkspaceId": ""
}
},
"redis": {
"type": "azure.bicep.v0",
Expand Down
20 changes: 20 additions & 0 deletions playground/bicep/BicepSample.AppHost/lawkspc.module.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
targetScope = 'resourceGroup'

@description('')
param location string = resourceGroup().location


resource operationalInsightsWorkspace_cxL77xv9Y 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: toLower(take(concat('lawkspc', uniqueString(resourceGroup().id)), 24))
location: location
tags: {
'aspire-resource-name': 'lawkspc'
}
properties: {
sku: {
name: 'PerGB2018'
}
}
}

output logAnalyticsWorkspaceId string = operationalInsightsWorkspace_cxL77xv9Y.id
2 changes: 2 additions & 0 deletions playground/bicep/BicepSample.AppHost/test0.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
param location string = ''
output val0 string = location
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Aspire.Hosting.Azure.OperationalInsights\Aspire.Hosting.Azure.OperationalInsights.csproj" />
<ProjectReference Include="..\Aspire.Hosting.Azure\Aspire.Hosting.Azure.csproj" />
<PackageReference Include="Azure.Provisioning" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,21 @@ public static class AzureApplicationInsightsExtensions
public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplicationInsights(this IDistributedApplicationBuilder builder, string name)
{
#pragma warning disable ASPIRE0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
return builder.AddAzureApplicationInsights(name, (_, _, _) => { });
return builder.AddAzureApplicationInsights(name, null, null);
#pragma warning restore ASPIRE0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
}

/// <summary>
/// Adds an Azure Application Insights resource to the application model.
/// </summary>
/// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
/// <param name="name">The name of the resource. This name will be used as the connection string name when referenced in a dependency.</param>
/// <param name="logAnalyticsWorkspace">A resource builder for the log analytics workspace.</param>
/// <returns>A reference to the <see cref="IResourceBuilder{AzureApplicationInsightsResource}"/>.</returns>
public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplicationInsights(this IDistributedApplicationBuilder builder, string name, IResourceBuilder<AzureLogAnalyticsWorkspaceResource>? logAnalyticsWorkspace)
{
#pragma warning disable ASPIRE0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
return builder.AddAzureApplicationInsights(name, logAnalyticsWorkspace, null);
#pragma warning restore ASPIRE0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
}

Expand All @@ -36,6 +50,20 @@ public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplica
/// <returns></returns>
[Experimental("ASPIRE0001", UrlFormat = "https://aka.ms/dotnet/aspire/diagnostics#{0}")]
public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplicationInsights(this IDistributedApplicationBuilder builder, string name, Action<IResourceBuilder<AzureApplicationInsightsResource>, ResourceModuleConstruct, ApplicationInsightsComponent>? configureResource)
{
return builder.AddAzureApplicationInsights(name, null, configureResource);
}

/// <summary>
/// Adds an Azure Application Insights resource to the application model.
/// </summary>
/// <param name="builder">The builder for the distributed application.</param>
/// <param name="name">The name of the resource.</param>
/// <param name="logAnalyticsWorkspace">A resource builder for the log analytics workspace.</param>
/// <param name="configureResource">Optional callback to configure the Application Insights resource.</param>
/// <returns></returns>
[Experimental("ASPIRE0001", UrlFormat = "https://aka.ms/dotnet/aspire/diagnostics#{0}")]
public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplicationInsights(this IDistributedApplicationBuilder builder, string name, IResourceBuilder<AzureLogAnalyticsWorkspaceResource>? logAnalyticsWorkspace, Action<IResourceBuilder<AzureApplicationInsightsResource>, ResourceModuleConstruct, ApplicationInsightsComponent>? configureResource)
{
builder.AddAzureProvisioning();

Expand All @@ -45,7 +73,19 @@ public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplica
appInsights.Properties.Tags["aspire-resource-name"] = construct.Resource.Name;
appInsights.AssignProperty(p => p.ApplicationType, new Parameter("applicationType", defaultValue: "web"));
appInsights.AssignProperty(p => p.Kind, new Parameter("kind", defaultValue: "web"));
appInsights.AssignProperty(p => p.WorkspaceResourceId, new Parameter(AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId));

if (logAnalyticsWorkspace != null)
{
appInsights.AssignProperty(p => p.WorkspaceResourceId, logAnalyticsWorkspace.Resource.WorkspaceId, AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId);
}
else
{
// If the user does not supply a log analytics workspace of their own we still create a parameter on the Aspire
// side and the CDK side so that AZD can fill the value in with the one it generates.
construct.Resource.Parameters.Add(AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId, "");
appInsights.AssignProperty(p => p.WorkspaceResourceId, new Parameter(AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId));

}

appInsights.AddOutput("appInsightsConnectionString", p => p.ConnectionString);

Expand All @@ -56,6 +96,7 @@ public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplica
configureResource(resourceBuilder, construct, appInsights);
}
};

var resource = new AzureApplicationInsightsResource(name, configureConstruct);

return builder.AddResource(resource)
Expand Down
2 changes: 1 addition & 1 deletion src/Aspire.Hosting.Azure/AzureBicepResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public virtual BicepTemplateFile GetBicepTemplateFile(string? directory = null,
isTempFile = directory is null;

path = TempDirectory is null
? Path.GetTempFileName() + ".bicep"
? Path.Combine(directory ?? Directory.CreateTempSubdirectory("aspire").FullName, $"{Name.ToLowerInvariant()}.bicep")
: Path.Combine(TempDirectory, $"{Name.ToLowerInvariant()}.bicep");

if (TemplateResourceName is null)
Expand Down
71 changes: 69 additions & 2 deletions tests/Aspire.Hosting.Tests/Azure/AzureBicepResourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ param principalType string
}

[Fact]
public async Task AddApplicationInsights()
public async Task AddApplicationInsightsWithoutExplicitLawGetsDefaultLawParameter()
{
using var builder = TestDistributedApplicationBuilder.Create();

Expand All @@ -363,7 +363,74 @@ public async Task AddApplicationInsights()
{
"type": "azure.bicep.v0",
"connectionString": "{appInsights.outputs.appInsightsConnectionString}",
"path": "appInsights.module.bicep"
"path": "appInsights.module.bicep",
"params": {
"logAnalyticsWorkspaceId": ""
}
}
""";
Assert.Equal(expectedManifest, appInsightsManifest.ManifestNode.ToString());

var expectedBicep = """
targetScope = 'resourceGroup'

@description('')
param location string = resourceGroup().location

@description('')
param applicationType string = 'web'

@description('')
param kind string = 'web'

@description('')
param logAnalyticsWorkspaceId string


resource applicationInsightsComponent_fo9MneV12 'Microsoft.Insights/components@2020-02-02' = {
name: toLower(take(concat('appInsights', uniqueString(resourceGroup().id)), 24))
location: location
tags: {
'aspire-resource-name': 'appInsights'
}
kind: kind
properties: {
Application_Type: applicationType
WorkspaceResourceId: logAnalyticsWorkspaceId
}
}

output appInsightsConnectionString string = applicationInsightsComponent_fo9MneV12.properties.ConnectionString

""";
Assert.Equal(expectedBicep, appInsightsManifest.BicepText);
}

[Fact]
public async Task AddApplicationInsightsWithExplicitLawArgumentDoesntGetDefaultParameter()
{
using var builder = TestDistributedApplicationBuilder.Create();

var law = builder.AddAzureLogAnalyticsWorkspace("mylaw");
var appInsights = builder.AddAzureApplicationInsights("appInsights", law);

appInsights.Resource.Outputs["appInsightsConnectionString"] = "myinstrumentationkey";

var connectionStringResource = (IResourceWithConnectionString)appInsights.Resource;

Assert.Equal("appInsights", appInsights.Resource.Name);
Assert.Equal("myinstrumentationkey", await connectionStringResource.GetConnectionStringAsync());
Assert.Equal("{appInsights.outputs.appInsightsConnectionString}", appInsights.Resource.ConnectionStringExpression.ValueExpression);

var appInsightsManifest = await ManifestUtils.GetManifestWithBicep(appInsights.Resource);
var expectedManifest = """
{
"type": "azure.bicep.v0",
"connectionString": "{appInsights.outputs.appInsightsConnectionString}",
"path": "appInsights.module.bicep",
"params": {
"logAnalyticsWorkspaceId": "{mylaw.outputs.logAnalyticsWorkspaceId}"
}
}
""";
Assert.Equal(expectedManifest, appInsightsManifest.ManifestNode.ToString());
Expand Down