How to use Azure DevOps server (TFS) Predefined Variable in My Ansible Playbook? - powershell

I want to use Azure DevOps Predefine Variable "$(Build.SourcesDirectory)" in My playbook:
Here is my playbook:
---
- hosts: KBR_MTL361
tasks:
- name: copy file
win_copy:
src: D:\Web.config
dest: $(Build.SourcesDirectory)
I am running this ansible-playbook using Azure DevOps Pipeline:
TFS Pipeline Task
But it is not working
Is there anyone who has any idea how to use the variable in the pipeline?

Just add your variables as additional args in the azure-pipelines.yml like this:
- task: Ansible#0
inputs:
ansibleInterface: 'agentMachine'
playbookPathOnAgentMachine: 'ansible/tfs_playbooks/install_agent.yml'
inventoriesAgentMachine: 'file'
inventoryFileOnAgentMachine: 'hosts.yml'
args: '--extra-vars "build_source_dir=$(Build.SourcesDirectory) AGENT_URL=$(AGENT_URL)"'
Then you can access the variables in your playbook:
---
- hosts: localhost
tasks:
- name: show debug
debug:
msg: "Dir {{ build_source_dir }} agent url {{AGENT_URL}}"

if you look here: https://daniel-krzyczkowski.github.io/Parameters-In-Azure-DevOps-Pipelines there is a certain way to pass Pipeline variables to a powershell script, for instance:
[CmdletBinding()]
param (
$ApiManagementServiceName,
$ApiManagementServiceResourceGroup
)
$apimServiceName = $ApiManagementServiceName
$resourceGroupName = $ApiManagementServiceResourceGroup
Write-Host "Api Management Service Name: $($apimServiceName)"
Write-Host "Api Management Resource Group Name: $($resourceGroupName)"
you are using still powershell you say, so give this a try or try to do something similar that works in your case, for me the above approach works pretty well in standard powershell.

Related

Retrieve powershell variable in azure devops task and assign to terraform conf

I have an Azire Devops release pipeline, in which i have a task executing a powershell script. In this script, i retrieve the uuid of a (nutanix) vlan according to its name, like this :
parameters:
- name: vlan
displayName: vlan
type: string
default: VLAN_DMZ_1
values:
- VLAN_DMZ_1
- VLAN_DMZ_2
steps:
- task: petergroenewegen.PeterGroenewegen-Xpirit-Vsts-Build-InlinePowershell.Xpirit-Vsts-Build-InlinePowershell.InlinePowershell#1
displayName: 'Check Parameters'
inputs:
Script:
$NIC = Get-NTNXNetwork | where { $_.name -eq "${{ parameters.vlan }}" } | select uuid -ExpandProperty uuid
How can i retrieve the value of this variable into the .tf file?
I tried this :
nic_list {
subnet_uuid = "$(NIC)"
}
But it doesn't work (it takes $(NIC) as the value itself), tried the replace token but it does not seem to be what i am looking for.
Thank your for your help.
The correct way to implement would be to define your terraform variable in the variables.tf file and then pass the variable through Azure devops pipeline from terraform plan command. For example in the below plan I pass into environment terraform variable the azure devops environment parameter.
terraform plan -input=false -out=tf_plan -var=environment="${{ parameters.environment }}"
Otherwise you could just append the value on the .tfvars file that you want. This should be done in powershell
Write-Output "subnet_uuid = $(NIC)" >> terraform_folder\terraform.tfvars

Evaluating Azure Devops Expressions within Powershell

I want to be able to invoke the Counter expression within a template but I am unsure how to do so; my current template yml file looks like this:
parameters:
- name: major
type: string
default: '1'
- name: minor
type: string
default: '0'
steps:
- task: PowerShell#2
displayName: Set NuGet package version
inputs:
targetType: 'inline'
script: |
$isMain = ('$(Build.SourceBranch)' -eq 'refs/heads/main')
$minor = ${{ parameters.minor }}
$revision1 = $[counter($minor, 1)]
Write-Host $revision
exit 0
But I get:
The term '$[counter' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I am guessing there is way I can invoke the function via Powershell.
The reason for me wanting to do this in the template as opposed to passing it in as a parameter from the consumer of the template is because seemingly parameters are not evaluated when passed into a template.
Evaluating Azure Devops Expressions within Powershell
Just as Daniel said that:
The powershell script you're trying to run is getting finalized
during compile time. This line: $revision1 = $[counter($minor, 1)]
cannot possibly work. You are trying to take the results of a
powershell script expression and use it in a YAML function.
That is reason why it is not work for you.
And personally think you can go the easier way, just define the variable in the main YAML file:
azure-pipelines.yml:
variables:
- name: minor
value: 0
- name: revision1
value: $[counter(variables['minor'], 0)]
stages:
- stage: Run
jobs:
- job:
steps:
- template: Template.yml
And we could use the the Counter in the template directly:
Template.yml:
steps:
- task: PowerShell#2
displayName: Set NuGet package version
inputs:
targetType: 'inline'
script: |
Write-Host '$(revision1)'
The test result:

