Skip to content

Commit

Permalink
Adding bicep resource type (dotnet#2056)
Browse files Browse the repository at this point in the history
* Added bicep resource primitive for azure resources
- Added new resource types to aid in the transition to the new bicep resource primitive
- Updated a BicepProvisioner to AzureProvisioning
- Added lots of bicep files

---------

Co-authored-by: Mitch Denny <midenn@microsoft.com>
  • Loading branch information
davidfowl and mitchdenny committed Feb 6, 2024
1 parent e86957f commit 55c1921
Show file tree
Hide file tree
Showing 56 changed files with 3,356 additions and 10 deletions.
17 changes: 17 additions & 0 deletions Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MySqlDb.AppHost", "Playgrou
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MySql.ApiService", "playground\mysql\MySql.ApiService\MySql.ApiService.csproj", "{F699F3AD-2AD9-454B-BA40-82AC3D6250FE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bicep", "bicep", "{4E1F1835-7006-412D-83A1-740709A54A26}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BicepSample.AppHost", "playground\bicep\BicepSample.AppHost\BicepSample.AppHost.csproj", "{7E67B5F3-ADAC-48E2-83CE-1E1BFF1F8505}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BicepSample.ApiService", "playground\bicep\BicepSample.ApiService\BicepSample.ApiService.csproj", "{54FE1759-A648-4805-94FD-08F0F4B147CF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -632,6 +638,14 @@ Global
{F699F3AD-2AD9-454B-BA40-82AC3D6250FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F699F3AD-2AD9-454B-BA40-82AC3D6250FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F699F3AD-2AD9-454B-BA40-82AC3D6250FE}.Release|Any CPU.Build.0 = Release|Any CPU
{7E67B5F3-ADAC-48E2-83CE-1E1BFF1F8505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E67B5F3-ADAC-48E2-83CE-1E1BFF1F8505}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E67B5F3-ADAC-48E2-83CE-1E1BFF1F8505}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E67B5F3-ADAC-48E2-83CE-1E1BFF1F8505}.Release|Any CPU.Build.0 = Release|Any CPU
{54FE1759-A648-4805-94FD-08F0F4B147CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54FE1759-A648-4805-94FD-08F0F4B147CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54FE1759-A648-4805-94FD-08F0F4B147CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54FE1759-A648-4805-94FD-08F0F4B147CF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -745,6 +759,9 @@ Global
{621991F1-854A-4743-835B-10CAF11A0CFF} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
{7E2AD00B-60E0-46C2-8640-7217D678F312} = {621991F1-854A-4743-835B-10CAF11A0CFF}
{F699F3AD-2AD9-454B-BA40-82AC3D6250FE} = {621991F1-854A-4743-835B-10CAF11A0CFF}
{4E1F1835-7006-412D-83A1-740709A54A26} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
{7E67B5F3-ADAC-48E2-83CE-1E1BFF1F8505} = {4E1F1835-7006-412D-83A1-740709A54A26}
{54FE1759-A648-4805-94FD-08F0F4B147CF} = {4E1F1835-7006-412D-83A1-740709A54A26}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C}
Expand Down
4 changes: 3 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.0" />
<PackageVersion Include="Azure.Identity" Version="1.10.4" />
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.17.1" />
<PackageVersion Include="Azure.ResourceManager.Resources" Version="1.7.0" />
<PackageVersion Include="Azure.Security.KeyVault.Secrets" Version="4.6.0-beta.2" />
<PackageVersion Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageVersion Include="Azure.Storage.Queues" Version="12.17.1" />
Expand Down Expand Up @@ -99,6 +100,7 @@
<PackageVersion Include="RabbitMQ.Client" Version="6.7.0" />
<PackageVersion Include="StackExchange.Redis" Version="2.7.4" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.1.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.23407.1" />
<!-- Open Telemetry -->
Expand Down Expand Up @@ -127,4 +129,4 @@
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> <!-- Introduced by Microsoft.Azure.Cosmos, https://github.com/Azure/azure-cosmos-dotnet-v3/issues/4302 -->

</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Components\Aspire.Azure.Data.Tables\Aspire.Azure.Data.Tables.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.Azure.Messaging.ServiceBus\Aspire.Azure.Messaging.ServiceBus.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.Azure.Storage.Blobs\Aspire.Azure.Storage.Blobs.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.Azure.Storage.Queues\Aspire.Azure.Storage.Queues.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.Microsoft.Azure.Cosmos\Aspire.Microsoft.Azure.Cosmos.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.Microsoft.EntityFrameworkCore.SqlServer\Aspire.Microsoft.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.Npgsql.EntityFrameworkCore.PostgreSQL\Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.csproj" />
<ProjectReference Include="..\..\..\src\Components\Aspire.StackExchange.Redis\Aspire.StackExchange.Redis.csproj" />
<ProjectReference Include="..\..\Playground.ServiceDefaults\Playground.ServiceDefaults.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@CosmosEndToEnd.ApiService_HostAddress = http://localhost:5193

GET {{SqlServerEndToEnd.ApiService_HostAddress}}/weatherforecast/
Accept: application/json

###
224 changes: 224 additions & 0 deletions playground/bicep/BicepSample.ApiService/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text.Json;
using Azure.Data.Tables;
using Azure.Messaging.ServiceBus;
using Azure.Storage.Blobs;
using Azure.Storage.Queues;
using Microsoft.Azure.Cosmos;
using Microsoft.EntityFrameworkCore;
using StackExchange.Redis;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.AddSqlServerDbContext<MyDbContext>("db");
builder.AddNpgsqlDbContext<MyPgDbContext>("db2");
builder.AddAzureCosmosDB("db3", settings => settings.IgnoreEmulatorCertificate = true);
builder.AddRedis("redis");
builder.AddAzureBlobService("blob");
builder.AddAzureTableService("table");
builder.AddAzureQueueService("queue");
builder.AddAzureServiceBus("sb");

var app = builder.Build();

app.MapGet("/", async (MyDbContext context) =>
{
// You wouldn't normally do this on every call,
// but doing it here just to make this simple.
context.Database.EnsureCreated();
var entry = new Entry();
await context.Entries.AddAsync(entry);
await context.SaveChangesAsync();
var entries = await context.Entries.ToListAsync();
return new
{
totalEntries = entries.Count,
entries = entries
};
});

app.MapGet("/pg", async (MyPgDbContext context) =>
{
// You wouldn't normally do this on every call,
// but doing it here just to make this simple.
context.Database.EnsureCreated();
var entry = new Entry();
await context.Entries.AddAsync(entry);
await context.SaveChangesAsync();
var entries = await context.Entries.ToListAsync();
return new
{
totalEntries = entries.Count,
entries = entries
};
});

app.MapGet("/cosmos", async (CosmosClient cosmosClient) =>
{
var db = (await cosmosClient.CreateDatabaseIfNotExistsAsync("db3")).Database;
var container = (await db.CreateContainerIfNotExistsAsync("entries", "/Id")).Container;
// Add an entry to the database on each request.
var newEntry = new Entry();
await container.CreateItemAsync(newEntry);
var entries = new List<Entry>();
var iterator = container.GetItemQueryIterator<Entry>(requestOptions: new QueryRequestOptions() { MaxItemCount = 5 });
var batchCount = 0;
while (iterator.HasMoreResults)
{
batchCount++;
var batch = await iterator.ReadNextAsync();
foreach (var entry in batch)
{
entries.Add(entry);
}
}
return new
{
batchCount = batchCount,
totalEntries = entries.Count,
entries = entries
};
});

app.MapGet("/redis", async (IConnectionMultiplexer connection) =>
{
var database = connection.GetDatabase();
var entry = new Entry();
// Add an entry to the list on each request.
await database.ListRightPushAsync("entries", JsonSerializer.SerializeToUtf8Bytes(entry));
var entries = new List<Entry>();
var list = await database.ListRangeAsync("entries");
foreach (var item in list)
{
entries.Add(JsonSerializer.Deserialize<Entry>((string)item!)!);
}
return entries;
});

app.MapGet("/blobs", async (BlobServiceClient blobServiceClient) =>
{
var container = blobServiceClient.GetBlobContainerClient("blobs");
await container.CreateIfNotExistsAsync();
var entry = new Entry();
var blob = container.GetBlobClient(entry.Id.ToString());
// Add an entry to the blob on each request.
await blob.UploadAsync(new BinaryData(entry));
var entries = new List<Entry>();
await foreach (var item in container.GetBlobsAsync())
{
var client = container.GetBlobClient(item.Name);
using var content = await client.OpenReadAsync();
entries.Add(JsonSerializer.Deserialize<Entry>(content)!);
}
return entries;
});

app.MapGet("/tables", async (TableServiceClient tableServiceClient) =>
{
var table = tableServiceClient.GetTableClient("entries");
await table.CreateIfNotExistsAsync();
var entry = new Entry();
var tableEntry = new TableEntity(entry.Id.ToString(), entry.Id.ToString())
{
{ "data", JsonSerializer.Serialize(entry) }
};
// Add an entry to the table on each request.
await table.AddEntityAsync(tableEntry);
var entries = new List<Entry>();
await foreach (var item in table.QueryAsync<TableEntity>())
{
entries.Add(JsonSerializer.Deserialize<Entry>((string)item["data"])!);
}
return entries;
});

app.MapGet("/queues", async (QueueServiceClient queueServiceClient, CancellationToken cancellationToken) =>
{
var queue = queueServiceClient.GetQueueClient("entries");
await queue.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
var entry = new Entry();
// Add an entry to the queue on each request.
await queue.SendMessageAsync(new BinaryData(entry), cancellationToken: cancellationToken);
var entries = new List<Entry>();
var message = await queue.ReceiveMessageAsync(cancellationToken: cancellationToken);
if (message != null)
{
entries.Add(message.Value.Body.ToObjectFromJson<Entry>());
}
return entries;
});

app.MapGet("/servicebus", async (ServiceBusClient serviceBusClient, CancellationToken cancellationToken) =>
{
await using var sender = serviceBusClient.CreateSender("queue1");
var entry = new Entry();
// Add an entry to the queue on each request.
await sender.SendMessageAsync(new ServiceBusMessage(new BinaryData(entry)), cancellationToken);
var entries = new List<Entry>();
await using var receiver = serviceBusClient.CreateReceiver("queue1");
var message = await receiver.ReceiveMessageAsync(cancellationToken: cancellationToken);
if (message != null)
{
entries.Add(message.Body.ToObjectFromJson<Entry>());
}
return entries;
});

app.Run();

public class MyPgDbContext(DbContextOptions<MyPgDbContext> options) : DbContext(options)
{
public DbSet<Entry> Entries { get; set; }
}

public class MyDbContext(DbContextOptions<MyDbContext> options) : DbContext(options)
{
public DbSet<Entry> Entries { get; set; }
}

public class Entry
{
[Newtonsoft.Json.JsonProperty("id")]
public Guid Id { get; set; } = Guid.NewGuid();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5180",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions playground/bicep/BicepSample.ApiService/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
23 changes: 23 additions & 0 deletions playground/bicep/BicepSample.AppHost/BicepSample.AppHost.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>dafae173-3ac0-4100-8cab-602852cb28dd</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(SharedDir)KnownResourceNames.cs" Link="KnownResourceNames.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Aspire.Dashboard\Aspire.Dashboard.csproj" />
<ProjectReference Include="..\..\..\src\Aspire.Hosting.Azure.Provisioning\Aspire.Hosting.Azure.Provisioning.csproj" IsAspireProjectResource="false" />

<ProjectReference Include="..\BicepSample.ApiService\BicepSample.ApiService.csproj" />
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions playground/bicep/BicepSample.AppHost/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<!-- NOTE: This line is only required because we are using P2P references, not NuGet. It will not exist in real apps. -->
<Import Project="../../../src/Aspire.Hosting/build/Aspire.Hosting.props" />

</Project>
9 changes: 9 additions & 0 deletions playground/bicep/BicepSample.AppHost/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project>

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />

<!-- NOTE: These lines are only required because we are using P2P references, not NuGet. They will not exist in real apps. -->
<Import Project="..\..\..\src\Aspire.Hosting\build\Aspire.Hosting.targets" />
<Import Project="..\..\..\src\Aspire.Hosting.Sdk\SDK\Sdk.targets" />

</Project>
Loading

0 comments on commit 55c1921

Please sign in to comment.