I want ansible play book to run only when a group variable defined like authentication_required=yes if not skip the play book.
so i added authentication_required=yes in my group vars
and then
in my playbook added
when: authentication_required is defined .
my playbook skips its not taking the variable
Related
In my GitLab CICD pipeline I've defined a job with the following rule:
rules:
- if: $TERRAFORM_ENVIRONMENT == "qa" && $TERRAFORM_EXCLUDED_ENVIRONMENTS !~ /qa/
Each job has an environment clause and its name defined.
This allows me to target the pipeline to execute when TERRAFORM_ENVIRONMENT is set to "qa" while ensuring "qa" environment isn't part of TERRAFORM_EXCLUDED_ENVIRONMENTS list.
The value of TERRAFORM_EXCLUDED_ENVIRONMENTS variable is a series of comma separated environment names as a single string, for example, "dev,qa,uat".
While this rule works, I want to make the pipeline more maintainable across multiple environments without having to explicitly state the environment name. I want to be able to use $CI_ENVIRONMENT_NAME instead.
This is what I want to do:
rules:
- if: $TERRAFORM_ENVIRONMENT == "$CI_ENVIRONMENT_NAME" && $TERRAFORM_EXCLUDED_ENVIRONMENTS !~ /$CI_ENVIRONMENT_NAME/
When I tried this in my CICD pipeline, the job was executed even though "qa" was part of $TERRAFORM_EXCLUDED_ENVIRONMENTS.
Does anyone know how I can get this to work?
I am really struggling with some variables which I have in my variable group named 'android-pipeline'.
Inside this variable group, I have some variables with values.
But when I am running the pipeline it cannot read the values inside my variable group. :(
Example:
Inside the variable group, I have a variable called
$(key.alias)
I am trying to get this value which is behind the variable, see my code below.
I think something is wrong with the syntax (or the way I am using it), but I cannot find the right syntax for using my $(key.alias) variable.
Also, inside the variable group I have made sure that All pipelines have access to this Variable group.
Can someone, please tell me how I can get the value behind the $(key.alias) variable and use this in a task? I tried to follow many guides, but none are clear enough for me or not working
variables:
group: android-pipeline
buildConfiguration: 'Release'
stages:
stage: Publish
dependsOn: Build
displayName: Sign Apps
jobs:
- task: AndroidSigning#3
displayName: Android App signing
inputs:
apkFiles: '**/*.apk'
apksignerKeystoreFile: '$(androidKeyStore)'
apksignerKeystorePassword: '********'
apksignerKeystoreAlias: '$(key.alias)'
apksignerKeyPassword: '*******'
apksignerArguments: --out $(outputDirectory)/app.release.apk
zipalign: true
Since you're mixing groups and inline variables, you may need to change this from a mapping to a sequence, as in:
variables:
- group: android-pipeline
- name: buildConfiguration
value: Release
Normally when you declare variables, you can do them like a mapping, or hashtable, of name/value pairs:
variables
var1: value1 # note there's no dash at the beginning of the line
var2: value2
var3: value3
# etc
When you want to use a group, you have to change your syntax a little, so that the parser doesn't think you want to create a variable named "group" - you turn it into a sequence, or array:
variables
- group: groupname1 # note there's a dash at the beginning of the line
- group: groupname2
# etc
Here's the final wrinkle - once you've gone from the first format to the second (mapping to sequence), you have to declare new variables that are local to your file in the "sequence" style:
variables
- group: groupname1 # note there's a dash at the beginning of the line
- name: varname1
value: value1
- name: varname2
value: value2
# etc
You reference the variable further down in your pipeline the same way, with $(varname1) syntax.
If you're having problems with this, I recommend a couple of things (actually, 3):
Use script or pwsh tasks to echo or Write-Host everything you want to see but aren't, as in "pwsh: Write-Host "My var should be $(varname1)"
Turn on system diagnostics when you run the pipeline and see if the output has any useful details
Edit the pipeline through the portal - Pipelines - select your pipeline -> Edit. Then, from the ellipsis menu in the top right of the page, select "Download full YAML" - this will give download what the compiler would create. Now, it won't give you variable values, but what it can do is give you clues as to possible format or declaration errors.
I am very new to Azure pipeline and I am stuck in an issue from pas one week.
I have a Selenium c# test case which I have to execute on pipeline.
I must use the Variable groups as the input parameters for my test cases.
So, I have created appsettings.json file
appsettings.json
In my YAML code, I am able to read the variable groups, but I am not able to use it's values in the pipeline.How to do it?
To use a variable from a variable group, you need to add a reference to the group in your YAML file:
variables:
- group: my-variable-group
Thereafter variables from the variable group can be used in your YAML file.
If you use both variables and variable groups, you'll have to use name/value syntax for the individual (non-grouped) variables:
variables:
- group: my-variable-group
- name: my-bare-variable
value: 'value of my-bare-variable'
To reference a variable group, you can use macro syntax or a runtime expression. In this example, the group my-variable-group has a variable named myhello.
variables:
- group: my-variable-group
- name: my-passed-variable
value: $[variables.myhello] # uses runtime expression
steps:
- script: echo $(myhello) # uses macro syntax
- script: echo $(my-passed-variable)
You can also reference multiple variable groups in the same pipeline, and link an existing Azure key vault to a variable group and map selective vault secrets to the variable group.
Check Add & use variable groups for more information and examples. Refer to this blog post for a detailed walkthrough.
is there anyway to do multiple AND variable expression?
let's say
.template1:
only:
variables:
- $flag1 == "true"
.template2:
only:
variables:
- $flag2 == "true"
job1:
extends:
- .template1
- .template2
script: echo "something"
How will this get evaluated?
Is this going to result in only:variables overwriting each other thus template2 is the final result?
or is this going to result in a combined variables such that it becomes an OR statement
only:
variables:
- $flag1 == "true"
- $flag2 == "true"
Is there anyway to make it as and AND statement instead? keeping the templating system, and without using rules: if since using rules if has its own quirk, triggering multiple pipeline during merge request
Problem
Any time two jobs get "merged", either using extends or anchors, GitLab will overwrite one section with another. The sections don't actually get merged. In your case, you're extending from two jobs, so GitLab will completely overwrite the first variables section with the second.
Solution
One way to achieve your desired result is by defining the variables in your template jobs. The problem you will have then is the two variables sections will overwrite each other. So..
You can use a before_script section to define the variable in the 2nd template. This approach works for your specific case of 2 templates. You can use script and after_script if you need a third template, buy you'd have to use a more advanced approach if you need more templates than that.
.template1:
# We can define a variables section here, no problem
variables:
flag1: "true"
.template2:
# You can't define a second variables section here, since it will overwrite the first
# Instead, define the environment variable directly in a before-script section
before_script:
- export flag2="true"
job1:
extends:
- .template1
- .template2
only:
variables:
- $flag1 == "true"
- $flag2 == "true"
script: echo "something"
hiera.yaml
---
:hierarchy:
- node/%{host_fqdn}
- site_config/%{host_site_name}
- site_config/perf_%{host_performance_class}
- site_config/%{host_type}_v%{host_type_version}
- site/%{host_site_name}
- environments/%{site_environment}
- types/%{host_type}_v%{host_type_version}
- hosts
- sites
- users
- common
# options are native, deep, deeper
:merge_behavior: deeper
We currently have this hiera config. So the config gets merged in the following sequence common.yaml > users.yaml > sites.yaml > hosts.yaml > types/xxx_vxxx.yaml > etc. For the variable top hierarchies, it gets overwritten only if that file exists.
eg:
common.yaml
server:
instance_type: m3.medium
site_config/mysite.yaml
server:
instance_type: m4.large
So for all other sites, the instance type will be m3.medium, but only for mysite it will be m4.large.
How can I achieve the same in Ansible?
I think that #Xiong is right that you should go the variables way in Ansible.
You can set up flexible inventory with vars precedence from general to specific.
But you can try this snippet if it helps:
---
- hosts: loc-test
tasks:
- include_vars: hiera/{{ item }}
with_items:
- common.yml
- "node/{{ ansible_fqdn }}/users.yml"
- "node/{{ ansible_fqdn }}/sites.yml"
- "node/{{ ansible_fqdn }}/types/{{ host_type }}_v{{ host_type_version }}.yml"
failed_when: false
- debug: var=server
This will try to load variables from files with structure similar to your question.
Nonexistent files are ignored (because of failed_when: false).
Files are loaded in order of this list (from top to bottom), overwriting previous values.
Gotchas:
all variables that you use in the list must be defined (e.g. host_type in this example can't be defined in common.yml), because list of items to iterate is templated before the whole loop is executed (see update for workaround).
Ansible overwrite(replace) dicts by default, I guess your use case expects merging behavior. This can be achieved with hash_behavior setting – but this is unusual for Ansible playbooks.
P.S. You may alter top-to-bottom-merge behavior by changing with_items to with_first_found and reverse the list (from specific to general). In this case Ansible will load variables from first file found.
Update: use variables from previous includes in file path.
You can split the loop into multiple tasks, so Ansible will evaluate each task's result before templating next file's include path.
Make hiera_inc.yml:
- include_vars: hiera/common.yml
failed_when: false
- include_vars: hiera/node/{{ ansible_fqdn }}/users.yml
failed_when: false
- include_vars: hiera/node/{{ ansible_fqdn }}/sites.yml
failed_when: false
- include_vars: hiera/node/{{ ansible_fqdn }}/types/{{ host_type | default('none') }}_v{{ host_type_version | default('none') }}.yml
failed_when: false
And in your main playbook:
- include: hiera_inc.yml
This looks a bit clumsy, but this way you can define host_type in common.yaml and it will be honored in the path templating for next tasks.
With Ansible 2.2 it will be possible to include_vars into named variable (not global host space), so you can include_vars into hiera_facts and use combine filter to merge them without altering global hash behavior.
I'm not familiar with Puppet, so this may not be a direct mapping. But what I understand your question to be is "how do I use values in one shared location but override their definitions for different servers?". In Ansible, you do this with variables.
You can define variables directly in your inventory. You can define variables in host- and group-specific files. You can define variables at a playbook level. You can define variables at a role level. Heck, you can even define variables with command-line switches.
Between all of these places, you should be able to define overrides to suit your situation. You'll probably want to take a look at the documentation section on how to decide where to define a variable for more info.
It seems a little more basic than Hiera, but somebody has created a basic ansible lookup plugin with similar syntax
https://github.com/sailthru/ansible-oss/tree/master/tools/echelon