Skip to content

Commit 9a175dd

Browse files
Copilotdavidfowl
andauthored
Ensure idempotency for AddAsExistingResource across all Azure resource implementations (#10562)
* Initial plan * Implement idempotency for 4 Azure resource AddAsExistingResource methods Co-authored-by: davidfowl <[email protected]> * Complete idempotency fixes for 14 Azure resource AddAsExistingResource methods Co-authored-by: davidfowl <[email protected]> * Complete idempotency fixes for all remaining Azure resource AddAsExistingResource methods Co-authored-by: davidfowl <[email protected]> * Split idempotency tests into individual Azure resource test classes Co-authored-by: davidfowl <[email protected]> * Add missing test files and idempotency tests for all Azure resources Co-authored-by: davidfowl <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: davidfowl <[email protected]>
1 parent 7009d94 commit 9a175dd

File tree

38 files changed

+548
-19
lines changed

38 files changed

+548
-19
lines changed

src/Aspire.Hosting.Azure.AIFoundry/AzureAIFoundryResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,19 @@ public class AzureAIFoundryResource(string name, Action<AzureResourceInfrastruct
6161
/// <inheritdoc/>
6262
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
6363
{
64-
var csa = CognitiveServicesAccount.FromExisting(this.GetBicepIdentifier());
64+
var bicepIdentifier = this.GetBicepIdentifier();
65+
var resources = infra.GetProvisionableResources();
66+
67+
// Check if a CognitiveServicesAccount with the same identifier already exists
68+
var existingCsa = resources.OfType<CognitiveServicesAccount>().SingleOrDefault(csa => csa.BicepIdentifier == bicepIdentifier);
69+
70+
if (existingCsa is not null)
71+
{
72+
return existingCsa;
73+
}
74+
75+
// Create and add new resource if it doesn't exist
76+
var csa = CognitiveServicesAccount.FromExisting(bicepIdentifier);
6577
csa.Name = NameOutputReference.AsProvisioningParameter(infra);
6678
infra.Add(csa);
6779
return csa;

src/Aspire.Hosting.Azure.AppConfiguration/AzureAppConfigurationResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,19 @@ public class AzureAppConfigurationResource(string name, Action<AzureResourceInfr
3535
/// <inheritdoc/>
3636
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
3737
{
38-
var store = AppConfigurationStore.FromExisting(this.GetBicepIdentifier());
38+
var bicepIdentifier = this.GetBicepIdentifier();
39+
var resources = infra.GetProvisionableResources();
40+
41+
// Check if an AppConfigurationStore with the same identifier already exists
42+
var existingStore = resources.OfType<AppConfigurationStore>().SingleOrDefault(store => store.BicepIdentifier == bicepIdentifier);
43+
44+
if (existingStore is not null)
45+
{
46+
return existingStore;
47+
}
48+
49+
// Create and add new resource if it doesn't exist
50+
var store = AppConfigurationStore.FromExisting(bicepIdentifier);
3951
store.Name = NameOutputReference.AsProvisioningParameter(infra);
4052
infra.Add(store);
4153
return store;

src/Aspire.Hosting.Azure.AppContainers/AzureContainerAppEnvironmentResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,20 @@ internal BicepOutputReference GetVolumeStorage(IResource resource, ContainerMoun
8989
/// <inheritdoc/>
9090
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
9191
{
92+
var bicepIdentifier = this.GetBicepIdentifier();
93+
var resources = infra.GetProvisionableResources();
94+
95+
// Check if a ContainerAppManagedEnvironment with the same identifier already exists
96+
var existingCae = resources.OfType<ContainerAppManagedEnvironment>().SingleOrDefault(cae => cae.BicepIdentifier == bicepIdentifier);
97+
98+
if (existingCae is not null)
99+
{
100+
return existingCae;
101+
}
102+
103+
// Create and add new resource if it doesn't exist
92104
// Even though it's a compound resource, we'll only expose the managed environment
93-
var cae = ContainerAppManagedEnvironment.FromExisting(this.GetBicepIdentifier());
105+
var cae = ContainerAppManagedEnvironment.FromExisting(bicepIdentifier);
94106
cae.Name = NameOutputReference.AsProvisioningParameter(infra);
95107
infra.Add(cae);
96108
return cae;

src/Aspire.Hosting.Azure.AppService/AzureAppServiceEnvironmentResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,19 @@ public class AzureAppServiceEnvironmentResource(string name, Action<AzureResourc
4444
/// <inheritdoc/>
4545
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
4646
{
47-
var plan = AppServicePlan.FromExisting(this.GetBicepIdentifier());
47+
var bicepIdentifier = this.GetBicepIdentifier();
48+
var resources = infra.GetProvisionableResources();
49+
50+
// Check if an AppServicePlan with the same identifier already exists
51+
var existingPlan = resources.OfType<AppServicePlan>().SingleOrDefault(plan => plan.BicepIdentifier == bicepIdentifier);
52+
53+
if (existingPlan is not null)
54+
{
55+
return existingPlan;
56+
}
57+
58+
// Create and add new resource if it doesn't exist
59+
var plan = AppServicePlan.FromExisting(bicepIdentifier);
4860
plan.Name = NameOutputReference.AsProvisioningParameter(infra);
4961
infra.Add(plan);
5062
return plan;

src/Aspire.Hosting.Azure.CognitiveServices/AzureOpenAIResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,19 @@ internal void AddDeployment(AzureOpenAIDeploymentResource deployment)
6262
/// <inheritdoc/>
6363
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
6464
{
65-
var account = CognitiveServicesAccount.FromExisting(this.GetBicepIdentifier());
65+
var bicepIdentifier = this.GetBicepIdentifier();
66+
var resources = infra.GetProvisionableResources();
67+
68+
// Check if a CognitiveServicesAccount with the same identifier already exists
69+
var existingAccount = resources.OfType<CognitiveServicesAccount>().SingleOrDefault(account => account.BicepIdentifier == bicepIdentifier);
70+
71+
if (existingAccount is not null)
72+
{
73+
return existingAccount;
74+
}
75+
76+
// Create and add new resource if it doesn't exist
77+
var account = CognitiveServicesAccount.FromExisting(bicepIdentifier);
6678
account.Name = NameOutputReference.AsProvisioningParameter(infra);
6779
infra.Add(account);
6880
return account;

src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,19 @@ public class AzureContainerRegistryResource(string name, Action<AzureResourceInf
3434
/// <inheritdoc/>
3535
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
3636
{
37-
var store = ContainerRegistryService.FromExisting(this.GetBicepIdentifier());
37+
var bicepIdentifier = this.GetBicepIdentifier();
38+
var resources = infra.GetProvisionableResources();
39+
40+
// Check if a ContainerRegistryService with the same identifier already exists
41+
var existingStore = resources.OfType<ContainerRegistryService>().SingleOrDefault(store => store.BicepIdentifier == bicepIdentifier);
42+
43+
if (existingStore is not null)
44+
{
45+
return existingStore;
46+
}
47+
48+
// Create and add new resource if it doesn't exist
49+
var store = ContainerRegistryService.FromExisting(bicepIdentifier);
3850
store.Name = NameOutputReference.AsProvisioningParameter(infra);
3951
infra.Add(store);
4052
return store;

src/Aspire.Hosting.Azure.CosmosDB/AzureCosmosDBResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,19 @@ internal void SetAccountEndpoint(IDictionary<string, object> target, string conn
117117
/// <inheritdoc/>
118118
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
119119
{
120-
var store = CosmosDBAccount.FromExisting(this.GetBicepIdentifier());
120+
var bicepIdentifier = this.GetBicepIdentifier();
121+
var resources = infra.GetProvisionableResources();
122+
123+
// Check if a CosmosDBAccount with the same identifier already exists
124+
var existingStore = resources.OfType<CosmosDBAccount>().SingleOrDefault(store => store.BicepIdentifier == bicepIdentifier);
125+
126+
if (existingStore is not null)
127+
{
128+
return existingStore;
129+
}
130+
131+
// Create and add new resource if it doesn't exist
132+
var store = CosmosDBAccount.FromExisting(bicepIdentifier);
121133
store.Name = NameOutputReference.AsProvisioningParameter(infra);
122134
infra.Add(store);
123135
return store;

src/Aspire.Hosting.Azure.EventHubs/AzureEventHubsResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,19 @@ internal void ApplyAzureFunctionsConfiguration(IDictionary<string, object> targe
127127
/// <inheritdoc/>
128128
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
129129
{
130-
var hubs = EventHubsNamespace.FromExisting(this.GetBicepIdentifier());
130+
var bicepIdentifier = this.GetBicepIdentifier();
131+
var resources = infra.GetProvisionableResources();
132+
133+
// Check if an EventHubsNamespace with the same identifier already exists
134+
var existingHubs = resources.OfType<EventHubsNamespace>().SingleOrDefault(hubs => hubs.BicepIdentifier == bicepIdentifier);
135+
136+
if (existingHubs is not null)
137+
{
138+
return existingHubs;
139+
}
140+
141+
// Create and add new resource if it doesn't exist
142+
var hubs = EventHubsNamespace.FromExisting(bicepIdentifier);
131143
hubs.Name = NameOutputReference.AsProvisioningParameter(infra);
132144
infra.Add(hubs);
133145
return hubs;

src/Aspire.Hosting.Azure.KeyVault/AzureKeyVaultResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,19 @@ public IAzureKeyVaultSecretReference GetSecret(string secretName)
6262
/// <inheritdoc/>
6363
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
6464
{
65-
var store = KeyVaultService.FromExisting(this.GetBicepIdentifier());
65+
var bicepIdentifier = this.GetBicepIdentifier();
66+
var resources = infra.GetProvisionableResources();
67+
68+
// Check if a KeyVaultService with the same identifier already exists
69+
var existingStore = resources.OfType<KeyVaultService>().SingleOrDefault(store => store.BicepIdentifier == bicepIdentifier);
70+
71+
if (existingStore is not null)
72+
{
73+
return existingStore;
74+
}
75+
76+
// Create and add new resource if it doesn't exist
77+
var store = KeyVaultService.FromExisting(bicepIdentifier);
6678
store.Name = NameOutputReference.AsProvisioningParameter(infra);
6779
infra.Add(store);
6880
return store;

src/Aspire.Hosting.Azure.OperationalInsights/AzureLogAnalyticsWorkspaceResource.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,19 @@ public class AzureLogAnalyticsWorkspaceResource(string name, Action<AzureResourc
2727
/// <inheritdoc/>
2828
public override ProvisionableResource AddAsExistingResource(AzureResourceInfrastructure infra)
2929
{
30-
var store = OperationalInsightsWorkspace.FromExisting(this.GetBicepIdentifier());
30+
var bicepIdentifier = this.GetBicepIdentifier();
31+
var resources = infra.GetProvisionableResources();
32+
33+
// Check if an OperationalInsightsWorkspace with the same identifier already exists
34+
var existingStore = resources.OfType<OperationalInsightsWorkspace>().SingleOrDefault(store => store.BicepIdentifier == bicepIdentifier);
35+
36+
if (existingStore is not null)
37+
{
38+
return existingStore;
39+
}
40+
41+
// Create and add new resource if it doesn't exist
42+
var store = OperationalInsightsWorkspace.FromExisting(bicepIdentifier);
3143
store.Name = NameOutputReference.AsProvisioningParameter(infra);
3244
infra.Add(store);
3345
return store;

0 commit comments

Comments
 (0)