Azure DevOps - AWS CloudFormation and parameters

I have a simple CloudFomration template to create a VPC:
vpc.yaml
---
Parameters:
CidrBlock:
Type: String
Description: The primary IPv4 CIDR block for the VPC
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref "CidrBlock"
Tags:
- Key: "Name"
Value: "This is the main VPC"
In my Azure Devops pipleline I want to use AWS Stack create to create a VPC by using this CloudFormation template.
Azure-pipeline.yaml
---
jobs:
- job: Job1
steps:
- task: CloudFormationCreateOrUpdateStack#1
inputs:
awsCredentials: 'My-cred'
regionName: 'ap-southeast-2'
stackName: 'Stack1'
templateSource: 'file'
templateFile: 'vpc.yaml'
templateParametersSource: inline
templateParameters: |
- ParameterKey: CidrBlock
ParameterValue: '10.10.10.0/24'
Obviousely, it'll work fine when I manually provide the value for the CidrBlock parameter when calling vpc.yaml template (like above ^). But what I want to do is using another file to store the parameters and values and pass that when running the vpc template.
In other words, I have a params.yaml file in which I stored the required parameters to run vpc.yaml. How can I use that when running the vpc.yaml template as the parameter files?
params.yaml
---
parameters:
- name: CidrBlock
value: '10.10.10.0/24'
Like how I refer to the template file in azure-pipeline file above, is there a similar way with which I can refer to the params file instead of using templateParametersSource: inline ?
It looks like there is an issue with YAML parameters file with aws-cli:
https://github.com/aws/aws-cli/issues/2275
You can use JSON file:
[
{
"CidrBlock": "10.10.10.0/24",
}
]
Sounds like unlike Azure Bicep or ARM where you can use keys of your own when creating the params files, AWS expect a specific structure where you must always use ParameterKey and ParameterValue as the key.
Here is how the params file should look like in my case:
---
- ParameterKey: CidrBlock
ParameterValue: '10.10.10.0/24'

What is the best way to create git tags from Azure Pipelines?

