Proposed Pull Request Change

title description ms.topic ms.service author ms.author ms.reviewer ms.date ms.custom
Deploy Azure Cloud Services (extended support) - SDK Deploy Azure Cloud Services (extended support) by using the Azure SDK. quickstart azure-virtual-machines gachandw gachandw mimckitt 07/24/2024 devx-track-azurepowershell
šŸ“„ Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: Deploy Azure Cloud Services (extended support) - SDK description: Deploy Azure Cloud Services (extended support) by using the Azure SDK. ms.topic: quickstart ms.service: azure-virtual-machines author: gachandw ms.author: gachandw ms.reviewer: mimckitt ms.date: 07/24/2024 ms.custom: devx-track-azurepowershell # Customer intent: As a cloud developer, I want to deploy Azure Cloud Services (extended support) using the SDK so that I can manage role-based applications and configurations programmatically through Resource Manager. --- # Deploy Cloud Services (extended support) by using the Azure SDK > [!IMPORTANT] > As of March 31, 2025, cloud Services (extended support) is deprecated and will be fully retired on March 31, 2027. [Learn more](https://aka.ms/csesretirement) about this deprecation and [how to migrate](https://aka.ms/cses-retirement-march-2025). This article shows how to use the [Azure SDK](https://azure.microsoft.com/downloads/) to create an Azure Cloud Services (extended support) deployment that has multiple roles (WebRole and WorkerRole). It also covers how to use the Remote Desktop Protocol (RDP) extension. Cloud Services (extended support) is a deployment model of Azure Cloud Services based on Azure Resource Manager. ## Prerequisites Review the [deployment prerequisites](deploy-prerequisite.md) for Cloud Services (extended support) and create the required resources. ## Deploy Cloud Services (extended support) To deploy Cloud Services (extended support) by using the SDK: 1. Install the [Azure Compute SDK NuGet package](https://www.nuget.org/packages/Microsoft.Azure.Management.Compute/43.0.0-preview) and initialize the client by using a standard authentication method: ```csharp public class CustomLoginCredentials : ServiceClientCredentials { private string AuthenticationToken { get; set; } public override void InitializeServiceClient<T>(ServiceClient<T> client) { var authenticationContext = new AuthenticationContext("https://login.windows.net/{tenantID}"); var credential = new ClientCredential(clientId: "{clientID}", clientSecret: "{clientSecret}"); var result = authenticationContext.AcquireTokenAsync(resource: "https://management.core.windows.net/", clientCredential: credential); if (result == null) throw new InvalidOperationException("Failed to obtain the JWT"); AuthenticationToken = result.Result.AccessToken; } public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) throw new ArgumentNullException("request"); if (AuthenticationToken == null) throw new InvalidOperationException("Token Provider Cannot Be Null"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //request.Version = new Version(apiVersion); await base.ProcessHttpRequestAsync(request, cancellationToken); } } var creds = new CustomLoginCredentials(); m_subId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID"); ResourceManagementClient m_ResourcesClient = new ResourceManagementClient(creds); NetworkManagementClient m_NrpClient = new NetworkManagementClient(creds); ComputeManagementClient m_CrpClient = new ComputeManagementClient(creds); StorageManagementClient m_SrpClient = new StorageManagementClient(creds); m_ResourcesClient.SubscriptionId = m_subId; m_NrpClient.SubscriptionId = m_subId; m_CrpClient.SubscriptionId = m_subId; m_SrpClient.SubscriptionId = m_subId; ``` 1. Create a new resource group by installing the Azure Resource Manager NuGet package: ```csharp var resourceGroups = m_ResourcesClient.ResourceGroups; var m_location = ā€œEast USā€; var resourceGroupName = "ContosoRG";//provide existing resource group name, if created already var resourceGroup = new ResourceGroup(m_location); resourceGroup = await resourceGroups.CreateOrUpdateAsync(resourceGroupName, resourceGroup); ``` 1. Create a storage account and container where you store the package (.cspkg or .zip) file and configuration (.cscfg) file for the deployment. Install the [Azure Storage NuGet package](https://www.nuget.org/packages/Azure.Storage.Common/). This step is optional if you're using an existing storage account. The storage account name must be unique. ```csharp string storageAccountName = ā€œContosoSASā€ var stoInput = new StorageAccountCreateParameters { Location = m_location, Kind = Microsoft.Azure.Management.Storage.Models.Kind.StorageV2, Sku = new Microsoft.Azure.Management.Storage.Models.Sku(SkuName.StandardRAGRS), }; StorageAccount storageAccountOutput = m_SrpClient.StorageAccounts.Create(rgName, storageAccountName, stoInput); bool created = false; while (!created) { Thread.Sleep(600); var stos = m_SrpClient.StorageAccounts.ListByResourceGroup(rgName); created = stos.Any( t => StringComparer.OrdinalIgnoreCase.Equals(t.Name, storageAccountName)); } StorageAccount storageAccountOutput = m_SrpClient.StorageAccounts.GetProperties(rgName, storageAccountName);. var accountKeyResult = m_SrpClient.StorageAccounts.ListKeysWithHttpMessagesAsync(rgName, storageAccountName).Result; CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(storageAccountName, accountKeyResult.Body.Keys.FirstOrDefault(). Value), useHttps: true); var blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference("sascontainer"); container.CreateIfNotExistsAsync().Wait(); sharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy(); sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddDays(-1); sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddDays(2); sasConstraints.Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write; ``` 1. Upload the package (.cspkg or .zip) file to the storage account. The package URL can be a shared access signature (SAS) URI from any storage account. ```csharp CloudBlockBlob cspkgblockBlob = container.GetBlockBlobReference(ā€œContosoApp.cspkgā€); cspkgblockBlob.UploadFromFileAsync(ā€œ./ContosoApp/ContosoApp.cspkgā€). Wait(); //Generate the shared access signature on the blob, setting the constraints directly on the signature. string cspkgsasContainerToken = cspkgblockBlob.GetSharedAccessSignature(sasConstraints); //Return the URI string for the container, including the SAS token. string cspkgSASUrl = cspkgblockBlob.Uri + cspkgsasContainerToken; ``` 1. Upload the configuration (.cscfg) file to the storage account. Specify the service configuration as either string XML or URL format. ```csharp CloudBlockBlob cscfgblockBlob = container.GetBlockBlobReference(ā€œContosoApp.cscfgā€); cscfgblockBlob.UploadFromFileAsync(ā€œ./ContosoApp/ContosoApp.cscfgā€). Wait(); //Generate the shared access signature on the blob, setting the constraints directly on the signature. string sasCscfgContainerToken = cscfgblockBlob.GetSharedAccessSignature(sasConstraints); //Return the URI string for the container, including the SAS token. string cscfgSASUrl = cscfgblockBlob.Uri + sasCscfgContainerToken; ``` 1. Create a virtual network and subnet. Install the [Azure Network NuGet package](https://www.nuget.org/packages/Azure.ResourceManager.Network/). This step is optional if you're using an existing network and subnet. ```csharp VirtualNetwork vnet = new VirtualNetwork(name: vnetName) { AddressSpace = new AddressSpace { AddressPrefixes = new List<string> { "10.0.0.0/16" } }, Subnets = new List<Subnet> { new Subnet(name: subnetName) { AddressPrefix = "10.0.0.0/24" } }, Location = m_location }; m_NrpClient.VirtualNetworks.CreateOrUpdate(resourceGroupName, ā€œContosoVNetā€, vnet); ``` 1. Create a public IP address and set the DNS label property of the public IP address. Cloud Services (extended support) supports only a [Basic](../virtual-network/ip-services/public-ip-addresses.md#sku) SKU public IP address. Standard SKU public IP addresses do not work with Cloud Services (extended support). If you use a static IP address, you must reference it as a reserved IP address in the configuration (.cscfg) file. ```csharp PublicIPAddress publicIPAddressParams = new PublicIPAddress(name: ā€œContosIpā€) { Location = m_location, PublicIPAllocationMethod = IPAllocationMethod.Dynamic, DnsSettings = new PublicIPAddressDnsSettings() { DomainNameLabel = ā€œcontosoappdnsā€ } }; PublicIPAddress publicIpAddress = m_NrpClient.PublicIPAddresses.CreateOrUpdate(resourceGroupName, publicIPAddressName, publicIPAddressParams); ``` 1. Create a network profile object and associate the public IP address with the front end of the load balancer. The Azure platform automatically creates a Classic SKU load balancer resource in the same subscription as the deployment. The load balancer resource is read-only in Azure Resource Manager. You can update the resource only via the Cloud Services (extended support) configuration (.cscfg) file and definition (.csdef) file. ```csharp LoadBalancerFrontendIPConfiguration feipConfiguration = new LoadBalancerFrontendIPConfiguration() { Name = ā€œContosoFeā€, Properties = new LoadBalancerFrontendIPConfigurationProperties() { PublicIPAddress = new CM.SubResource() { Id = $"/subscriptions/{m_subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPAddresses/{publicIPAddressName}", } } }; CloudServiceNetworkProfile cloudServiceNetworkProfile = new CloudServiceNetworkProfile() { LoadBalancerConfigurations = new List<LoadBalancerConfiguration>() { new LoadBalancerConfiguration() { Name = 'ContosoLB', Properties = new LoadBalancerConfigurationProperties() { FrontendIPConfigurations = new List<LoadBalancerFrontendIPConfiguration>() { feipConfig } } } } }; ``` 1. Create a key vault. This key vault stores certificates that are associated with the Cloud Services (extended support) roles. The key vault must be in the same region and subscription as the Cloud Services (extended support) resource and have a unique name. For more information, see [Use certificates with Cloud Services (extended support)](certificates-and-key-vault.md). ```powershell New-AzKeyVault -Name "ContosKeyVaultā€ -ResourceGroupName ā€œContosoOrgā€ -Location ā€œEast USā€ ``` 1. Update the key vault's access policy and grant certificate permissions to your user account: ```powershell Set-AzKeyVaultAccessPolicy -VaultName 'ContosKeyVault' -ResourceGroupName 'ContosoOrg' -UserPrincipalName 'user@domain.com' -PermissionsToCertificates create,get,list,delete ``` Alternatively, set the access policy via object ID (which you can get by running `Get-AzADUser`): ```powershell Set-AzKeyVaultAccessPolicy -VaultName 'ContosKeyVault' -ResourceGroupName 'ContosOrg' -ObjectId 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' -PermissionsToCertificates create,get,list,delete ``` 1. The following example adds a self-signed certificate to a key vault. The certificate thumbprint must be added in the configuration (.cscfg) file for Cloud Services (extended support) roles. ```powershell $Policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" - SubjectName "CN=contoso.com" -IssuerName "Self" -ValidityInMonths 6 -ReuseKeyOnRenewal Add-AzKeyVaultCertificate -VaultName "ContosKeyVault" -Name "ContosCert" -CertificatePolicy $Policy ``` 1. Create an OS profile object. The OS profile specifies the certificates that are associated with Cloud Services (extended support) roles. You use the same certificate that you created in the preceding step. ```csharp CloudServiceOsProfile cloudServiceOsProfile = new CloudServiceOsProfile { Secrets = new List<CloudServiceVaultSecretGroup> { New CloudServiceVaultSecretGroup { SourceVault = <sourceVault>, VaultCertificates = <vaultCertificates> } } }; ``` 1. Create a role profile object. A role profile defines role-specific properties for a SKU, such as name, capacity, and tier. This example defines two roles: ContosoFrontend and ContosoBackend. Role profile information must match the role defined in the configuration (.cscfg) file and definition (.csdef) file. ```csharp CloudServiceRoleProfile cloudServiceRoleProfile = new CloudServiceRoleProfile() { Roles = new List<CloudServiceRoleProfileProperties>(); // foreach role in cloudService roles.Add(new CloudServiceRoleProfileProperties() { Name = 'ContosoFrontend', Sku = new CloudServiceRoleSku { Name = 'Standard_D1_v2', Capacity = 2, Tier = 'Standard' } ); roles.Add(new CloudServiceRoleProfileProperties() { Name = 'ContosoBackend', Sku = new CloudServiceRoleSku { Name = 'Standard_D1_v2', Capacity = 2, Tier = 'Standard' } ); } } ``` 1. (Optional) Create an extension profile object to add to your Cloud Services (extended support) deployment. This example adds a Remote Desktop Protocol (RDP) extension: ```csharp string rdpExtensionPublicConfig = "<PublicConfig>" + "<UserName>adminRdpTest</UserName>" + "<Expiration>2021-10-27T23:59:59</Expiration>" + "</PublicConfig>"; string rdpExtensionPrivateConfig = "<PrivateConfig>" + "<Password>VsmrdpTest!</Password>" + "</PrivateConfig>"; Extension rdpExtension = new Extension { Name = name, Properties = new CloudServiceExtensionProperties { Publisher = "Microsoft.Windows.Azure.Extensions", Type = "RDP", TypeHandlerVersion = "1.2.1", AutoUpgradeMinorVersion = true, Settings = rdpExtensionPublicConfig, ProtectedSettings = rdpExtensionPrivateConfig, RolesAppliedTo = [ā€œ*ā€], } }; CloudServiceExtensionProfile cloudServiceExtensionProfile = new CloudServiceExtensionProfile { Extensions = rdpExtension }; ``` 1. Create the Cloud Services (extended support) deployment: ```csharp CloudService cloudService = new CloudService { Properties = new CloudServiceProperties { RoleProfile = cloudServiceRoleProfile Configuration = < Add Cscfg xml content here>, // ConfigurationUrl = <Add your configuration URL here>, PackageUrl = <Add cspkg SAS url here>, ExtensionProfile = cloudServiceExtensionProfile, OsProfile= cloudServiceOsProfile, NetworkProfile = cloudServiceNetworkProfile, UpgradeMode = 'Auto' }, Location = m_location }; CloudService createOrUpdateResponse = m_CrpClient.CloudServices.CreateOrUpdate(ā€œContosOrgā€, ā€œContosoCSā€, cloudService); ``` ## Related content - Review [frequently asked questions](faq.yml) for Cloud Services (extended support). - Deploy Cloud Services (extended support) by using the [Azure portal](deploy-portal.md), [Azure PowerShell](deploy-powershell.md), an [ARM template](deploy-template.md), or [Visual Studio](deploy-visual-studio.md). - Visit the [Cloud Services (extended support) samples repository](https://github.com/Azure-Samples/cloud-services-extended-support).
Success! Branch created successfully. Create Pull Request on GitHub
Error: