I have declared the following Variable group in Azure DevOps.
KUBERNETES_CLUSTER = myAksCluster
RESOURCE_GROUP = myResourceGroup
In the Release pipeline process, I want to create a Public Static IP address in order to assigned to some application in myAksCluster
.
Via Azure cli commands I am creating the Static IP address of this way via az cli bash small script. We can assume here that I already have created the kubernetes cluster
#!/usr/bin/env bash
KUBERNETES_CLUSTER=myAksCluster
RESOURCE_GROUP=myResourceGroup
# Getting the name of the node resource group. -o tsv is to get the value without " "
NODE_RESOURCE_GROUP=$(az aks show --resource-group $RESOURCE_GROUP --name $KUBERNETES_CLUSTER --query nodeResourceGroup -o tsv)
echo "Node Resource Group:" $NODE_RESOURCE_GROUP
# Creating Public Static IP
PUBLIC_IP_NAME=DevelopmentStaticIp
az network public-ip create --resource-group $NODE_RESOURCE_GROUP --name $PUBLIC_IP_NAME --allocation-method static
# Query the ip
PUBLIC_IP_ADDRESS=$(az network public-ip list --resource-group $NODE_RESOURCE_GROUP --query [1].ipAddress --output tsv)
# Output
# I want to use the value of PUBLIC_IP_ADDRESS variable in Azure DevOps variable groups of the release pipeline
If I execute az network public-ip list ...
command I get my public Ip address.
⟩ az network public-ip list --resource-group $NODE_RESOURCE_GROUP --query [1].ipAddress -o tsv
10.x.x.x
I want to use that PUBLIC_IP_ADDRESS
value to assign it to a new Azure DevOps variable groups in my release, but doing all this process from a CLI task or Azure Cli task like part of the release pipeline process.
The idea is when my previous az cli bash small script to be executed in the release pipeline, I have a new variable in my ReleaseDev azure variable groups of this way:
And after that, I can use PUBLIC_STATIC_IP_ADDRESS
which will be an azure devops variable like arguments to the application which will use that IP value inside my kubernetes cluster.
I have been checking some information and maybe I could create an Azure CLI task in my release pipeline to execute the az cli bash small script which is creating the public static ip address of this way:
But is finally at the end when I get the public ip address value, that I don't know how to create from this Azure CLI task (my script) the variable PUBLIC_STATIC_IP_ADDRESS
with its respective value that I got here.
Can I use an Azure CLI task from the release pipeline to get this small workflow? I have been checking somethings like this recommendation but is not clear for me
how to create an Az variable group with some value passed from my release pipeline? Is Azure CLI release pipeline task, the proper task for do that?
UPDATE
I am following the approach suugested by Lu Mike, so I have created a Powershell task and executing the following script in Inline type/mode:
# Connect-AzAccount
Install-Module -Name Az -AllowClobber -Force
@{KUBERNETES_CLUSTER = "$KUBERNETES_CLUSTER"}
@{RESOURCE_GROUP = "$RESOURCE_GROUP"}
@{NODE_RESOURCE_GROUP="$(az aks show --resource-group $RESOURCE_GROUP --name $KUBERNETES_CLUSTER --query nodeResourceGroup -o tsv)"}
# echo "Node Resource Group:" $NODE_RESOURCE_GROUP
@{PUBLIC_IP_NAME="Zcrm365DevelopmentStaticIpAddress"}
az network public-ip create --resource-group $NODE_RESOURCE_GROUP --name $PUBLIC_IP_NAME --allocation-method static
@{PUBLIC_IP_ADDRESS="$(az network public-ip list --resource-group $NODE_RESOURCE_GROUP --query [1].ipAddress --output tsv)"}
echo "##vso[task.setvaraible variable=ipAddress;]%PUBLIC_IP_ADDRESS%"
$orgUrl="https://dev.azure.com/my-org/"
$projectName = "ZCRM365"
##########################################################################
$personalToken = $PAT # "<your PAT>"
# I am creating a varaible environment inside the power shell task and reference it here.
##########################################################################
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}
$projectsUrl = "$($orgUrl)/$($projectName)/_apis/distributedtask/variablegroups/1?api-version=5.0-preview.1"
$requestBody = @{
"variables" = @{
"PUBLIC_STATIC_IP_ADDRESS" = @{
"value" = "$PUBLIC_IP_ADDRESS"
}
}
"@type" = "Vsts"
"name" = "ReleaseVariablesDev"
"description" = "Updated variable group"
} | ConvertTo-Json
Invoke-RestMethod -Uri $projectsUrl -Method Put -ContentType "application/json" -Headers $header -Body $requestBody
Invoke-RestMethod -Uri $projectsUrl -Method Put -ContentType "application/json" -Headers $header -Body $requestBody
IMPORTANT
As you can see, in this process I am mixing az cli
commands and powershell language in this task. I am not sure if it is good. By the way I am using a Linux Agent.
I had to include -Force
flag to the Install-Module -Name Az -AllowClobber -Force
command to install azure powershell module
My output is the following:
2019-07-19T06:01:29.6372873Z Name Value
2019-07-19T06:01:29.6373433Z ---- -----
2019-07-19T06:01:29.6373706Z KUBERNETES_CLUSTER
2019-07-19T06:01:29.6373856Z RESOURCE_GROUP
2019-07-19T06:01:38.0177665Z ERROR: az aks show: error: argument --resource-group/-g: expected one argument
2019-07-19T06:01:38.0469751Z usage: az aks show [-h] [--verbose] [--debug]
2019-07-19T06:01:38.0470669Z [--output {json,jsonc,table,tsv,yaml,none}]
2019-07-19T06:01:38.0471442Z [--query JMESPATH] --resource-group RESOURCE_GROUP_NAME
2019-07-19T06:01:38.0472050Z --name NAME [--subscription _SUBSCRIPTION]
2019-07-19T06:01:38.1381959Z NODE_RESOURCE_GROUP
2019-07-19T06:01:38.1382691Z PUBLIC_IP_NAME Zcrm365DevelopmentStaticIpAddress
2019-07-19T06:01:39.5094672Z ERROR: az network public-ip create: error: argument --resource-group/-g: expected one argument
2019-07-19T06:01:39.5231190Z usage: az network public-ip create [-h] [--verbose] [--debug]
2019-07-19T06:01:39.5232152Z [--output {json,jsonc,table,tsv,yaml,none}]
2019-07-19T06:01:39.5232671Z [--query JMESPATH] --resource-group
2019-07-19T06:01:39.5233234Z RESOURCE_GROUP_NAME --name NAME
2019-07-19T06:01:39.5233957Z [--location LOCATION]
2019-07-19T06:01:39.5234866Z [--tags [TAGS [TAGS ...]]]
2019-07-19T06:01:39.5235731Z [--allocation-method {Static,Dynamic}]
2019-07-19T06:01:39.5236428Z [--dns-name DNS_NAME]
2019-07-19T06:01:39.5236795Z [--idle-timeout IDLE_TIMEOUT]
2019-07-19T06:01:39.5237070Z [--reverse-fqdn REVERSE_FQDN]
2019-07-19T06:01:39.5240483Z [--version {IPv4,IPv6}]
2019-07-19T06:01:39.5250084Z [--sku {Basic,Standard}] [--zone {1,2,3}]
2019-07-19T06:01:39.5250439Z [--ip-tags IP_TAGS [IP_TAGS ...]]
2019-07-19T06:01:39.5251048Z [--public-ip-prefix PUBLIC_IP_PREFIX]
2019-07-19T06:01:39.5251594Z [--subscription _SUBSCRIPTION]
2019-07-19T06:01:40.4262896Z ERROR: az network public-ip list: error: argument --resource-group/-g: expected one argument
2019-07-19T06:01:40.4381683Z usage: az network public-ip list [-h] [--verbose] [--debug]
2019-07-19T06:01:40.4382086Z [--output {json,jsonc,table,tsv,yaml,none}]
2019-07-19T06:01:40.4382346Z [--query JMESPATH]
2019-07-19T06:01:40.4382668Z [--resource-group RESOURCE_GROUP_NAME]
2019-07-19T06:01:40.4382931Z [--subscription _SUBSCRIPTION]
2019-07-19T06:01:40.5103276Z PUBLIC_IP_ADDRESS
2019-07-19T06:01:40.5133644Z ##[error]Unable to process command '##vso[task.setvaraible variable=ipAddress;]%PUBLIC_IP_ADDRESS%' successfully. Please reference documentation (http://go.microsoft.com/fwlink/?LinkId=817296)
2019-07-19T06:01:40.5147351Z ##[error]##vso[task.setvaraible] is not a recognized command for Task command extension. Please reference documentation (http://go.microsoft.com/fwlink/?LinkId=817296)
And maybe that is why I have some problem to execute az
commands
Power shell and its respective azure task are new for me, and I am not sure about how can I get along of this process.
You can try to invoke REST API(Variablegroups - Update) to add or update the variable group in the script. Please refer to following script.
$orgUrl = "https://dev.azure.com/<your organization >"
$projectName = "<your project>"
$personalToken = "<your PAT>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}
$projectsUrl = "$($orgUrl)/$($projectName)/_apis/distributedtask/variablegroups/1?api-version=5.0-preview.1"
$requestBody = @{
"variables" = @{
"PUBLIC_STATIC_IP_ADDRESS" = @{
"value" = "<the static ip you got>"
}
}
"@type" = "Vsts"
"name" = "<your variable group name>"
"description" = "Updated variable group"
} | ConvertTo-Json
Invoke-RestMethod -Uri $projectsUrl -Method Put -ContentType "application/json" -Headers $header -Body $requestBody
Then, you will find the varaible in the group.
UPDATE:
You can use AZ
commands directly as powershell script, since after you installed Az module for powershell, Az commands support powershell and bash. Please refer to following script.
$KUBERNETES_CLUSTER = "KUBERNETES_CLUSTER"
$RESOURCE_GROUP = "RESOURCE_GROUP"
$PUBLIC_IP_ADDRESS
$PUBLIC_IP_NAME="Zcrm365DevelopmentStaticIpAddress"
$NODE_RESOURCE_GROUP = az aks show --resource-group $RESOURCE_GROUP --name $KUBERNETES_CLUSTER --query nodeResourceGroup -o tsv | az network public-ip create --resource-group --name $PUBLIC_IP_NAME --allocation-method static
az network public-ip create --resource-group $NODE_RESOURCE_GROUP --name $PUBLIC_IP_NAME --allocation-method static
$PUBLIC_IP_ADDRESS = az network public-ip list --resource-group $NODE_RESOURCE_GROUP --query [1].ipAddress --output tsv
echo "##vso[task.setvaraible variable=ipAddress;]$PUBLIC_IP_ADDRESS"
$orgUrl="https://dev.azure.com/<org>/"
....
Please refer to following links to learn the usage of az commands in powershell.
https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-script
You can use the Rest API as Lu Mike mentioned to update the variable group, or you can install the Shared variable updater extension that do it for you.
But the important thing is, you need to set a variable in the Azure CLI task that you can use it in the second task (either it's Rest API task or the Shared variable updater task). so you need to add this line to your script:
echo "##vso[task.setvaraible variable=ipAddress;]%PUBLIC_IP_ADDRESS%"
Now in the next tasks you can use the variable $(ipAddress)
that contains the ip value: