Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
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).