I'm currently using an extension to create the git tag, my problem is that I'm using the Azure Platform to add the variables instead of the yaml file.
- task: GitTag#6
displayName: 'Creating Git Tag'
inputs:
workingdir: '$(SYSTEM.DEFAULTWORKINGDIRECTORY)'
git: '$(Major).$(Minor).$(Patch)'
The Variables are:
Name:
Major
Value:
1
Name:
Minor
Value:
0
Name:
Patch
Value:
$[counter(format('{0}.{1}', variables['Major'], variables['Minor']), 0)]
The current output is the following:
1.0.0
My question would be: How can I declare the Patch as a variable in the yaml file. I tried to add the following variables:
- name: Major
value: 1
- name: Minor
value: 0
- name: patch
value: echo "##vso$[counter(format('{0}.{1}', variables['Major'], variables['Minor']), 0)]"
Now my new output is:
1.0.$[counter(format('{0}.{1}', variables['Major'], variables['Minor'])
Does anyone knows how can I add a script as a variable inside of the yaml file?
You might be able to use the Run Inline Powershell Azure Pipelines task, like so:
- task: InlinePowershell#1
inputs:
Script: |
$foo = 'bar'
Write-Output "##vso[task.setvariable variable=foo;]$foo"

Stop azure pipelines from running my template files

I am trying to use Azure pipeline templates to organize my build.
I am using multiple repositories for this:
BuildTemplates
MySoftwareProject1
MySoftwareProject2
MySoftwareProjectN
The BuildTemplates repo contains all templates and I want to use these from my other repos.
I am trying to make sure that when the BuildTemplates repo is changed - not a single pipeline gets triggered to run (these are templates and should not run) - more on this later.
The folder structure is like so:
I've also added these templates as pipeline to Azure (which is a bit unconventional):
This is great because now I can use the editor for azure pipelines.
If I edit the .yml directly from the repo, or do that locally, I don't get the nice tooling:
Editing yaml file in azure pipelines:
Editing yaml file in azure repos:
This works but now every time the BuildTemplates repository is updated, it will run these template pipelines - which will fail.
I've tried to set trigger: none which works when importing jobs, but not when importing steps.
Here are all the yaml files that make up this build:
trigger:
- master
pool:
vmImage: 'windows-latest'
resources:
repositories:
- repository: BuildTemplates
type: git
name: HMI/BuildTemplates
extends:
template: NuGet/Jobs/NuGet.Build.yml#BuildTemplates
# Don't run templates NOTE: this works!
trigger: none
parameters:
- name: packagesToPack
type: string
default: '**/*.nuspec'
jobs:
- job: package
steps:
- template: ../Steps/NuGet.Build.yml
parameters:
packagesToPack: ${{ parameters.packagesToPack }}
# Don't run templates NOTE: this does not work!
# trigger: none
steps:
- task: NuGetToolInstaller#1
- task: NuGetCommand#2
inputs:
command: 'pack'
packagesToPack: ${{ parameters.packagesToPack }}
versioningScheme: 'byPrereleaseNumber'
majorVersion: '7'
minorVersion: '1'
patchVersion: '0'
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'Files'
publishLocation: 'Container'
When I uncomment #trigger: none from the /steps/NuGet.Build.yml file the following happens when trying to run a build (with the first mentioned yaml file)
/NuGet/Steps/NuGet.Build.yml#BuildTemplates (Line: 3, Col: 1): Unexpected value 'trigger'
My question therefore is: How can I stop templates from running automatically when I have them defined as a pipeline so that I can use the pipeline editor?
Can I disable the pipeline from running somewhere?
Can I conditionally add 'trigger: none'?
I was also thinking of create a trigger-none.yml file with the contents being only trigger: none and use extend to optionally include it or something - but I don't believe that would work.
Is there perhaps another way I can edit the templates with tooling support - is there for example a vscode extension or something?
There is an easier way without using YAML.
I will go to the pipeline
Click 3 dots, and click Settings
Set it to Disabled
The pipeline will never trigger, but you can call it from another YAML as a template and it will run within that YAML.
This is the way I have solved it in my case and it works just fine.
My best advice is to document this part internally for later use.
Unfortunately there is no real way to add a yaml file to a pipeline and stop it from running if your file contains only steps. It will result in yaml compile errors.
So it seems like there is no way to get the nice online editor for yaml templates.
The next best thing is what DreadedFrost proposed, The VSCode extension.
I've added a powershell script to auto update the schema definition:
# This powershell updates the Yaml schema file.
Set-StrictMode -Version Latest
# Configure these options before running
#
# The personal access token to use.
# Grant the Token Administration(Read & manage) or Tokens(Read & manage) permission to the PAT.
# Also see: https://stackoverflow.com/a/64868268/4122889
$pat = 'TODO'
# Name of the organization
$organizationName = "TODO"
$yamlSchemaPartUrl = "https://dev.azure.com/{0}/_apis/distributedtask/yamlschema?api-version=6.0" # &accessToken={1}
$yamlSchemaUrl = $yamlSchemaPartUrl -f $organizationName #, $pat
$outputFile = ".\yamlschema.json"
Write-Host "Going to fetch file at " $yamlSchemaUrl " to: " $(Resolve-Path -Path $outputFile)
# See the resources below for how authentication with the PAT works:
# https://tenbulls.co.uk/2020/03/11/querying-azure-devops-rest-api-with-powershell/
# https://learn.microsoft.com/en-us/rest/api/azure/devops/?view=azure-devops-rest-6.1#assemble-the-request
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$props = #{
Uri = $yamlSchemaUrl
Method = 'GET'
ContentType = 'application/json'
Headers = #{authorization = "Basic $token"}
}
# Write-Host $props.Headers.accessToken
Invoke-RestMethod #props -OutFile $outputFile
# Invoke-WebRequest $yamlSchemaUrl -OutFile $outputFile
Write-Host "Done, please restart VsCode to apply the changes."
Write-Warning "Make sure the output file is correct - if it is a bunch of html, something likely went wrong with the PAT"
Write-Host "if thats the case download the yaml schema manually via the browser, or fix the PAT"
I still find myself copy and pasting items into the online editor however.