Pass Multi-Line Text Parameter in Jenkins to Ansible Playbook - jenkins

I have a text parameter in Jenkins that looks like so:
text(
defaultValue: '''
- 'evn-111'
- 'evn-423'
- 'evn-414'
''',
description: 'Add list of devices to create lab',
name: 'DEVICES',
)
I want to take this list of devices and pass it as a string into an ansible playbook.
However, when I pass this string into the ansible playbook like so:
extra_args = "-e devices=${ params.DEVICES }"
sh "ansible-playbook $extra_args deploy_lab.yml"
My output in Jenkins is:
ansible-playbook -e devices=
Followed by recommendations on what arguments I need to pass. Can anyone provide suggestions on how I can accomplish passing a multiline parameter to Ansible? Once I get the variable in the Ansible file, I have a template that creates another yml file using the multi-line text string passed from Jenkins.
My Ansible file looks like this:
---
- hosts: all
gather_facts: true
vars:
devices: ""
tasks:
- name: 'Create device file'
template:
src: devices.j2
dest: "host_vars/devices.yml"
mode: '0600'
delegate_to: localhost
My Template file devices.j2 looks like this:
---
devices_from_jenkins_param:
"{{ devices }}"
In the end, I want there to be a file host_vars/devices.yml that looks like this:
---
devices_from_jenkins_param:
- 'evn-111'
- 'evn-423'
- 'evn-414'

Related

Pass environment variables to reusable workflow without using 1 to 1 inputs

Right now, if I want to pass a environment variable to a reusable workflow I have to do something like this:
name: Reusable workflow
on:
workflow_call:
inputs:
my_env_var:
required: false
type: string
env:
my_env_var: ${{ inputs.my_env_var }}
However, for this I first need to define as an input each environment variable I want to pass. This works, but having to hard code the environment variables makes my reusable workflows less generic. Is there a way to pass envs without having to define them one by one? I was thinking on something like this:
name: Calling reusable workflow
on:
workflow_dispatch:
jobs:
push-image-dev:
uses: ./.github/workflows/my-reusable-workflow.yml
with:
input1: ...
input2: ...
env:
env1: ...
env2: ...
However, I have been reading some documentation and I don't think that exists. Is there any other way of doing it, as inheriting env variables or creating a single input which is a variable dictionary, which is later parsed and sets all the env vars in the reusable workflow?
I created this simple logic which allows me to pass all the environment variables I want on a 1:N relationship with respect to inputs. I created an input which expects a list of environment variables, formatted as "env=value", and which is later converted to environment variables in a step inside the workflow.
Calling the workflow:
name: Calling reusable workflow
on:
workflow_dispatch:
jobs:
my-job:
uses: ./.github/workflows/my-reusable-workflow.yml
with:
env_vars: |
env1=value1
env2=value2
env3=value3
Workflow definition:
name: My reusable workflow
on:
workflow_call:
inputs:
env_vars:
description: List of environment variables to set up, given in env=value format.
required: false
type: string
jobs:
my-job:
runs-on: ubuntu-latest
steps:
- name: Set environment variables
if: ${{ inputs.env_vars }}
run: |
for i in "${{ inputs.env_vars }}"
do
printf "%s\n" $i >> $GITHUB_ENV
done

Consuming var group value in place of yaml template parameter

I have a yml file which calls a templated stage:
- template: pipeline-templates/iac/deploy-template.yml
parameters:
envName: dev
varGroup: dev-variables-group-library
In the template I have made use of the template parameter:
parameters:
envName: ''
varGroup: ''
stages:
- stage: Deploy_for_${{ parameters.envName }}
I want to use the envName variable from the variable group, instead of the template parameters. I have tried template code like this:
parameters:
envName: ''
varGroup: ''
stages:
- stage: Deploy_for_$( envName )
When I do this, the pipeline throws an unrelated error, for example stating that the stage name cannot be duplicate. This is clearly because the variable envName is not being read.
There are other places in my template where the pipeline variable is read and used successfully, so what am I doing wrong in this particular part of the template script?
So if wanted to use a variable group need to define the group to be read in:
- group: ${{parameters.varGroup}}
After doing this should be able to reference by $(envName) or if compile time is alright can also specify ${{ varaibles.envName }}
Microsoft Documentation

Conditionally setting parameter in yml file (Azure pipeline): VAR not updating

