Tuesday, August 31, 2021

 Azure Pipeline

Introduction: This article is a continuation of the series of articles starting with the description of SignalR service which was followed by a discussion on Azure Gateway service, Azure Private Link, and Azure Private Endpoint and the benefit of diverting traffic to the Azure Backbone network. Then we started reviewing a more public internet-facing service such as the Bing API. and the benefits it provided when used together with Azure Cognitive Services. We now focus internally with infrastructure API such as Provider API and ARM resources and follow it up with a discussion on the Azure Pipeline. 

Description:    

Azure Pipeline is a CI/CD service whose importance is unquestioned. Continuous Integration is the process by which software is tested and continuously merged into a release vehicle. Automated tests assure the quality of the code as it flows to release and facilitate different gates for controlling the flow of code from source to destination. Continuous Deployment is the process by which code is build, tested and deployed to one or more test or production environments. Deployment alleviates the concern that the code may not work under certain conditions by trying it out in controlled environments. Azure pipeline is notable for CI/CD purposes because it supports the following scenarios: 1) working with any language or platform to build, test and deploy code, 2) deploying to different types of targets at the same time, 3) integrating with Azure deployments and building on Windows, Linux or Mac machines and 4) working with all major source control repositories as well as open source. 

Azure Pipelines deploy code to target which can be a virtual machine, environment, container, on-premises, and cloud platforms or PaaS services. It can also publish a mobile application or a store. A release definition helps automate the deployment of application to one or more environments. The automation process is defined as a collection of tasks.

Since it is a cloud service, it facilitates the build-deploy-test workflows both on-premises and in the cloud. Changes can be made and tested in a fast, scalable and efficient manner and the results are visible via rich analytics and reporting. When the build is done, the test results can be reviewed to resolve problems, if any. The build and deploy reports are core tools to the development and test teams of any organization.


Monday, August 30, 2021

Azure Provider API


Introduction: This article is a continuation of the series of articles starting with the description of SignalR service. We followed up with a discussion of Azure Gateway service, Azure Private Link, and Azure Private Endpoint and the benefit of diverting traffic to the Azure Backbone network. Then we started reviewing a more public internet-facing service such as the Bing API. We now focus internally with infrastructure API such as Provider API and ARM resources.

 

Description:   

Azure Provider API is probably the single most comprehensive reference API for almost all Azure resources. It is called Provider API because it has the added advantage of referring to individual Azure resource definitions categorized by their providers such as Microsoft.Cache, Microsoft.Compute, Microsoft.DocumentDB and others. 

With its support for REST API, Powershell, Azure CLI just like any other Azure cloud service, it becomes a one-stop shop to query and compare resources by their providers. For example, to know whether an Azure resoure can be provisioned with zone-redundancy, one can attempt the following:

