I am trying to get the subscription keys for my products as well as default subscription key using cli. I have gone through the documentation https://learn.microsoft.com/en-us/cli/azure/apim/api?view=azure-cli-latest , but right now I don't see any commands to get me the subscription key.
While I can see there are powershell way of getting it, we run the tasks in ubuntu pipeline, and the commands listed below is not working in the linux agent. It says Set-AzContext is not a known command
$subscriptionId = "id"
$RG = "rg"
$service = "apim-name"
Set-AzContext -Subscription $subscriptionIdÂ
$apimContext = New-AzApiManagementContext -ResourceGroupName $RG -ServiceName $service
Get-AzApiManagementSubscriptionKey -Context $apimContext -SubscriptionId "master"
Update
I am able to fetch the details through powershell task for Azure in the DevOps pipeline. If there is no option in azure cli I will use this as a workaround.
Using az rest it is possible:
APIMID=`az apim show -n apimname -g resourcegroup --query id -o tsv`
az rest --method post --uri ${APIMID}/subscriptions/test-subscription/listSecrets?api-version=2021-08-01 --query primaryKey -o tsv
where test-subscription is the name of the subscription.
Currently it is not possible to fetch subscription key using AZ CLI commands. The PowerShell command used is the correct way to go. Just in case if it helps another way to get the subscription key is by using Management API call
Related
I've run into a snag with my powershell script that builds an azure function & all its dependencies.
This is what's happening: (i'm doing it manually here to demo...)
I request the storage account information like this:
PS C:\Users\me\> Get-AzStorageAccount -ResourceGroupName widget-resource-group
StorageAccountName ResourceGroupName PrimaryLocation SkuName Kind AccessTier CreationTime ProvisioningState EnableHttpsTrafficOnly LargeFileShares
------------------ ----------------- --------------- ------- ---- ---------- ------------ ----------------- ---------------------- ---------------
widgetx4ge6v27rlgdk widget-resource-group eastus Standard_LRS StorageV2 Hot 2022-03-10 2:00:26 PM Succeeded True
It comes back with the correct information. So then I try to get the connection string like this:
PS C:\Users\me> func azure storage fetch-connection-string widgetx4ge6v27rlgdk
Cannot find storage account with name widgetx4ge6v27rlgdk
But it says it can't find the storage account.
The actual code looks like this:
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# Get new connection string for the storage account.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
When the code runs, everything works until the call to "func azure storage fetch-connection-string".
Any tips on what I'm missing?
Edit 1
In case it helps, this logic works just fine when I run it against Tenant 1, Subscription A. But for Tenant 1, Subscription B it bombs.
I've made sure the service account principle it runs under is contributor on both subscriptions.
And for what it's worth, the script is able to create the resource group and many of the resources inside. It's just hat when I try to get the connection string, it bombs. It also bombs further down in the script when it tries to deploy the functions in my function app. The error message though is similar - it complains that it can't find the function app that I just finished creating.
Edit 2
So I figured out the problm but not sure how to fix it in a nice / simple way.
For 90% of the script, including login, i'm using the new Az Powershell modules. However, the "func azure" tool relies on login information provided by the az cli. (that seems to be cached??)
To get you on the same page, here's the relevant part of the code in the script:
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AZ_DEPLOYMENT_CLIENT_ID, $Secure2
#Connect
Connect-AzAccount -ServicePrincipal -TenantId $AZ_TENANT_ID -Credential $Credential
#OPTIONAL - List the subscriptions available to the current User
Get-Azcontext -ListAvailable
#Set the subscription context to subscription 2
Set-Azcontext -Subscription $AZ_SUBSCRIPTION_ID -Tenant $AZ_TENANT_ID
#Create a new resource group
New-AzResourceGroup -Name $AZ_RESOURCE_GROUP_NAME -Location $AZ_RESOURCE_LOCATION -Force
New-AzResourceGroupDeployment -ResourceGroupName $AZ_RESOURCE_GROUP_NAME -TemplateFile (Join-Path $PSScriptRoot "./artifacts/widget-resources.json")
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# this is where it is failing because it is using a subscription that is visible to az cli.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
Here's what I did to troubleshoot from a powershell cli:
az account list
That returns this:
{
"cloudName": "AzureCloud",
"homeTenantId": "asdf-asdf-asdf-asdf-12312312313",
"id": "[guid]",
"isDefault": false,
"managedByTenants": [],
"name": "subscription-1",
"state": "Enabled",
"tenantId": "[our-tenant-id]",
"user": {
"name": "[another-guid]",
"type": "servicePrincipal"
}
}
When I ran the above command, it only returned one subscription called "subscription-1" for discussion purposes. It isn't/wasn't the one that the rest of the script was working with. The rest of script was dealing with subscription 2
As I test, I added the following lines of code just before call func azure storage:
az login --service-principal --username $AZ_APPLICATION_CLIENT_ID --password $AZ_SECRET --tenant $AZ_TENANT --allow-no-subscriptions
#set the subscription we want to use
az account set --subscription $subscription2
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
And now it finds the correct subscription and resource group / storage account. And now when I run az account list again, it shows me both subscriptions.
One addition comment / observation. Once the az login / az account set has been run with the desired subscription id, i've noticed that I can remove the az login and account set logic from the script and it just uses the cached values. I'm not saying this is what I want to do ... cuz I think it' best to be explicit. But just an observation which explains what bit me in the first place.
So my question is... is there anyway to avoid having to log in twice - once with az cli and another time with the Az Powerhsell modules?
I'm thinking of just abandoning the Az Powershell module and just rewriting everything in just az cli.
But asking the community to see if there's a better way to do this.
EDIT 3
Based on the docs for the azure core functions tools, technically I should be able to use the powershell modules or the cli:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash#publish
"You must have the Azure CLI or Azure PowerShell installed locally to be able to publish to Azure from Core Tools."
Yes, using a mix of azcli and azure powershell, as they are their seperate entities in their own right, you would need to login to each of them individually.
And yes, you are right its better to ditch of them and choose one or the other ! Just much cleaner that way
The issue was that the azure core functions tool is using the cached az account list to find my resources.
So in other words, unbeknownst to me, the func method was using az cli, whereas the rest of the script is using the new Az Powershell modules.
For now, I've just rewritten everything in az cli syntax, and am happy with that. But per the docs it seems that the azure core functions tools should be able to work with either az cli or az powershell. Will open a separate question that addresses that point. For now, my script is working again.
I'm a bit of an Azure & Powershell newbie.
I'm trying to write PowerShell scripts to create an environment that can be published to from Azure DevOps.
As part of that, I'm creating a Service Bus with multiple topics. Each of the topics will have multiple Authorization Rules - one for publication and one for subscription.
I have the scripts for this working. However, I need to get the connection strings for these rules and save them to a key vault, to make them available to apps.
This is where I have become stuck.
This is similar to my existing code:
New-AzServiceBusTopic -ResourceGroupName myResourceGroup -Namespace myServiceBus -EnablePartitioning $false -Name myTopic
New-AzServiceBusAuthorizationRule `
-ResourceGroupName myResourceGroup `
-Namespace myServiceBus `
-Topic myTopic`
-Name myTopic.pub `
-Rights #("Send")
In the Azure Portal, I would click into the Service bus and Topic, select Shared Access Policies and click on the policy. It would show me the SAS Policy with the Primary Connection String.
Is there any way in PowerShell to get the Primary Connection String?
Thanks
If you have azure powershell Az.ServiceBus module installed, you can directly use this command: Get-AzServiceBusKey.
For example:
Get-AzServiceBusKey -ResourceGroup Default-ServiceBus-WestUS -Namespace SB-Example1 -Name AuthoRule1
I have a container created by someone and I'm using it load the data. In the manage access tab I see my user name and also $superuser(Owner) and $superuser(Owning Group) with different level of ACLs set.
How to find who is the superuser for that container? I tried Get Properties API but still seeing the response as $superuser
You could use the Az powershell command to get $superuser(Owner), it returns the Object ID of the Owner, which could be a user, group, service principal in Azure AD.
Connect-AzAccount
$storageAccount = Get-AzStorageAccount -ResourceGroupName <group-name> -AccountName <storage-account-name>
$ctx = $storageAccount.Context
$filesystemName = "<container-name>"
$filesystem = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName
$filesystem.Owner
If you want to get the details of the Object ID, you could use the AzureAD command below.
Connect-AzureAD
Get-AzureADObjectByObjectId -ObjectIds $filesystem.Owner
Update:
Yes, you could use the azure cli command az storage blob directory access show, first you need to add the storage-preview extension.
az extension add -n storage-preview
az login
az storage blob directory access show -d '/' -c '<container-name>' --account-name '<account-name>'
It also returns the Object ID of the $superuser(Owner), but in azure cli, there is no built-in command to get the directory object with Object ID, you can get the details about the object with az ad user show, az ad sp show, az ad group show, you need to know the type of the object previously.
If you don't know the type of the object, you can just use az rest to call Microsoft Graph to get the details.
az rest --method get --uri https://graph.microsoft.com/v1.0/directoryObjects/<Object ID>
I have a logic App with Managed Identity enabled. For automation purposes, I need to use either Azure CLI or Powershell to grab the objectID of the Logic App Managed Identity to grant it access to a keyvault.
I have done the same for Azure Data Factory using a Poweshell command like this:
(Get-AzureRMDataFactoryV2 -ResourceGroupName $ResourceGroup -Name $DataFactoryName).Identity
Tried something similar for logic app but it does not return the identity.
Looks like the Workflow object returned by Get-AzLogicApp doesn't have the identity property defined.
A workaround would be to use the Get-AzResource cmdlet instead.
$ID = (Get-AzResource -Name myLogicApp -ResourceType Microsoft.Logic/workflows).Identity.PrincipalId
Based on the previous answer by Joey Cai, you can do the following in AZ CLI also:
$ID = az resource show --name "myLogicApp" --resource-group "myResourceGroup" --resource-type "Microsoft.Logic/workflows" --query "identity.principalId" | ConvertFrom-Json
I have an azure subscription that has upwards of 200 appServices where around about half of them have Continuous, always on webJobs attached, some also have slots which also have webJobs.
Is there a way to list all webJobs that are inside a subscription? I was originally tring to use powershell to do this but it was getting rather complex and was wondering if anyone knew of an easy way to achieve the above.
It seems like Get-AzureRmWebApp should be able to help but i cant find a way to list the jobs that reside inside the webapps.
I found the command Get-AzureWebsiteJob which is not in the AzureRM family of commandlets. The following script can get the data that I'm looking for:
$groups = get-AzureRmResourceGroup | where{$_.ResourceGroupName -like "*-prod-*"}
foreach($group in $groups){
Write-Host -ForegroundColor Cyan "processing resourceGroup" $group.ResourceGroupName
$webApps = Get-AzureRmWebApp -ResourceGroupName $group.ResourceGroupName
foreach($webApp in $webApps){
write-host -ForegroundColor Yellow $webApp.Name
$job = Get-AzureWebsiteJob -Name $webApp.Name
if($job){
write-host -ForegroundColor DarkYellow $job.JobName
}
$job = Get-AzureWebsiteJob -Name $webApp.Name -Slot staging
if($job){
write-host -ForegroundColor DarkYellow $job.JobName " -staging"
}
}
}
The above does not filter out the running ones from the stopped, but that can be easily added if need be.
Of course you firstly need to be logged into AzureRM and Azure classic
Login-AzureRmAccount
Select-AzureRmSubscription -SubscriptionId <<mySubscriptionId>>
Get-AzureRmContext
Add-AzureAccount
Select-AzureSubscription -SubscriptionId <<mySubscriptionId>>
Get-AzureSubscription -Current
Its a very slow script iterating over this number or AppServices though. Any ideas for speeding it up would be appreciated.
You can do it through the ARM APIs, though you still need to call it on each Web App.
You can get the WebJobs with a GET request to:
https://management.azure.com/subscriptions/subscription-id/resourceGroups/resource-group-name/providers/Microsoft.Web/sites/app-name/webjobs?api-version=2016-03-01
But I doubt this will be any more efficient than what you have since you still need to make a call for every Web App. And you will need to get the access token somehow.
Web Jobs are a property of App Service applications and can't be requested all at once from Azure.
I know it's too late but we can try with Azure CLI too these days.
az webapp webjob triggered list --name MyWebApp --resource-group MyResourceGroup
Additionally, you can query the above result and get the desired information you are looking for
az webapp webjob triggered list --name MyWebApp --resource-group MyResourceGroup --query "[].{Name:name, Schedule:settings.schedule}"
I know it's too late but we can try with Azure CLI too these days.
az webapp webjob triggered list --name MyWebApp --resource-group MyResourceGroup
Additionally, you can query the above result and get the desired information you are looking for
az webapp webjob triggered list --name MyWebApp --resource-group MyResourceGroup --query "[].{Name:name, Schedule:settings.schedule}"
But, again you have to run the above query in the for each loop to fetch the results from all resource groups in the subscription.