|
5 | 5 | using Aspire.Hosting.Azure;
|
6 | 6 | using Azure.Provisioning;
|
7 | 7 | using Azure.Provisioning.Expressions;
|
| 8 | +using Azure.Provisioning.Primitives; |
8 | 9 | using Azure.Provisioning.Sql;
|
9 | 10 |
|
10 | 11 | namespace Aspire.Hosting;
|
@@ -226,6 +227,20 @@ private static void CreateSqlServer(
|
226 | 227 | };
|
227 | 228 | });
|
228 | 229 |
|
| 230 | + // If the resource is an existing resource, we model the administrator access |
| 231 | + // for the managed identity as an "edge" between the parent SqlServer resource |
| 232 | + // and a custom SqlServerAzureADAdministrator resource. |
| 233 | + if (sqlServer.IsExistingResource) |
| 234 | + { |
| 235 | + var admin = new SqlServerAzureADAdministratorWorkaround($"{sqlServer.BicepIdentifier}_admin") |
| 236 | + { |
| 237 | + ParentOverride = sqlServer, |
| 238 | + LoginOverride = principalNameParameter, |
| 239 | + SidOverride = principalIdParameter |
| 240 | + }; |
| 241 | + infrastructure.Add(admin); |
| 242 | + } |
| 243 | + |
229 | 244 | infrastructure.Add(new SqlFirewallRule("sqlFirewallRule_AllowAllAzureIps")
|
230 | 245 | {
|
231 | 246 | Parent = sqlServer,
|
@@ -268,4 +283,79 @@ private static void CreateSqlServer(
|
268 | 283 |
|
269 | 284 | infrastructure.Add(new ProvisioningOutput("sqlServerFqdn", typeof(string)) { Value = sqlServer.FullyQualifiedDomainName });
|
270 | 285 | }
|
| 286 | + |
| 287 | + /// <remarks> |
| 288 | + /// Workaround for immutable properties on SqlServerAzureADAdministrator. |
| 289 | + /// </remarks> |
| 290 | + private sealed class SqlServerAzureADAdministratorWorkaround(string bicepIdentifier) : SqlServerAzureADAdministrator(bicepIdentifier) |
| 291 | + { |
| 292 | + private BicepValue<string>? _name; |
| 293 | + private BicepValue<string>? _login; |
| 294 | + private BicepValue<Guid>? _sid; |
| 295 | + private ResourceReference<SqlServer>? _parent; |
| 296 | + |
| 297 | + /// <summary> |
| 298 | + /// Login name of the server administrator. |
| 299 | + /// </summary> |
| 300 | + public BicepValue<string> LoginOverride |
| 301 | + { |
| 302 | + get |
| 303 | + { |
| 304 | + Initialize(); |
| 305 | + return _login!; |
| 306 | + } |
| 307 | + set |
| 308 | + { |
| 309 | + Initialize(); |
| 310 | + _login!.Assign(value); |
| 311 | + } |
| 312 | + } |
| 313 | + |
| 314 | + /// <summary> |
| 315 | + /// SID (object ID) of the server administrator. |
| 316 | + /// </summary> |
| 317 | + public BicepValue<Guid> SidOverride |
| 318 | + { |
| 319 | + get |
| 320 | + { |
| 321 | + Initialize(); |
| 322 | + return _sid!; |
| 323 | + } |
| 324 | + set |
| 325 | + { |
| 326 | + Initialize(); |
| 327 | + _sid!.Assign(value); |
| 328 | + } |
| 329 | + } |
| 330 | + |
| 331 | + /// <summary> |
| 332 | + /// Parent resource of the server administrator. |
| 333 | + /// </summary> |
| 334 | + public SqlServer? ParentOverride |
| 335 | + { |
| 336 | + get |
| 337 | + { |
| 338 | + Initialize(); |
| 339 | + return _parent!.Value; |
| 340 | + } |
| 341 | + set |
| 342 | + { |
| 343 | + Initialize(); |
| 344 | + _parent!.Value = value; |
| 345 | + } |
| 346 | + } |
| 347 | + |
| 348 | + private static BicepValue<string> GetNameDefaultValue() |
| 349 | + { |
| 350 | + return new StringLiteralExpression("ActiveDirectory"); |
| 351 | + } |
| 352 | + |
| 353 | + protected override void DefineProvisionableProperties() |
| 354 | + { |
| 355 | + _name = DefineProperty("Name", ["name"], defaultValue: GetNameDefaultValue()); |
| 356 | + _login = DefineProperty<string>("Login", ["properties", "login"]); |
| 357 | + _sid = DefineProperty<Guid>("Sid", ["properties", "sid"]); |
| 358 | + _parent = DefineResource<SqlServer>("Parent", ["parent"], isOutput: false, isRequired: true); |
| 359 | + } |
| 360 | + } |
271 | 361 | }
|
0 commit comments