creating AKS cluster with managed identity and associated with an acr by az cli script error - azure

I am new to power-shell scripts and I tried to run below script that will create an AKS-cluster with managed identity also associated with an ACR . But it was giving an error at "managed identity" line..
Param(
[parameter(Mandatory = $false)]
[string]$subscriptionName = "azure-subcription",
[parameter(Mandatory = $false)]
[string]$resourceGroupName = "demoRG",
[parameter(Mandatory = $false)]
[string]$resourceGroupLocaltion = "East US 2",
[parameter(Mandatory = $false)]
[string]$clusterName = "nginxCluster",
[parameter(Mandatory = $false)]
[int16]$workerNodeCount = 3,
[parameter(Mandatory = $false)]
[string]$kubernetesVersion = "1.19.3",
[parameter(Mandatory = $false)]
[string]$acrRegistryName = "ngAcrRegistrydemo"
)
# Set Azure subscription name
Write-Host "Setting Azure subscription to $subscriptionName" -ForegroundColor Yellow
az account set --subscription=$subscriptionName
$aksRgExists = az group exists --name $resourceGroupName
Write-Host "$resourceGroupName exists : $aksRgExists"
if ($aksRgExists -eq $false) {
# Create resource group name
Write-Host "Creating resource group $resourceGroupName in region $resourceGroupLocaltion" -ForegroundColor Yellow
az group create `
--name=$resourceGroupName `
--location=$resourceGroupLocaltion `
--output=jsonc
}
$aks = az aks show `
--name $clusterName `
--resource-group $resourceGroupName `
--query name | ConvertFrom-Json
$aksCLusterExists = $aks.Length -gt 0
if ($aksCLusterExists -eq $false) {
# Create AKS cluster
Write-Host "Creating AKS cluster $clusterName with resource group $resourceGroupName in region $resourceGroupLocaltion" -ForegroundColor Yellow
az aks create `
--resource-group=$resourceGroupName `
--name=$clusterName `
--node-count=$workerNodeCount `
--enable-managed-identity `
--output=jsonc `
--kubernetes-version=$kubernetesVersion `
--aks-custom-headers="CustomizedUbuntu=aks-ubuntu-1804,ContainerRuntime=containerd" `
--attach-acr=$acrRegistryName
}
# Get credentials for newly created cluster
Write-Host "Getting credentials for cluster $clusterName" -ForegroundColor Yellow
az aks get-credentials `
--resource-group=$resourceGroupName `
--name=$clusterName `
--overwrite-existing
Write-Host "Successfully created cluster $clusterName with $workerNodeCount node(s)" -ForegroundColor Green
Write-Host "Creating cluster role binding for Kubernetes dashboard" -ForegroundColor Green
# kubectl create clusterrolebinding kubernetes-dashboard `
# -n kube-system `
# --clusterrole=cluster-admin `
# --serviceaccount=kube-system:kubernetes-dashboard
Error Msg is coming like as "az: error: unrecognized arguments: --enable-managed-identity".
Please help or give suggestions on how to enable managed identity also associated with AKS-clusters.
Many Thanks,

First, there is no parameter --aks-custom-headers of the CLI command az aks create, and the other two-parameter --enable-managed-identity and --attach-acr. You can try it again without the character =, just append the value behind the parameters:
az aks create `
--resource-group $resourceGroupName `
--name $clusterName `
--node-count $workerNodeCount `
--enable-managed-identity `
--kubernetes-version $kubernetesVersion `
--attach-acr $acrRegistryName
You can take a look at the command az aks create. In addition, that's managed identity, not the service principal, so you need to use the command az identity list to get the identity of the AKS in the node group and you can get the node group through CLI command like below:
az aks show -g aksGroup -n aksCluster --query nodeResourceGroup

I updated Azure CLI (version 2.15.1 or later) by using below
https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-powershell
and executed aks creation ps-script as above and it working perfectly .
AKS-infrastructure are created .
Many Thanks..

Related

Why are write-host statements are not appearing when calling a script with an azure commandlet in it?

I have a very simplistic 2 scripts and I'm trying to call the powershell script from another powershell run script
run script (run.ps1)
.\NewRG.ps1 -rgName "singleVM12" -location "Canada Central" -tags #{dept="Marketing"}
called script (newRG.ps1)
[CmdletBinding()]
param (
[string]$rgName = "Test1-rg",
[string]$location = "Canada Central",
[Parameter(Mandatory)]
[hashtable]$tags)
$newRG = New-AzResourceGroup -name $rgName -location $location -tags #{dept="marketing"}
write-output "test"
I would expect that I should get test in the console but I get the properties of the Resource group
ResourceGroupName : singleVM12
Location : canadacentral
ProvisioningState : Succeeded
The issue is I have more complex scripts with multiple write-host entries that I want shown but none of it appears when I run the "run.ps1" file, it works fine if I just call the called script by itself. I tried using write-output and same thing happens. I noticed that hello world works, so I'm guessing something about the Azure commandlets are maybe causing this. Any way around this?
I am using Write-Output to print the values in prompt. I have followed the same way you did.
Follow the workaround:
testout.ps1
# I am getting resource information
[CmdletBinding()]
param (
[string]$rgName = "test")
#$newRG = New-AzResourceGroup -name $rgName -location $location -tags #{dept="marketing"}
$getResource = Get-AzResource -ResourceGroupName $rgName
write-output "azure resoure get successfully- " $rgName
$getResource = Get-AzResource -ResourceGroupName $rgName
write-output "test2- " $rgName
$getResource = Get-AzResource -ResourceGroupName $rgName
write-output "test3 - " $rgName
$getResource = Get-AzResource
write-output "test4- " $rgName
# you can use return to send the the required data to promt as well. But you can use end of your script otherwise it will skip after the return statement.
return $getResource.ResourceGroupName
test2.ps1
Calling testout.ps1 in test2.ps1 script.
# Connect Azure Account using specific Subscription Id if you are using more subscription in single account
Connect-AzAccount -SubscriptionId '<Your subscription Id>'
# calling test.ps1 script
.\testout.ps1 -rgName "<Your Resourcegroup Name>"
Result

AzureRM `New-AzureRmResource` works but `az resource create doesn't`

i've been tasked with migrating some PowerShell scripts from AzureRM to azure cli. We have some deep resources that get set on App Services to enable complex logging.
This AzureRM script works fine. Even the Get-AzureRmResouce call works, but the azure cli does not and even the REST api call does not. I get a Resource not found error.
this code works:
New-AzureRmResource -ResourceGroupName $ResourceGroupName `
-ResourceName ($AppName + "/AntMDS/" + $SettingName) `
-ResourceType "Microsoft.Web/serverfarms/firstPartyApps/settings" `
-Properties $SettingProperties `
-ApiVersion 2015-08-01 -Force | Out-Null
this code does not:
$temp = New-TemporaryFile
$SettingProperties | ConvertTo-Json | Out-File $temp.FullName
$result = az resource create --resource-group $ResourceGroupName `
--name "$AppName/AntMDS/$SettingName" `
--resource-type "Microsoft.Web/serverfarms/firstPartyApps/settings" `
--properties "#$($temp.FullName)" `
--api-version "2015-08-01" `
| ConvertFrom-Json
if(-not $result) {
throw "Unable to create resource: ""$AppName/AntMDS/$SettingName"" on group $ResourceGroupName"
}
Remove-Item $temp
says "Resource not found"

Adding vnet integration for the multiple Azure webapp slots using powershell or azure cli

I'm trying to Vnet integrate the multiple webapps and slots using powershell. Where enabling vnet integration for webapps is working fine, but in the same way for webapp slots its not working.
$RGName = "web app resource group name "
$vnetName = "yashvnet01"
$VnetRG = "vnet name"
$subnetName = "subnet name"
$Vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $VnetRG
$subnet = Get-AzVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $Vnet
$Vnet.Id
##Add vnet integration to the webapps in the specific Resource group
$Webapps=Get-AzWebApp -ResourceGroupName $RGname
$Webapps.Name
ForEach($webapp in $Webapps.Name)
{
Write-Host "Adding Vnet intergation to the $webapp"
az webapp vnet-integration add --resource-group $RGname --name $webapp --vnet $Vnet.Id --subnet $subnetName
Write-Host "Successfully added Vnet intergation to the $webapp"
}
How can we do the same for multiple webapp slot.
I would be glad if someone helps me on this.
Cheers
Rewanth
You can use the below script to apply v-net intergration on the webapps slots.
Connect-AzAccount
$RGName = "yourresourcegroupname"
$vnetName = "vnetname"
$VnetRG = "vnet resource group name"
$subnetName = "subnetname"
$Vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $VnetRG
$subnet = Get-AzVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $Vnet
$Vnet.Id
$Webapps=Get-AzWebApp -ResourceGroupName $RGname
$Webapps.Name
##Add vnet integration to the webapps slots in the specific Resource group
ForEach($webapp in $Webapps.Name)
{
#Webapp slot
$WebappsSlot = Get-AzWebAppSlot -ResourceGroupName $RGName -Name $webapp
$WebappsSlot.Name
ForEach($webappSlot in $WebappsSlot.Name) {
$s = $webappSlot -replace $webapp + "/"
Write-Host "Adding Vnet intergation to the $s"
az webapp vnet-integration add --resource-group $RGname --name $webapp --vnet $Vnet.Id --subnet $subnetName -s $s
Write-Host "Successfully added Vnet intergation to the $s"
}
}
Output for test:
Note:
Please make sure to use the updated az version while running the above code . The az cli version used for the above is 2.71.1 . You can upgrade az version using command az upgrade in powershell.

Passing multiple Parameters in single Azure Storage Script for various environments

I have a powershell script that creates the storage and blob account for a given subscription that works fine . Subscription Name, resource group keeps changing for different environments like DEV,UAT,PROD
STRUCTURE OF MY TEMPLATE / CODE :
param(
[string] $subscriptionName ="ABC",
[string] $resourceGroupName = "XYZ",
[string] $resourceGroupLocation ="westus",
[string] $templateFilePath = "template.json",
[string] $parametersFilePath = "parameters.json"
)
Function RegisterRP {
Param(
[string]$ResourceProviderNamespace
)
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
}
$ErrorActionPreference = "Stop"
$confirmExecution = Read-Host -Prompt "Hit Enter to continue."
if($confirmExecution -ne '') {
Write-Host "Script was stopped by user." -ForegroundColor Yellow
exit
}
# sign in
Write-Host "Logging in...";
Login-AzureRmAccount;
# select subscription
Write-Host "Selecting subscription '$subscriptionName'";
Select-AzureRmSubscription -SubscriptionName $subscriptionName;
# Register RPs
$resourceProviders = #("microsoft.storage");
if($resourceProviders.length) {
Write-Host "Registering resource providers"
foreach($resourceProvider in $resourceProviders) {
RegisterRP($resourceProvider);
}
}
#Create or check for existing resource group
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if(!$resourceGroup)
{
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
if(!$resourceGroupLocation) {
$resourceGroupLocation = Read-Host "resourceGroupLocation";
}
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
}
else{
Write-Host "Using existing resource group '$resourceGroupName'";
}
# Start the deployment
Write-Host "Starting deployment...";
if(Test-Path $parametersFilePath) {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath -storageAccounts_name $storageAccountName
} else {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath; -storageAccounts_name $storageAccountName
}
Approach 1 :
Created multiple powershell scripts for each denvironment
Created 1 Menu Based powershell script that calls the other script and executes like : Select 1 for Dev , 2 for UAt , 3 for PROD , this approach works but is not effective .
Approach 2 :
I would like to combine all scripts and just have one script for all environments and based on select should allow me to create the storage accounts. Only Subscription and resource group change rest all structure of the powershell remains same .
I tried using GET function commandlets and it selects but still throws the error
[string] $subscriptionName = Get-AzureSubscription,
[string] $resourceGroupName = Get-AzureRmLocation,
If i try to use it using an array based approach like passing the values as below im unable to understand how do i pass these array based values to the code and get it to work .
$environment=#('DEV','TEST','QA','PROD')
$resourcegroupname = #('test','test1','test2','test3')
$subscriptionName = #('devsub1','devsub2','test3','prod4')
I'm trying to call the functions using :
$environment[0]
$subscriptionName[0]
It returns the value as below if i execute it seperately but how do i pass these values to my script to create storage account ?
DEV
devsub1
Requesting expert help if anyone has come across such scenarios earlier and if you can help in changing the above code and provide a tested code that would be of great help.
APPROACH 3:
$subscription = #(Get-AzureRmSubscription)
$resourcegroup = #(Get-AzureRmResourceGroup)
$Environment = #('DEV','TEST','QA','PROD')
$resourceGroupName = $resourcegroup | Out-GridView -PassThru -Title 'Pick the environment'
$subscriptionName = $subscription | Out-GridView -PassThru -Title 'Pick the subscription'
Write-Host "Subscription:" $subscriptionName
Write-Host "ResourceGroup:" $resourcegroup
OUTPUT :
If you look at resource group it fails to give the selection option for resource group .
Subscription: < it returns the subscription name >
ResourceGroup: Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup Microsoft.Azure.Commands.ResourceManager.Cmd
lets.SdkModels.PSResourceGroup Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup Microsoft.Azure.Commands.Res
ourceManager.Cmdlets.SdkModels.PSResourceGroup
What you are proposing is an interesting approach. I would likely an input parameter that defines which environment the work will be done in, and then have a conditional block that sets the dynamic variables for that environment. There would be some duplication of initialization code for each environment, but the main code block would still be unified.

chaining az calls in a powershell script

I'm trying to build a script that sets up my Azure environment, but passing information from one call to the next is proving to be tricky. I'm not sure how to treat the data returned as an object.
# az network public-ip create output (truncated)
#{
# "publicIp": {
# "ipAddress": "1.1.1.1",
# }
#}
$staticIpCreate = (az network public-ip create --resource-group mygroup --name myipname --allocation-method static | ConvertFrom-Json)
$staticIp = ($staticIpCreate | Select-Object ipAddress)
Write-Host "Static Ip :$($staticIp)"
You do not need to combine them, here is PowerShell command to achieve the samething
$PIP = New-AzureRmPublicIpAddress -AllocationMethod Static -ResourceGroupName DDemo -Location Westus2 -Name DDemoIPTest
Write-Host "Static IP:" $PIP.IpAddress
Image
from jessehouwing's comment
Write-Debug "////// static ip"
$staticIpCreate = az network public-ip create --resource-group mygroup --name myipname --allocation-method static | ConvertFrom-Json
$staticIp = $staticIpCreate.publicIp.ipAddress
Write-Host "Static Ip :$($staticIp)"

Resources