look up variables and change them from an ansible vault dynamically - ansible

I am new to ansible and I have problems when I want to replace variables in a configuration file. The case is that I have tags in this file to be replaced by the value found in ansible-vault that has the same name as the tag in the configuration file.
the configuration file looks like this:
mongo.uri=<%=#dbruchost%>
mongo.replica.set=set0
mongo.database=<%=#dbrucdb%>
mongo.user=<%=#dbrucuser%>
mongo.password=<%=#dbrucpass%>
and the ansible-vault is as follows
vars:
dbruchost: "test.test:27017"
replica.set: "set0"
dbrucdb: "database1"
dbrucuser: "data"
dbrucpass: "d4t4"
jenkinsuser: "jenkinstest"
jenkinspassword: "j3nkins"
Actually I change the variables one by one with regex
- name: Replace uri
replace:
path: /tmp/artifacts/surveyMonkey/application.properties
regexp: "<%=#dbruchost%>"
replace: vars.dbruchost
But I would like to do it dynamically. Is there any possibility for ansible to read the tags from the application properties and look for them in the ansible-vault and replace them?

why dont use template for your config file:
use a template file.j2 like this for example:
mongo.uri={{ dbruchost }}
mongo.replica.set=set0
mongo.database={{ dbrucdb }}
mongo.user={{ dbrucuser }}
mongo.password={{ dbrucpass }}
you add a task to create you config file with the module template
a sample of task: put your config.j2 in templates dir
tasks:
- name: Dump all variables
template:
src: file.j2
dest: /tmp/artifacts/surveyMonkey/application.properties
i suppose you have access to your vault variables

Related

How to write a variable value in a file using ansible.builtin.template module?

I wanted to log content of a variable in a file. I did it like this,
- name: write infraID to somefile.log
copy:
content: "{{ infraID.stdout }}"
dest: somefile.log
And it worked. But in the documentation for copy here, I found that they have recommended to use template instead of copy in such cases.
For advanced formatting or if content contains a variable, use the
ansible.builtin.template module.
I went through the examples given at the documentation for template module here. But I was unable to figure out something that works in my scenario. Could you please show me how to do this properly in recommended way ?
Thanks in advance !! Cheers!
The template module does not have a content property.
You have to create a file that contains your template, for example:
templates/infra-id-template
{{ infraID.stdoud }}
playbook
---
- hosts: localhost
tasks:
- name: Get infra ID
shell: echo "my-infra-id"
register: infraID
- name: Template the file
template:
src: infra-id-template
dest: infra-id-file

I need to replace this <ServerURL>https://localhost:${my.port}${my.context}services/</ServerURL> using ansible

hi i need to replace below string in ansible
'https://localhost:${mgt.transport.https.port}${carbon.context}services/'
with
'localhost:2222/services'
i have used a command for that using ansible. but it doesn't working.
name: set ServerURL of the AuthManager [HUB_HOME]/repository/conf/api-manager.xml
replace:
dest: "{{packFolderNameAM}}/repository/conf/api-manager.xml"
regexp: '<ServerURL>https://localhost:${my.port}${my.context}services/</ServerURL>'- name: set ServerURL of the AuthManager [HUB_HOME]/repository/conf/api-manager.xml
replace: 'localhost/9444/services'
before: 'Admin username for the Authentication manager'
backup: yes
please help me with this. Thankyou!!
As api-manager.xml is a file. We can keep in side templates: as different files with and dynamically copy the file using tags: in tasks:
This will prevent the scripting.
Or
Keep the template with the mentioned variables and define variables in playbooks var:
or
in role based var /main.yml file https://localhost:${my.port}${my.context}services/
Then variables will get populated
EXAMPLE:

Include external yaml file in ansible task

I am creating an ecs_taskdefinition in ansible, but I would like the task-defintion in a sperate file. Can I somehow do something like this:
ecs_taskdefintion:
containers: {{ load_external_yaml containers.yaml }}
volumes: {{ load_external_yaml_volumes.yaml }}
So I want to load the yaml data from external files.
You may try to combine file lookup and from_yaml filter like this:
{{ lookup('file','containers.yaml') | from_yaml }}
Remember that lookups are local, so containers.yaml should be on ansible control host.
Since your file is YAML, you may use include_vars
from https://docs.ansible.com/ansible/latest/collections/ansible/builtin/include_vars_module.html :
- name: Setup vars
tags: ["always"]
include_vars:
file: "./vars/tintin.yaml"
name: tintin
Use tintin as a normal var everywhere!

Is it possible to use inline templates?

I need to create a single file with the contents of a single fact in Ansible. I'm currently doing something like this:
- template: src=templates/git_commit.j2 dest=/path/to/REVISION
My template file looks like this:
{{ git_commit }}
Obviously, it'd make a lot more sense to just do something like this:
- inline_template: content={{ git_revision }} dest=/path/to/REVISION
Puppet offers something similar. Is there a way to do this in Ansible?
Another option to the lineinfile module (as given by udondan's answer) would be to use the copy module and specify the content rather than a source local to the Ansible host.
An example task would look something like:
- name: Copy commit ref to file
copy:
content: "{{ git_commit }}"
dest: /path/to/REVISION
I personally prefer this to lineinfile as for me lineinfile should be for making slight changes to files that are already there where as copy is for making sure a file is in a place and looking exactly like you want it to. It also has the benefit of coping with multiple lines.
In reality though I'd be tempted to make this a template task and just have a the template file be:
"{{ git_commit }}"
Which gets created by this task:
- name: Copy commit ref to file
template:
src: path/to/template
dest: /path/to/REVISION
It's cleaner and it's using modules for exactly what they are meant for.
Yes, in that simple case it is possible with the lineinfile module.
- lineinfile:
dest=/path/to/REVISION
line="{{ git_commit }}"
regexp=".*"
create=yes
The lineinfile module usually is used to ensure that a specific line is contained inside a file. The create=yes option will crete the file if it does not exist. The regexp=.* option makes sure you do not add content to the file if git_commit changes, because it would by default simply make sure the new content is added to the file and not replace the previous content.
This only works since you only have one line in your file. If you'd had more lines this obviously would not work with this module.
This issue seems to be resolved. However, if the template file was more than one variable, i.e. a json file, it is possible to use copy module with content parameter, with a lookup, i.e.:
# playbook.yml
---
- name: deploy inline template
copy:
content: '{{ lookup("template", "inlinetemplate.yml.j2") }}'
dest: /var/tmp/inlinetempl.yml
# inlinetemplate.yml.j2
---
- name: {{ somevar }}
abc: def
If you need insert the template to the exist file, you can insert through the lineinfile module.
- name: Insert jinja2 template to the file
lineinfile:
path: /path/file.conf
insertafter: "after this line"
line: "{{ lookup('template', 'template.conf.j2') }}"

Using variables for file name and file contents in lineinfile module

I am trying to read the contents of a file, store these in a variable and then insert them into another file if they don't already exist.
So, how I'm attempting to go about this is as follows:
# Create a variable that represents the path to the file that you want to read from
ssh_public_key_file: '../../jenkins_master/files/{{ hostvars[inventory_hostname]["environment"] }}/id_rsa.pub'
# Create a variable that represents the contents of this file:
ssh_public_key: "{{ lookup('file', '{{ ssh_public_key_file }}') }}"
I then use these variables in my Ansible playbook as follows:
- name: Install SSH authorized key
lineinfile: create=yes dest=~/.ssh/authorized_keys line=" {{ ssh_public_key }}" mode=0644
However, when I try and run the playbook, I get the following error message:
could not locate file in lookup: {{ ssh_public_key_file }}
Can anyone recommend a solution or suggest what I may have done wrong?
Thanks,
Seán
You have to change the line to:
# Create a variable that represents the contents of this file:
ssh_public_key: "{{ lookup('file', ssh_public_key_file) }}"
If you need to concatenate variables and strings you can do it like this:
# Example with two variables
ssh_public_key: "{{ lookup('file', var_1+var_2) }}"
# Example with string and variable
ssh_public_key: "{{ lookup('file', '~/config/'+var_1) }}"
. .
First I would make sure that your ssh_public_key_file variable is set up properly. If you add a task like the following what does it show?
- name: display variable
debug: var=ssh_public_key_file
If the output looks something like this then the variable isn't defined properly (eg. the "environment" fact doesn't exist for the host):
ok: [localhost] => {
"ssh_public_key_file": "../../jenkins_master/files/{{ hostvars[inventory_hostname][\"environment\"] }}/id_rsa.pub"
}
However if everything is defined properly then your output should show the variables replaced with their correct values:
ok: [localhost] => {
"ssh_public_key_file": "../../jenkins_master/files/foo/id_rsa.pub"
}
Once you've verified that then I would do the same thing with your ssh_public_key variable. Just output its value using the debug module. It should display as the contents of the public key file.
One other thing I would strongly suggest is to avoid using lineinfile altogether. Since you're working with SSH keys I would recommend you use the authorized_key module instead. It's a much cleaner way of managing authorized_keys files.

Resources