function Get-AzReadyByProviderAndLocation() { 

    [CmdletBinding(SupportsShouldProcess)] 

    param ( 

        [Parameter(Mandatory=$true, HelpMessage="The subscription with which to lookup if availability zones exist.")][string]$SubscriptionId, 

        [Parameter(Mandatory=$true, HelpMessage="For example: West US 2")][string]$Location, 

        [Parameter(Mandatory=$true, HelpMessage="For example: Microsoft.Cache")][string]$Provider, 

        [Parameter(Mandatory=$true, HelpMessage="For example: Redis")][string]$ProviderType, 

        [string]$ResourceAccountWithType = "$($Provider)/$($ProviderType)", 

:

    )

 :

 $ApiUri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/$($Provider)?api-version=$ApiVersion" 

 $Headers = @{} 

 $Headers.Add("Authorization","$($TokenType) "+ " " + "$($TokenStr)") 

:

 $ApiUri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/$Provider?api-version=$ApiVersion"

 $azReadiness = Invoke-RestMethod -Method Get -Uri $ApiUri -Headers $Headers -ErrorAction Stop  

 $azReadinessForResource = $azReadiness.resourceTypes | Where-Object -filterscript { (($_.resourceType -eq $providerType) -and ($_.locations -contains $Location) -and ($_.zoneMappings.location -eq $location)) } 

 :


This service differs from Azure Resource Graph Provider API in that it is more concerned with resource providers and resource types, their permissions and management plane registration rather than a service that deploys the resources on the resource management plane. It is also certainly not to be confused with ProviderHub APIs.


Other than getting a wide variety of information on the providers by name, or organized within a subscription or tenant scope, the provider API is used to register a subscription or a management group with a resource provider. Registering is an important step and a prerequisite before a resource can be instantiated by that resource provider for a specific type of resource because a public access by default could invite malicious usages. That said, some resource providers are registered by default. For example, Microsoft.ADHybridHealthService, Microsoft.Authorization, Microsoft.Billing, Microsoft.ClassicSubscription, Microsoft.Commerce, Microsoft.Consumption, Microsoft.Features, Microsoft.MarketplaceOrdering, Microsoft.Portal, Microsoft.ResourceGraph, Microsoft.Resources, Microsoft.SerialConsole, and Microsoft.Support are already registered for all end-users. 

If an Azure Resource Manager Template is used to deploy a resource, any required resource providers are also registered.

The registration status for all resource providers for a given subscription can be found using:

Get-AzResourceProvider -ListAvailable | Select-Object ProviderNamespace, RegistrationState.

Provider permissions for a resource list permission by role. Access policies and compliance can be managed effectively with a management group that spans multiple Azure subscriptions. Registration of a management group with a resource provider is just as easy as the registration of a single subscription. 


Finally, resource providers are supported in all regions unlike the resources that may be supported only in some regions.


Conclusion: These are the ways in which the Provider API can be used, and it is available as just another cloud resource along with the benefits that come with a cloud service.


Sunday, August 29, 2021

<# 

  

.SYNOPSIS 

  

This script can be called from a runbook and uses Azure REST methods for resource related helper cmdlets. 

This module shows how to query if a resource can be provisioned with zone redundacy using the Provider API and client secret based authentication. 

#https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow 

#please refer the module members exported from this library for details. 

#> 

  

  

  

function Get-Payload() { 

param ( 

    [Parameter(Mandatory=$true)][string]$ClientId, 

    [Parameter(Mandatory=$true)][string]$ClientSecret, 

    [string]$Resource = "https://management.core.windows.net/" 

) 

    $Encoded=[System.Web.HttpUtility]::UrlEncode($ClientSecret) 

    $Payload = "grant_type=client_credentials&client_id=$ClientId&client_secret=$Encoded&resource=$Resource" 

    return $Payload 

} 

  

function Get-Token(){ 

param ( 

    [Parameter(Mandatory=$true)][string]$TenantId, 

    [Parameter(Mandatory=$true)][string]$ClientId, 

    [Parameter(Mandatory=$true)][string]$ClientSecret, 

    [string]$Resource = "https://management.core.windows.net/", 

     [string]$RequestAccessTokenUri = "https://login.microsoftonline.com/$TenantId/oauth2/token" 

) 

    $Payload = Get-Payload $ClientId $ClientSecret 

    $Token = Invoke-RestMethod -Method Post -Uri $RequestAccessTokenUri -body $Payload -ContentType 'application/x-www-form-urlencoded' 

    return $Token 

} 

<# 

  

.DESCRIPTION 

This returns true if the provider type and location supports availability zones. 

  

.PARAMETER subscriptionId 

The subscription to the Azure with which the resource group must be found. 

  

.PARAMETER location 

The location where the provider type must be looked up. 

  

#> 

function Get-AzReadyByProviderAndLocation() { 

    [CmdletBinding(SupportsShouldProcess)] 

    param ( 

        [Parameter(Mandatory=$true, HelpMessage="The subscription with which to lookup if availability zones exist.")][string]$SubscriptionId, 

        [Parameter(Mandatory=$true, HelpMessage="For example: West US 2")][string]$Location, 

        [Parameter(Mandatory=$true, HelpMessage="For example: Microsoft.Cache")][string]$Provider, 

        [Parameter(Mandatory=$true, HelpMessage="For example: Redis")][string]$ProviderType, 

        [string]$ResourceAccountWithType = "$($Provider)/$($ProviderType)", 

        [string]$TenantId = "", 

        [string]$ResourceType = "redisCache", 

        [string]$ResourceName = "", 

        [string]$ResourceGroupName = "", 

        [string]$resourceId = "/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/$($ResourceAccountWithType)/$($ResourceName)", 

        [string]$ClientId = $null, 

        [string]$ClientSecret = $null, 

        [string]$Resource = "https://management.core.windows.net/", 

        [string]$RequestAccessTokenUri = "https://login.microsoftonline.com/$TenantId/oauth2/token", 

        [string]$EnvironmentName = "azurecloud", 

        [string]$ApiVersion="2020-06-01" 

    ) 

    $output = $False 

    if (($ClientId -eq "") -or ($ClientSecret -eq "") -or ($TenantId -eq "")) { 

        Connect-AzAccount -Environment $EnvironmentName  | Out-Null 

        Set-AzContext -subscriptionId ($SubscriptionId) | Out-Null 

        $Token = $(Get-AzAccessToken) 

        $TokenType = ($Token.Type) 

        $TokenStr = ($Token.Token) 

    } else { 

        $Token = Get-Token $TenantId $ClientId $ClientSecret $Resource $RequestAccessTokenUri 

        $TokenType = ($Token.token_type) 

        $TokenStr = ($Token.access_token) 

    } 

    $ApiUri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/$($Provider)?api-version=$ApiVersion" 

    $Headers = @{} 

    $Headers.Add("Authorization","$($TokenType) "+ " " + "$($TokenStr)") 

    $SupportedProviders = @() 

    $SupportedProviders += "Microsoft.Cache" 

    $SupportedProviders += "Microsoft.Compute" 

    $SupportedProviders += "Microsoft.Network" 

    $SupportedProviders += "Microsoft.Storage" 

    $SupportedProviders += "Microsoft.Kusto" 

    $SupportedProviders += "Microsoft.ApiManagement" 

    $SupportedProviders += "Microsoft.DBforMySQL" 

    $SupportedProviders += "Microsoft.DBforPostgreSQL" 

    $SupportedProviders += "Microsoft.HDInsight" 

  

    if ($Provider -in $SupportedProviders) { 

        $azReadiness = Invoke-RestMethod -Method Get -Uri $ApiUri -Headers $Headers -ErrorVariable errMsg -ErrorAction SilentlyContinue  

        if ($errMsg -ne $null) { 

            $errMsg | Select-String -Pattern "The supported versions are '([\d-]+)," | Foreach-Object { $first, $last, $followers, $handle = $_.Matches[0].Groups[1].Value; break} 

            if ($first -ne $null) { 

                $ApiVersion = $first 

                $ApiUri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/$Provider?api-version=$ApiVersion" 

                $azReadiness = Invoke-RestMethod -Method Get -Uri $ApiUri -Headers $Headers -ErrorAction Stop 

            } 

        } 

        if ($azReadiness -eq $null){ 

            return $Output 

        } 

        $azReadinessForResource = $azReadiness.resourceTypes | Where-Object -filterscript { (($_.resourceType -eq $providerType) -and ($_.locations -contains $Location) -and ($_.zoneMappings.location -eq $location)) } 

        if ($azReadinessForResource -ne $null){ 

            $zm = $azReadinessForResource.ZoneMappings | Where-Object -filterScript {($_.location -eq $Location)} 

            if ($zm -ne $null) {  

                $Output = ($zm.zones.length -gt 0) 

            } 

        } 

    } else { 

        Write-Host "Unsupported Provider." 

    } 

    return $Output 

} 

  

Export-ModuleMember -Function Get-Token 

Export-ModuleMember -Function Get-AzReadyByProviderAndLocation