Skip to content

Commit 6e0a43c

Browse files
Add Azure provisioning and deployment capabilities
Introduced Azure-specific startup mode and added support for provisioning Azure resources such as Container Apps, Event Hubs, Cosmos DB, Application Insights, and more. Updated projects to publish as Azure Container Apps with scaling configurations. Improved resource dependency handling with `.WaitFor()` calls. Added `PublishAsAzureContainerAppJob` for BotQ with event-triggered scaling. Updated SQL Server configuration for `OnPremises` mode. Enhanced `Codebreaker.AppHost.csproj` with new Azure-related NuGet dependencies. Included code cleanup, comments, and TODOs for future improvements.
1 parent 722d8a1 commit 6e0a43c

2 files changed

Lines changed: 92 additions & 36 deletions

File tree

src/services/host/Codebreaker.AppHost/AppHost.cs

Lines changed: 91 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
using Azure.Provisioning.AppContainers;
2+
using Azure.Provisioning.EventHubs;
3+
using Azure.Provisioning.Sql;
4+
15
var builder = DistributedApplication.CreateBuilder(args);
26

37
string dataStore = builder.Configuration["DataStore"] ?? "InMemory";
@@ -17,7 +21,7 @@
1721
var sqlServer = builder.AddSqlServer("sql")
1822
.WithDataVolume()
1923
.PublishAsContainer()
20-
.AddDatabase("CodebreakerSql");
24+
.AddDatabase("CodebreakerSql");
2125

