Skip to content

Commit 9ef696c

Browse files
authored
initial checkin for Azure.Provisioning.CloudMachine (work in progress) (Azure#46077)
1 parent f166fdb commit 9ef696c

File tree

10 files changed

+351
-0
lines changed

10 files changed

+351
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Release History
2+
3+
## 1.0.0-beta.1 (Unreleased)
4+
5+
### Features Added
6+
7+
### Breaking Changes
8+
9+
### Bugs Fixed
10+
11+
### Other Changes
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Azure Provisioning client library for .NET
2+
3+
Azure.Provisioning.CloudMachine simplifies declarative resource provisioning in .NET for CloudMachine resources.
4+
5+
## Getting started
6+
7+
### Install the package
8+
9+
Install the client library for .NET with [NuGet](https://www.nuget.org/ ):
10+
11+
```dotnetcli
12+
dotnet add package Azure.Provisioning.CloudMachine
13+
```
14+
15+
### Prerequisites
16+
17+
> You must have an [Azure subscription](https://azure.microsoft.com/free/dotnet/).
18+
19+
### Authenticate the Client
20+
21+
## Key concepts
22+
23+
This library allows you to specify your infrastructure in a declarative style using dotnet. You can then use azd to deploy your infrastructure to Azure directly without needing to write or maintain bicep or arm templates.
24+
25+
## Examples
26+
27+
## Troubleshooting
28+
29+
- File an issue via [GitHub Issues](https://github.com/Azure/azure-sdk-for-net/issues).
30+
- Check [previous questions](https://stackoverflow.com/questions/tagged/azure+.net) or ask new ones on Stack Overflow using Azure and .NET tags.
31+
32+
## Next steps
33+
34+
## Contributing
35+
36+
For details on contributing to this repository, see the [contributing
37+
guide][cg].
38+
39+
This project welcomes contributions and suggestions. Most contributions
40+
require you to agree to a Contributor License Agreement (CLA) declaring
41+
that you have the right to, and actually do, grant us the rights to use
42+
your contribution. For details, visit <https://cla.microsoft.com>.
43+
44+
When you submit a pull request, a CLA-bot will automatically determine
45+
whether you need to provide a CLA and decorate the PR appropriately
46+
(for example, label, comment). Follow the instructions provided by the
47+
bot. You'll only need to do this action once across all repositories
48+
using our CLA.
49+
50+
This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For
51+
more information, see the [Code of Conduct FAQ][coc_faq] or contact
52+
<[email protected]> with any other questions or comments.
53+
54+
<!-- LINKS -->
55+
[cg]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/resourcemanager/Azure.ResourceManager/docs/CONTRIBUTING.md
56+
[coc]: https://opensource.microsoft.com/codeofconduct/
57+
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Azure.Provisioning.CloudMachine
2+
{
3+
public partial class CloudMachineInfrastructure : Azure.Provisioning.Infrastructure
4+
{
5+
public CloudMachineInfrastructure(string? name = "cm") : base (default(string)) { }
6+
public Azure.Provisioning.BicepParameter PrincipalIdParameter { get { throw null; } }
7+
public Azure.Provisioning.BicepParameter PrincipalNameParameter { get { throw null; } }
8+
public Azure.Provisioning.BicepParameter PrincipalTypeParameter { get { throw null; } }
9+
public override Azure.Provisioning.ProvisioningPlan Build(Azure.Provisioning.ProvisioningContext? context = null) { throw null; }
10+
}
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<Description>Azure.Provisioning.CloudMachine simplifies declarative resource provisioning in .NET.</Description>
5+
<Version>1.0.0-beta.1</Version>
6+
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
7+
<LangVersion>12</LangVersion>
8+
9+
<!-- Disable warning CS1591: Missing XML comment for publicly visible type or member -->
10+
<NoWarn>CS1591</NoWarn>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Azure.Provisioning.Storage" VersionOverride="1.0.0-alpha.20240918.3" />
15+
<PackageReference Include="Azure.Provisioning.ServiceBus" VersionOverride="1.0.0-alpha.20240918.3" />
16+
<PackageReference Include="Azure.Provisioning.EventGrid" VersionOverride="1.0.0-alpha.20240918.1" />
17+
</ItemGroup>
18+
19+
</Project>
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Provisioning.Authorization;
5+
using Azure.Provisioning.EventGrid;
6+
using Azure.Provisioning.Expressions;
7+
using Azure.Provisioning.Resources;
8+
using Azure.Provisioning.Roles;
9+
using Azure.Provisioning.ServiceBus;
10+
using Azure.Provisioning.Storage;
11+
12+
namespace Azure.Provisioning.CloudMachine;
13+
14+
public class CloudMachineInfrastructure : Infrastructure
15+
{
16+
private readonly string _name;
17+
private UserAssignedIdentity _identity;
18+
private StorageAccount _storage;
19+
private BlobService _blobs;
20+
private BlobContainer _container;
21+
private ServiceBusNamespace _serviceBusNamespace;
22+
private ServiceBusNamespaceAuthorizationRule _serviceBusNamespaceAuthorizationRule;
23+
private ServiceBusTopic _serviceBusTopic_main;
24+
private ServiceBusTopic _serviceBusTopic_app;
25+
private ServiceBusSubscription _serviceBusSubscription_main;
26+
private ServiceBusSubscription _serviceBusSubscription_app;
27+
private SystemTopic _eventGridTopic_Blobs;
28+
private SystemTopicEventSubscription _systemTopicEventSubscription;
29+
30+
/// <summary>
31+
/// The common principalId parameter.
32+
/// </summary>
33+
public BicepParameter PrincipalIdParameter => new BicepParameter("principalId", typeof(string));
34+
35+
/// <summary>
36+
/// The common principalType parameter.
37+
/// </summary>
38+
public BicepParameter PrincipalTypeParameter => new BicepParameter("principalType", typeof(string));
39+
40+
/// <summary>
41+
/// The common principalName parameter.
42+
/// </summary>
43+
public BicepParameter PrincipalNameParameter => new BicepParameter("principalName", typeof(string));
44+
45+
public CloudMachineInfrastructure(string name = "cm") : base(name!)
46+
{
47+
_name = name ?? "cm";
48+
_identity = new($"{_name}_identity");
49+
ManagedServiceIdentity managedServiceIdentity = new()
50+
{
51+
ManagedServiceIdentityType = ManagedServiceIdentityType.UserAssigned,
52+
UserAssignedIdentities = { { BicepFunction.Interpolate($"{_identity.Id}").Compile().ToString(), new UserAssignedIdentityDetails() } }
53+
};
54+
55+
_storage = StorageResources.CreateAccount($"{_name}_sa");
56+
_storage.Identity = managedServiceIdentity;
57+
58+
_blobs = new($"{_name}_blobs")
59+
{
60+
Parent = _storage,
61+
};
62+
_container = new BlobContainer($"{_name}_container", "2023-01-01")
63+
{
64+
Parent = _blobs,
65+
Name = "default"
66+
};
67+
68+
_serviceBusNamespace = new($"{_name}_sb")
69+
{
70+
Sku = new ServiceBusSku
71+
{
72+
Name = ServiceBusSkuName.Standard,
73+
Tier = ServiceBusSkuTier.Standard
74+
},
75+
};
76+
_serviceBusNamespaceAuthorizationRule = new($"{_name}_sb_auth_rule", "2021-11-01")
77+
{
78+
Parent = _serviceBusNamespace,
79+
Rights = [ServiceBusAccessRight.Listen, ServiceBusAccessRight.Send, ServiceBusAccessRight.Manage]
80+
};
81+
_serviceBusTopic_main = new($"{_name}_sb_topic_main", "2021-11-01")
82+
{
83+
Parent = _serviceBusNamespace,
84+
MaxMessageSizeInKilobytes = 256,
85+
DefaultMessageTimeToLive = new StringLiteral("P14D"),
86+
RequiresDuplicateDetection = false,
87+
EnableBatchedOperations = true,
88+
SupportOrdering = true,
89+
Status = ServiceBusMessagingEntityStatus.Active
90+
};
91+
_serviceBusSubscription_main = new($"{_name}_sb_sub_main", "2021-11-01")
92+
{
93+
Parent = _serviceBusTopic_main,
94+
IsClientAffine = false,
95+
LockDuration = new StringLiteral("PT30S"),
96+
RequiresSession = false,
97+
DefaultMessageTimeToLive = new StringLiteral("P14D"),
98+
DeadLetteringOnFilterEvaluationExceptions = true,
99+
DeadLetteringOnMessageExpiration = true,
100+
MaxDeliveryCount = 10,
101+
EnableBatchedOperations = true,
102+
Status = ServiceBusMessagingEntityStatus.Active
103+
};
104+
_serviceBusTopic_app = new($"{_name}_sb_topic_app", "2021-11-01")
105+
{
106+
Parent = _serviceBusNamespace,
107+
// Name = "default",
108+
MaxMessageSizeInKilobytes = 256,
109+
DefaultMessageTimeToLive = new StringLiteral("P14D"),
110+
RequiresDuplicateDetection = false,
111+
EnableBatchedOperations = true,
112+
SupportOrdering = true,
113+
Status = ServiceBusMessagingEntityStatus.Active
114+
};
115+
_serviceBusSubscription_app = new($"{_name}_sb_sub_app", "2021-11-01")
116+
{
117+
Parent = _serviceBusTopic_app,
118+
IsClientAffine = false,
119+
LockDuration = new StringLiteral("PT30S"),
120+
RequiresSession = false,
121+
DefaultMessageTimeToLive = new StringLiteral("P14D"),
122+
DeadLetteringOnFilterEvaluationExceptions = true,
123+
DeadLetteringOnMessageExpiration = true,
124+
MaxDeliveryCount = 10,
125+
EnableBatchedOperations = true,
126+
Status = ServiceBusMessagingEntityStatus.Active
127+
};
128+
_eventGridTopic_Blobs = new($"{_name}_eg_blob", "2022-06-15")
129+
{
130+
TopicType = "Microsoft.Storage.StorageAccounts",
131+
Source = _storage.Id,
132+
Identity = managedServiceIdentity
133+
};
134+
_systemTopicEventSubscription = new($"{_name}_eg_blob_sub", "2022-06-15")
135+
{
136+
Parent = _eventGridTopic_Blobs,
137+
DeliveryWithResourceIdentity = new DeliveryWithResourceIdentity
138+
{
139+
Identity = new EventSubscriptionIdentity
140+
{
141+
IdentityType = EventSubscriptionIdentityType.UserAssigned,
142+
UserAssignedIdentity = _identity.Id
143+
},
144+
Destination = new EventHubEventSubscriptionDestination
145+
{
146+
ResourceId = _serviceBusTopic_main.Id
147+
}
148+
},
149+
Filter = new EventSubscriptionFilter
150+
{
151+
IncludedEventTypes =
152+
[
153+
"Microsoft.Storage.BlobCreated",
154+
"Microsoft.Storage.BlobDeleted",
155+
"Microsoft.Storage.BlobRenamed"
156+
],
157+
IsAdvancedFilteringOnArraysEnabled = true
158+
},
159+
EventDeliverySchema = EventDeliverySchema.EventGridSchema,
160+
RetryPolicy = new EventSubscriptionRetryPolicy
161+
{
162+
MaxDeliveryAttempts = 30,
163+
EventTimeToLiveInMinutes = 1440
164+
}
165+
};
166+
}
167+
168+
public override ProvisioningPlan Build(ProvisioningContext? context = null)
169+
{
170+
// Always add a default location parameter.
171+
// azd assumes there will be a location parameter for every module.
172+
// The Infrastructure location resolver will resolve unset Location properties to this parameter.
173+
Add(new BicepParameter("location", typeof(string))
174+
{
175+
Description = "The location for the resource(s) to be deployed.",
176+
Value = BicepFunction.GetResourceGroup().Location
177+
});
178+
179+
Add(PrincipalIdParameter);
180+
Add(PrincipalTypeParameter);
181+
Add(PrincipalNameParameter);
182+
183+
Add(_identity);
184+
Add(_storage);
185+
Add(_storage.AssignRole(StorageBuiltInRole.StorageBlobDataContributor, RoleManagementPrincipalType.User, PrincipalIdParameter));
186+
Add(_storage.AssignRole(StorageBuiltInRole.StorageTableDataContributor, RoleManagementPrincipalType.User, PrincipalIdParameter));
187+
Add(_container);
188+
Add(_blobs);
189+
Add(_serviceBusNamespace);
190+
Add(_serviceBusNamespace.AssignRole(ServiceBusBuiltInRole.AzureServiceBusDataOwner, RoleManagementPrincipalType.User, PrincipalIdParameter));
191+
Add(_serviceBusNamespaceAuthorizationRule);
192+
Add(_serviceBusTopic_main);
193+
Add(_serviceBusTopic_app);
194+
Add(_serviceBusSubscription_main);
195+
Add(_serviceBusSubscription_app);
196+
197+
// This is necessary until SystemTopic adds an AssignRole method.
198+
var role = ServiceBusBuiltInRole.AzureServiceBusDataOwner;
199+
RoleAssignment roleAssignment = new RoleAssignment(_eventGridTopic_Blobs.ResourceName + "_" + _identity.ResourceName + "_" + ServiceBusBuiltInRole.GetBuiltInRoleName(role));
200+
roleAssignment.Name = BicepFunction.CreateGuid(_eventGridTopic_Blobs.Id, _identity.Id, BicepFunction.GetSubscriptionResourceId("Microsoft.Authorization/roleDefinitions", role.ToString()));
201+
roleAssignment.Scope = new IdentifierExpression(_eventGridTopic_Blobs.ResourceName);
202+
roleAssignment.PrincipalType = RoleManagementPrincipalType.ServicePrincipal;
203+
roleAssignment.RoleDefinitionId = BicepFunction.GetSubscriptionResourceId("Microsoft.Authorization/roleDefinitions", role.ToString());
204+
roleAssignment.PrincipalId = _identity.PrincipalId;
205+
Add(roleAssignment);
206+
Add(_systemTopicEventSubscription);
207+
Add(_eventGridTopic_Blobs);
208+
209+
// Placeholders for now.
210+
Add(new BicepOutput($"storage_name", typeof(string)) { Value = _storage.Name });
211+
Add(new BicepOutput($"servicebus_name", typeof(string)) { Value = _serviceBusNamespace.Name });
212+
213+
return base.Build(context);
214+
}
215+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Diagnostics.CodeAnalysis;
5+
6+
[assembly: Experimental("AZPROVISION001")]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<LangVersion>12</LangVersion>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<ProjectReference Include="..\..\..\core\Azure.Core.TestFramework\src\Azure.Core.TestFramework.csproj" />
7+
<ProjectReference Include="..\src\Azure.Provisioning.CloudMachine.csproj" />
8+
</ItemGroup>
9+
</Project>

sdk/provisioning/Azure.Provisioning.sln

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Provisioning.WebPubSu
106106
EndProject
107107
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Provisioning.WebPubSub.Tests", "Azure.Provisioning.WebPubSub\tests\Azure.Provisioning.WebPubSub.Tests.csproj", "{015670AB-881C-464F-8545-E686C9A92C4F}"
108108
EndProject
109+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Provisioning.CloudMachine", "Azure.Provisioning.CloudMachine", "{DB2FC0CB-7103-4D3C-A737-8C6AB61168F8}"
110+
EndProject
111+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Provisioning.CloudMachine", "Azure.Provisioning.CloudMachine\src\Azure.Provisioning.CloudMachine.csproj", "{F54CA64F-3BB8-49D5-AE3B-3408AE324632}"
112+
EndProject
113+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Provisioning.CloudMachine.Tests", "Azure.Provisioning.CloudMachine\tests\Azure.Provisioning.CloudMachine.Tests.csproj", "{94642992-7CC0-4649-B58F-8E5E3F134C8A}"
114+
EndProject
109115
Global
110116
GlobalSection(SolutionConfigurationPlatforms) = preSolution
111117
Debug|Any CPU = Debug|Any CPU
@@ -308,11 +314,23 @@ Global
308314
{015670AB-881C-464F-8545-E686C9A92C4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
309315
{015670AB-881C-464F-8545-E686C9A92C4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
310316
{015670AB-881C-464F-8545-E686C9A92C4F}.Release|Any CPU.Build.0 = Release|Any CPU
317+
{F54CA64F-3BB8-49D5-AE3B-3408AE324632}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
318+
{F54CA64F-3BB8-49D5-AE3B-3408AE324632}.Debug|Any CPU.Build.0 = Debug|Any CPU
319+
{F54CA64F-3BB8-49D5-AE3B-3408AE324632}.Release|Any CPU.ActiveCfg = Release|Any CPU
320+
{F54CA64F-3BB8-49D5-AE3B-3408AE324632}.Release|Any CPU.Build.0 = Release|Any CPU
321+
{94642992-7CC0-4649-B58F-8E5E3F134C8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
322+
{94642992-7CC0-4649-B58F-8E5E3F134C8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
323+
{94642992-7CC0-4649-B58F-8E5E3F134C8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
324+
{94642992-7CC0-4649-B58F-8E5E3F134C8A}.Release|Any CPU.Build.0 = Release|Any CPU
311325
EndGlobalSection
312326
GlobalSection(SolutionProperties) = preSolution
313327
HideSolutionNode = FALSE
314328
EndGlobalSection
315329
GlobalSection(ExtensibilityGlobals) = postSolution
316330
SolutionGuid = {7CB2D417-323C-4A66-9355-26459881303F}
317331
EndGlobalSection
332+
GlobalSection(NestedProjects) = preSolution
333+
{F54CA64F-3BB8-49D5-AE3B-3408AE324632} = {DB2FC0CB-7103-4D3C-A737-8C6AB61168F8}
334+
{94642992-7CC0-4649-B58F-8E5E3F134C8A} = {DB2FC0CB-7103-4D3C-A737-8C6AB61168F8}
335+
EndGlobalSection
318336
EndGlobal

sdk/provisioning/ci.compute.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ trigger:
1313
- sdk/provisioning/Azure.Provisioning.AppContainers
1414
- sdk/provisioning/Azure.Provisioning.ApplicationInsights
1515
- sdk/provisioning/Azure.Provisioning.AppService
16+
- sdk/provisioning/Azure.Provisioning.CloudMachine
1617
- sdk/provisioning/Azure.Provisioning.Communication
1718
- sdk/provisioning/Azure.Provisioning.ContainerRegistry
1819
- sdk/provisioning/Azure.Provisioning.ContainerService
@@ -37,6 +38,7 @@ pr:
3738
- sdk/provisioning/Azure.Provisioning.AppContainers
3839
- sdk/provisioning/Azure.Provisioning.ApplicationInsights
3940
- sdk/provisioning/Azure.Provisioning.AppService
41+
- sdk/provisioning/Azure.Provisioning.CloudMachine
4042
- sdk/provisioning/Azure.Provisioning.Communication
4143
- sdk/provisioning/Azure.Provisioning.ContainerRegistry
4244
- sdk/provisioning/Azure.Provisioning.ContainerService
@@ -62,6 +64,8 @@ extends:
6264
safeName: AzureProvisioningApplicationInsights
6365
- name: Azure.Provisioning.AppService
6466
safeName: AzureProvisioningAppService
67+
- name: Azure.Provisioning.CloudMachine
68+
safeName: AzureProvisioningCloudMachine
6569
- name: Azure.Provisioning.Communication
6670
safeName: AzureProvisioningCommunication
6771
- name: Azure.Provisioning.ContainerRegistry

0 commit comments

Comments
 (0)