Problem
I want to set a parameter conditionally based on which branch triggered the pipeline. If the triggered branch was feature/automated-testing, I would like to set a parameter equal to "True". See the code below.
Parts of my pipeline.yml file looks like so:
trigger:
branches:
include:
- feature/automated-testing
...
# Global variables for the pipeline
variables:
- name: "triggerRepoName"
value: "$(Build.SourceBranchName)"
stages:
# common stage. Docker build, tag and push
- stage: BuildDockerImage
displayName: "Build docker image"
variables:
...
jobs:
- template: /templates/pipelines/my-prject.yml#templates
parameters:
${{ if eq( variables.triggerRepoName, 'feature/automated-testing') }}:
runTests: "True"
${{ if ne(variables.triggerRepoName, 'feature/automated-testing') }}:
runTests: "False"
Question
When I push from branch feature/automated-testing and ´echo´ the variable runTests in the Dockerfile, it is blank. Is there something wrong with my syntax in the conditional statement?
I believe the error is in the way the variable is set conditionally, and I have therefore chosen not to supply the Dockerfile nor the other .yml template .yml used.
Please change variables.triggerRepoName to variables['triggerRepoName']. It should solve your issue.

Ansible vars file group_vars/"{{ param }}"/vars.yml was not found on the Ansible Controller

I am trying pass value from jenkins to ansible. However, I am hitting below exception. This only happen for group_vars, for hosts, there is no issue.
ERROR! vars file group_vars/"{{ param }}"/vars.yml was not found on the Ansible Controller
- hosts: "{{ param }}"-value
roles:
- tests
vars_files:
- group_vars/"{{ param }}"/vars.yml
- group_vars/all/vars.yml
did you try:
- hosts: "{{ param }}-value"
roles:
- tests
vars_files:
- group_vars/{{ param }}/vars.yml
- group_vars/all/vars.yml
the quotes " are only needed when a value starts with {{.

Azure pipelines UI to accept parameters (like Jenkins)

Jenkins has a UI concept with dropdown lists, etc. to allow users to specify variables at run time. This has proven essential in our builds to make decisions in the pipeline (ie. which agent to run on, code base to choose, etc). By allowing parameters we are able to have a single pipeline/definition handle the same task for many clients/releases/environments.
I have been watching many people over the past year ask for this - to eliminate the number of almost identical build definitions - is there a best practice to handle this? Would be nice to have a single build definition for a specific task that can be smart enough to handle parameters.
Edit : example of possible pseudo-code to build on levi-lu#MSFT's suggestion.
parameters:
- name: ClientName
displayName: Pool Image
default: Select client
values: powershell
valuesScript : [
assemble curl request to http://myUrl.com/Clients/GetAll
]
- name: TargetEnvironment
displayName: Client Environment
type: string
values: powershell
valuesScript: [
assemble curl request using above parameter value to
https://myUrl.com/Clients/$(ClientName)/GetEnvironments
]
trigger: none
jobs:
- job: build
displayName: Run pipeline job
pool:
vmImage: windows-latest
parameters:
ClientName : $(ClientName)
TargetEnvironment : $(TargetEnvironment)
steps:
- script: echo building $(Build.BuildNumber)
Runtime parameters is available now. You can now set runtime parameters at the beginning of your pipepline YAML using parameters. For below example:
parameters:
- name: image
displayName: Pool Image
default: ubuntu-latest
values:
- windows-latest
- vs2017-win2016
- ubuntu-latest
- ubuntu-16.04
- macOS-latest
- macOS-10.14
- name: test
displayName: Run Tests?
type: boolean
default: false
trigger: none
jobs:
- job: build
displayName: Build and Test
pool:
vmImage: ${{ parameters.image }}
steps:
- script: echo building $(Build.BuildNumber)
- ${{ if eq(parameters.test, true) }}:
- script: echo "Running all the tests"
Above example is from Microsoft official document. Click here to learn more about runtime parameters.
When you run above Yaml pipeline, You will be able to select the parameter's value from the dropdown list. See below screenshot.
Update: To set variables dynamically at runtime.
You can use the task.setvariable logging command to set variables dynamically in scripts.
For below example: $resultValue is the value from rest api call. And its value is assigned to variable VariableName
- powershell: |
$resultValue = call from Rest API
echo "##vso[task.setvariable variable=VariableName]$resultValue"
Check document here for more information.

Resources