I'm CSP partner and need to do following.
Is it possible to perform operations available here:
https://docs.microsoft.com/en-gb/azure/azure-resource-manager/programmatically-create-subscription?tabs=rest
I'm using partner center registered web app (app that is allowed to call Partner Center API through admin consent - has it's secret and app Id - is both registered within Partner Center and Azure Portal) that I would like to perform above rest requests.
Do I need any special setup for this web app - scopes or permissions? When queried
https://management.azure.com/providers/Microsoft.Billing/billingAccounts?api-version=2019-10-01-preview
I get empty response.
We already use mentioned web app to perform various tasks using Partner Center SDK API along with some other Azure APIs (Graph). It has Access Azure Service Management permission (user_impersonation) in Azure configuration.
0
votes
Could you please describe your issue in detail and tell me what is "partner center registered web app"?
- Jim Xu
Is that you are CSP Partner and you want to create Azure CSP subscription for one customer?
- Jim Xu
Please see my edit. I have multiple clients managed by my CSP tenant. I'm currently purchasing azure plans for them using Partner Center SDK, for those plans I would like to purchase additional azure plan usage subscriptions and for this I need to call Azure Management APIs (Microsoft.Billing namely).
- afrosz
Could you please tell me what is "additional azure plan usage subscriptions"?
- Jim Xu
After azure plan is purchased you can purchase addtiional azure usage subscriptions under that azure plan. When you purchase azure plan through Partner Center SDK one azure usage subscription is created automatically within Azure. This so far is only possible through Azure Portal - in subscriptions menu.
- afrosz
1 Answers
0
votes
According to my understanding, you have created Azure CSP subscriptions. Now you want to create Azure resource in the CSP subscription. Please refer to the following steps.
-
I use the powershell script(createCSPapplication.ps1) to create application
<#
.SYNOPSIS
This script will create the require Azure AD application.
.EXAMPLE
.\Create-AzureADApplication.ps1 -ConfigurePreconsent -DisplayName "Partner Center Web App"
.\Create-AzureADApplication.ps1 -ConfigurePreconsent -DisplayName "Partner Center Web App" -TenantId eb210c1e-b697-4c06-b4e3-8b104c226b9a
.\Create-AzureADApplication.ps1 -ConfigurePreconsent -DisplayName "Partner Center Web App" -TenantId tenant01.onmicrosoft.com
.PARAMETER ConfigurePreconsent
Flag indicating whether or not the Azure AD application should be configured for preconsent.
.PARAMETER DisplayName
Display name for the Azure AD application that will be created.
.PARAMETER TenantId
[OPTIONAL] The domain or tenant identifier for the Azure AD tenant that should be utilized to create the various resources.
#>
Param
(
[Parameter(Mandatory = $true)]
[switch]$ConfigurePreconsent,
[Parameter(Mandatory = $true)]
[string]$DisplayName,
[Parameter(Mandatory = $false)]
[string]$TenantId
)
$ErrorActionPreference = "Stop"
# Check if the Azure AD PowerShell module has already been loaded.
if ( ! ( Get-Module AzureAD ) ) {
# Check if the Azure AD PowerShell module is installed.
if ( Get-Module -ListAvailable -Name AzureAD ) {
# The Azure AD PowerShell module is not load and it is installed. This module
# must be loaded for other operations performed by this script.
Write-Host -ForegroundColor Green "Loading the Azure AD PowerShell module..."
Import-Module AzureAD
} else {
Install-Module AzureAD
}
}
try {
Write-Host -ForegroundColor Green "When prompted please enter the appropriate credentials..."
if([string]::IsNullOrEmpty($TenantId)) {
Connect-AzureAD | Out-Null
$TenantId = $(Get-AzureADTenantDetail).ObjectId
} else {
Connect-AzureAD -TenantId $TenantId | Out-Null
}
} catch [Microsoft.Azure.Common.Authentication.AadAuthenticationCanceledException] {
# The authentication attempt was canceled by the end-user. Execution of the script should be halted.
Write-Host -ForegroundColor Yellow "The authentication attempt was canceled. Execution of the script will be halted..."
Exit
} catch {
# An unexpected error has occurred. The end-user should be notified so that the appropriate action can be taken.
Write-Error "An unexpected error has occurred. Please review the following error message and try again." `
"$($Error[0].Exception)"
}
$adAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "00000002-0000-0000-c000-000000000000";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "5778995a-e1bf-45b8-affa-663a9f3f4d04";
Type = "Role"},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "a42657d6-7f20-40e3-b6f0-cee03008a62a";
Type = "Scope"},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6";
Type = "Scope"}
}
$graphAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "00000003-0000-0000-c000-000000000000";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "bf394140-e372-4bf9-a898-299cfc7564e5";
Type = "Role"},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "7ab1d382-f21e-4acd-a863-ba3e13f7da61";
Type = "Role"}
}
$partnerCenterAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "1cebfa2a-fb4d-419e-b5f9-839b4383e05a";
Type = "Scope"}
}
$SessionInfo = Get-AzureADCurrentSessionInfo
Write-Host -ForegroundColor Green "Creating the Azure AD application and related resources..."
$app = New-AzureADApplication -AvailableToOtherTenants $true -DisplayName $DisplayName -IdentifierUris "https://$($SessionInfo.TenantDomain)/$((New-Guid).ToString())" -RequiredResourceAccess $adAppAccess, $graphAppAccess, $partnerCenterAppAccess -ReplyUrls @("urn:ietf:wg:oauth:2.0:oob")
$password = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId
$spn = New-AzureADServicePrincipal -AppId $app.AppId -DisplayName $DisplayName
if($ConfigurePreconsent) {
$adminAgentsGroup = Get-AzureADGroup -Filter "DisplayName eq 'AdminAgents'"
Add-AzureADGroupMember -ObjectId $adminAgentsGroup.ObjectId -RefObjectId $spn.ObjectId
}
Write-Host "ApplicationId = $($app.AppId)"
Write-Host "ApplicationSecret = $($password.Value)"
- Perform the consent
Install-Module -Name PartnerCenter -RequiredVersion 1.5.1908.1
$secpasswd = ConvertTo-SecureString "<app secret>" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("<app id>", $secpasswd)
$token = New-PartnerAccessToken -Consent -Credential $mycreds -Resource https://api.partnercenter.microsoft.com -ServicePrincipal # it will open a window to login, please use CSP admin account to login
- Login Azure
Install-Module -Name Az -RequiredVersion 3.1.0
$secpasswd = ConvertTo-SecureString "<app secret>" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("<app id>", $secpasswd)
$token = New-PartnerAccessToken -Consent -Credential $mycreds -Resource https://api.partnercenter.microsoft.com -ServicePrincipal # it will open a window to login, please use CSP admin account to login
$refreshToken=$token.RefreshToken
$azureToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://management.azure.com/ -Credential $mycreds -TenantId '<the name or id of the customer’s tenant>'
$graphToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.windows.net -Credential $mycreds -TenantId '<the name or id of the customer’s tenant>'
Connect-AzAccount -AccessToken $azureToken.AccessToken -GraphAccessToken $graphToken.AccessToken -TenantId '<the name or id of the customer’s tenant>' -AccountId '<your CSP admin account>'
- Create Azure resource. For more details, please refer to the document
Update
Regarding how to create Azure resource, please refer to the following steps
- Get refresh token
$secpasswd = ConvertTo-SecureString "<app secret>" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("<app id>", $secpasswd)
$token = New-PartnerAccessToken -Consent -Credential $mycreds -Resource https://api.partnercenter.microsoft.com -ServicePrincipal # it will open a window to login, please use CSP admin account to login
$refreshToken=$token.RefreshToken
- Code
static RestClient client = new RestClient();
async static Task Main(string[] args)
{
// install RestSharp to call rest api : Install-Package RestSharp -Version 106.6.10
// get access token
string customerTenatId = "<the name or id of the customer’s tenant>";
string clientId = "<app id>";
string clientSecret = "<app secret>";
string refreshToken = "";
string aadInstance = "https://login.windows.net/";
string authContextURL = aadInstance + customerTenatId;
string loginUrl = string.Format("{0}/oauth2/token", authContextURL);
string content = string.Format(
"resource={0}&client_id={1}&client_secret={2}&grant_type=refresh_token&refresh_token={3}&scope=openid",
HttpUtility.UrlEncode("https://management.azure.com/"),
HttpUtility.UrlEncode(clientId),
HttpUtility.UrlEncode(clientSecret),
HttpUtility.UrlEncode(refreshToken));
client.BaseUrl = new Uri(loginUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("test", content, ParameterType.RequestBody);
IRestResponse response = await client.ExecuteTaskAsync(request);
JObject adResponse = JsonConvert.DeserializeObject<JObject>(response.Content);
var accessToken = adResponse["access_token"].ToString();
// call Azure rest api
}