2226
var cosmos = builder.AddAzureCosmosDB("codebreakercosmos")
2327
.AddCosmosDatabase("codebreaker");
@@ -53,6 +57,8 @@
5357
}
5458
else
5559
{
60+
builder.AddAzureContainerAppEnvironment("codebreaker-environment");
61+
5662
var logs = builder.AddAzureLogAnalyticsWorkspace("logs");
5763
var insights = builder.AddAzureApplicationInsights("insights", logs);
5864
var signalR = builder.AddAzureSignalR("signalr");
@@ -61,7 +67,16 @@
6167
var botQueue = storage.AddQueues("botqueue");
6268
var blob = storage.AddBlobs("checkpoints");
6369

64-
var eventHub = builder.AddAzureEventHubs("codebreakerevents");
70+
var eventHub = builder.AddAzureEventHubs("codebreakerevents")
71+
.ConfigureInfrastructure(infrastructure =>
72+
{
73+
var eventHubsNamespace = infrastructure.GetProvisionableResources().OfType<EventHubsNamespace>().Single();
74+
eventHubsNamespace.Sku = new EventHubsSku()
75+
{
76+
Name = EventHubsSkuName.Basic,
77+
Tier = EventHubsSkuTier.Basic
78+
};
79+
});
6580

6681
eventHub.AddHub("games");
6782

@@ -75,73 +90,113 @@
7590

7691
// TODO: fix new eventhub namings
7792
var gameAPIs = builder.AddProject<Projects.Codebreaker_GameAPIs>("gameapis")
78-
.WithReference(cosmos)
79-
.WithReference(redis)
80-
.WithReference(insights)
81-
.WithReference(eventHub)
93+
.WithReference(cosmos).WaitFor(cosmos)
94+
.WithReference(redis).WaitFor(redis)
95+
.WithReference(insights).WaitFor(insights)
96+
.WithReference(eventHub).WaitFor(eventHub)
8297
.WithEnvironment("DataStore", dataStore)
83-
.WithEnvironment("StartupMode", startupMode);
98+
.WithEnvironment("StartupMode", startupMode)
99+
.PublishAsAzureContainerApp((module, app) =>
100+
{
101+
app.Template.Scale.MinReplicas = 0;
102+
app.Template.Scale.MaxReplicas = 2;
103+
});
84104

85105
var bot = builder.AddProject<Projects.CodeBreaker_Bot>("bot")
86-
.WithReference(insights)
87-
.WithReference(botQueue)
88-
.WithReference(gameAPIs)
106+
.WithReference(insights).WaitFor(insights)
107+
.WithReference(botQueue).WaitFor(botQueue)
108+
.WithReference(gameAPIs).WaitFor(gameAPIs)
89109
.WithEnvironment("Bot__Loop", botLoop)
90110
.WithEnvironment("Bot__Delay", botDelay)
91-
.WaitFor(gameAPIs);
111+
.PublishAsAzureContainerApp((module, app) =>
112+
{
113+
app.Template.Scale.MinReplicas = 0;
114+
app.Template.Scale.MaxReplicas = 1;
115+
});
92116

93117
// TODO: change to use BotQ with Container App Jobs
118+
#pragma warning disable ASPIREAZURE002 // PublishAsAzureContainerAppJob is for evaluation purposes
94119
var botq = builder.AddProject<Projects.Codebreaker_BotQ>("botq")
95-
.WithReference(insights)
96-
.WithReference(botQueue)
97-
.WithReference(gameAPIs)
120+
.WithReference(insights).WaitFor(insights)
121+
.WithReference(botQueue).WaitFor(botQueue)
122+
.WithReference(gameAPIs).WaitFor(gameAPIs)
98123
.WithEnvironment("Bot__Loop", botLoop)
99124
.WithEnvironment("Bot__Delay", botDelay)
100-
.WaitFor(gameAPIs);
125+
.PublishAsAzureContainerAppJob((_, job) =>
126+
{
127+
job.Configuration.TriggerType = ContainerAppJobTriggerType.Event;
128+
job.Configuration.EventTriggerConfig.Scale.MinExecutions = 1;
129+
job.Configuration.EventTriggerConfig.Scale.MaxExecutions = 10;
130+
job.Configuration.EventTriggerConfig.Parallelism = 1;
131+
job.Configuration.EventTriggerConfig.ReplicaCompletionCount = 1;
132+
// TODO: specify scale rule on queue trigger
133+
//job.Configuration.EventTriggerConfig.Scale.Rules.Add(new ContainerAppJobScaleRule()
134+
//{
135+
// QueueName = botQueue.Resource.Name,
136+
// MessageCount = 1
137+
//});
138+
});
139+
#pragma warning restore ASPIREAZURE002
101140

102141
var live = builder.AddProject<Projects.Codebreaker_Live>("live")
103142
.WithReference(insights)
104143
.WithReference(eventHub)
105144
.WithReference(signalR)
106145
.WaitFor(eventHub)
107-
.WaitFor(gameAPIs);
146+
.WaitFor(gameAPIs)
147+
.PublishAsAzureContainerApp((module, app) =>
148+
{
149+
app.Template.Scale.MinReplicas = 0;
150+
app.Template.Scale.MaxReplicas = 1;
151+
});
108152

109153
var ranking = builder.AddProject<Projects.Codebreaker_Ranking>("ranking")
110154
.WithReference(cosmos)
111155
.WithReference(insights)
112-
.WithReference(eventHub)
156+
.WithReference(eventHub).WaitFor(eventHub)
113157
.WithReference(blob)
114-
.WaitFor(eventHub)
115158
.WaitFor(insights)
116-
.WaitFor(gameAPIs);
159+
.WaitFor(gameAPIs)
160+
.PublishAsAzureContainerApp((module, app) =>
161+
{
162+
app.Template.Scale.MinReplicas = 0;
163+
app.Template.Scale.MaxReplicas = 1;
164+
});
117165

118166
var users = builder.AddProject<Projects.CodeBreaker_UserService>("users")
119167
.WithReference(insights)
120168
.WithReference(userServiceKeyvault)
121169
.WaitFor(insights)
122-
.WaitFor(userServiceKeyvault);
170+
.WaitFor(userServiceKeyvault)
171+
.PublishAsAzureContainerApp((module, app) =>
172+
{
173+
app.Template.Scale.MinReplicas = 0;
174+
app.Template.Scale.MaxReplicas = 1;
175+
});
123176

124177
var gateway = builder.AddProject<Projects.Codebreaker_ApiGateway>("gateway")
125178
.WithExternalHttpEndpoints()
126-
.WithReference(gameAPIs)
127-
.WithReference(live)
128-
.WithReference(ranking)
129-
.WithReference(users)
130-
.WithReference(gatewayKeyvault)
131-
.WithReference(insights)
132-
.WaitFor(gameAPIs)
133-
.WaitFor(live)
134-
.WaitFor(ranking)
135-
.WaitFor(users)
136-
.WaitFor(gatewayKeyvault)
137-
.WaitFor(insights);
179+
.WithReference(gameAPIs).WaitFor(gameAPIs)
180+
.WithReference(live).WaitFor(live)
181+
.WithReference(ranking).WaitFor(ranking)
182+
.WithReference(users).WaitFor(users)
183+
.WithReference(gatewayKeyvault).WaitFor(gatewayKeyvault)
184+
.WithReference(insights).WaitFor(insights)
185+
.PublishAsAzureContainerApp((module, app) =>
186+
{
187+
app.Template.Scale.MinReplicas = 0;
188+
app.Template.Scale.MaxReplicas = 2;
189+
});
138190

139191
builder.AddProject<Projects.CodeBreaker_Blazor>("blazor")
140192
.WithExternalHttpEndpoints()
141-
.WithReference(gateway)
142-
.WithReference(insights)
143-
.WaitFor(gateway)
144-
.WaitFor(insights);
193+
.WithReference(gateway).WaitFor(gateway)
194+
.WithReference(insights).WaitFor(insights)
195+
.PublishAsAzureContainerApp((module, app) =>
196+
{
197+
app.Template.Scale.MinReplicas = 0;
198+
app.Template.Scale.MaxReplicas = 1;
199+
});
145200
}
146201

147202
builder.Build().Run();

src/services/host/Codebreaker.AppHost/Codebreaker.AppHost.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<PackageReference Include="Aspire.Hosting.AppHost" />
1515
<PackageReference Include="Aspire.Hosting.Azure" />
1616
<PackageReference Include="Aspire.Hosting.Azure.AppConfiguration" />
17+
<PackageReference Include="Aspire.Hosting.Azure.AppContainers" />
1718
<PackageReference Include="Aspire.Hosting.Azure.ApplicationInsights" />
1819
<PackageReference Include="Aspire.Hosting.Azure.CosmosDB" />
1920
<PackageReference Include="Aspire.Hosting.Azure.EventHubs" />

0 commit comments

Comments
 (0)