3

I have declared the following Variable group in Azure DevOps.

KUBERNETES_CLUSTER = myAksCluster
RESOURCE_GROUP = myResourceGroup

enter image description here

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:

enter image description here

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: enter image description here

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.

bgarcial
  • 2,915
  • 10
  • 56
  • 123

2 Answers2

1

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.

enter image description here

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://learn.microsoft.com/en-us/azure/storage/common/storage-auth-aad-script

Azure CLI vs Powershell?

Lu Mike
  • 677
  • 4
  • 4
  • I didn't know about Azure DevOps Services REST API Reference, looks like a great resource. My doubt is, how cam I put all together to work, I mean, how can I mix the azure cli commands (bash) that I have used to get the IP address and this script? I am a little bit confuse about it. What language is this script? Powershell maybe? – bgarcial Jul 17 '19 at 06:43
  • 1
    The Azure command-line interface (CLI) is Microsoft's cross-platform command-line experience for managing Azure resources. It supports bash script and powershell script. The above script is written in powershell. – Lu Mike Jul 17 '19 at 07:00
  • Did you mean, similar to this process? https://learn.microsoft.com/en-us/cli/azure/vm/run-command?view=azure-cli-latest I mean, call the script inside the `az` cli command? Or include all my `az` commands inside this powershell script? – bgarcial Jul 18 '19 at 08:30
  • 1
    You can add a powershell task, and sepecify the script as inline or script path. In the powershell script, firstly you need to usw powershell comand to install the Azure CLI module, please see [Install the Azure PowerShell module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-2.4.0), after that, you can add the az commands and my code in the powershell script. – Lu Mike Jul 18 '19 at 09:23
  • BTW, the link you mentioned is for VM, you don't need to run the az command for vm. – Lu Mike Jul 18 '19 at 09:23
  • Yes, I know, and vm is not related for this ip public process. Sorry for that I haven't sound a similar command directly with public-ip commands to illustrate my question. It's my fault. I am going to try your suggestions. – bgarcial Jul 18 '19 at 11:36
  • Hi **Lu Mike** My apologies. I again. Powershell and its respective azure task are new for me, and I am not sure about how can I get along of this process. Could you have a look to my **UPDATE** section in my question please? – bgarcial Jul 18 '19 at 14:45
  • @bgarcial, i updated my response. It is recommended to test your script in your local development pc at first. Please feel free let me know if you fixed the issue. – Lu Mike Jul 19 '19 at 08:08
1

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:

enter image description here

Shayki Abramczyk
  • 36,824
  • 16
  • 89
  • 114
  • Hi Shayki. More or less I am understanding the workflow to follow. I am following the Mike Lu approach in your answer in order to get familiarity with Powershell language, but I have some errors. Could you have a look to my **UPDATE** section in my original question please? – bgarcial Jul 18 '19 at 14:54
  • 1
    @bgarcial Why not set the variables in the azure cli task and in another powershell task push them to the group? – Shayki Abramczyk Jul 18 '19 at 16:42