Ansible AWX - get project url and user - ansible

I'm in the process of migrating Ansible playbooks into Ansible AWX projects.
Previously I'd checkout the Ansible playbook from git, then run it from the command line.
In this specific case I have a Ansible Playbook that creates VMware virtual machines. I use the following tasks to gather information about the git repo and current git commit hash, and use this info in the VM annotations, so that it can be later used to identify the exact instructions used to create the VM.
- name: return git commit hash
command: git rev-parse HEAD
register: gitCommitHash
delegate_to: localhost
become: false
become_user: "{{ lookup('env','USER') }}"
- name: get remote git repo
command: git config --get remote.origin.url
register: gitRemote
delegate_to: localhost
become: false
become_user: "{{ lookup('env','USER') }}"
I realize that playbooks run in AWX run as the awx user.
Is there anyway, in a playbook, I can get the AWX user that is running the AWX template, and can I get the url for the Ansible AWX project?
Update
I found I can get the AWX that is running the template by using the {{awx_user_name}}, but have not yet found out how to get the git remote url of the project/playbook.

I ran a job template with a simple playbook:
---
- name: Debug AWX
hosts: all
tasks:
- debug:
var: vars
And in the output, I could see these variables:
"awx_inventory_id": 1,
"awx_inventory_name": "Demo Inventory",
"awx_job_id": 23,
"awx_job_launch_type": "manual",
"awx_job_template_id": 10,
"awx_job_template_name": "Debug AWX",
"awx_project_revision": "3214f37f271ad589f7a63d12c3d1ef9fa0972d91",
"awx_user_email": "admin#example.com",
"awx_user_first_name": "",
"awx_user_id": 1,
"awx_user_last_name": "",
"awx_user_name": "admin",
So, no you don't get the AWX project url from the job. But you get the project ID!.
So you could query the API to get the job_template details, then query the project details to get the url. I would suggest to use the CLI for these steps.

Related

AWX fetch module directory missing

I'm working on this environment
ansible version = 2.5.1
python version = 2.7.17
awx version = 8.0.0
I'm trying to change my ansible project to AWX ( I installed AWX via docker)
I had two hosts called ansible-server and k8s-master
I originally fetched k8s-master's config.yaml to ansibler-server with this playbook
my fetch module worked on ansible playbook on cli (it worked on host : ansible-server)
- name: Fetch config.yaml from K8S-Master
hosts: K8S-Master
become: yes
fetch:
src: /home/vagrant/config.yaml
dest: /home/vagrant/config.yaml
flat: true
but when I play same playbook on AWX command, it shows me playbook has successed but no file exists on ansible-server
this is my inventory on AWX
Inventory : Demo-Inventory
Groups : Ansible-Server, K8S-Master
HOSTS(one each) : 192.168.32.145, 192.167.32.150
and I added my host ip on each group
I've fixed settings -> jobs -> job execution path and "extra environment variables" path to
/home/vagrant/
and
{
"HOME":"/home/vagrant/"
}
I've also checked those directory
/var/lib/awx/projects
/home/awx
I'm not sure how can I find AWX container's file system
I'll add more informations if I need to.
I found out that the file goes to container's directory
/var/lib/docker/overlay2/RANDOMCODE/merged/home/config.yaml
how can I get those file (as shell script or as another playbook)

Ansible pre-check before run playbook

Is it possible to add a condition before to run a playbook which check if there is a title, a description, the environment and the versions on the playbook ?
For example my test.yml playbook:
---
#Apache servers
#Linux
#Ubuntu
#version 2.1.1
#Testing for secure the webserver
task:
xxxxxx
xxxxxx
And I would like to check if all the comment before are present before to run this task !
I tried to test this solution :
name: run Apachetest playbook
include: test.yml
when: "{{ lookup('file', 'test.yml').split('\n')[1] == '#Apache servers' }}"
But still not working...
BS
Comments are, well, comments. They do not impact the execution and are just ignored. So there is no way, and actually no real reason, to check if comments are present or not. You would need to implement that yourself.
To check playbooks, roles, etc. there is ansible-lint which will verify the syntax and some best practices (e.g. if you use a command or shell for something there is a module for) but this does not verify comments (again, checking for comments does not make sense from a execution perspective, as they are ignored).
You want some information to be present in your playbook, that is what I understand. If I was you, I would either create a git hook, that verifies if the information is present before letting you push that code to your repository or establish a proper review-process, where the reviewer only accepts a merge/pull request, if the information is present.
Otherwise, here is the code, that will do what you are trying to do:
---
#Apache server
- hosts: all
tasks:
- name: set fact
set_fact:
pb: "{{ lookup('file', 'test.yml').split('\n')[1] }}"
- name: check if we found it
debug:
msg: 'found'
when: "'#Apache server' in pb"
You could use the apache role for apache installed like that
---
- hosts: apache
sudo: yes
tasks:
- name: install apache2
apt: name=apache2 update_cache=yes state=latest
have a look here how-to-install-apache-on-ansible

How to make an ansible playbook that works according to user input?

In my ansible playbook i am taking 2 inputs from user and i also wanted to take a third input which should be optional at times and if user provides the value for var3 then playbook must execute a task otherwise it should not, so what is the way to achieve this?
Also i wanted to know that i am using awx open-source UI for ansible so i choose the hosts to run the playbook in ansible awx inventory, after that what should i write in 'hosts' of my playbook or it can be left alone.
- name: Updating "{{ service_name }}" server codebase and starting its service.
hosts: all
tasks:
- name: Stopping nginx service
command: sudo service nginx stop
- name: Performing git checkout in the specified directory "{{ path }}"
command: git checkout .
args:
chdir: "{{ path }}"
- name: Running npm install in the directory "{{ path }}"
command: npm install
args:
chdir: "{{ path }}/node_modules"
- name: Restarting the "{{ service_name }}" service
command: sudo service "{{ service_name }}" restart
- name: Restarting the nginx service
command: sudo service nginx restart
Who is the user in this instance? you? if you are the user then you can run
ansible-playbook -i hosts <your-playbook> -e "service_name=<yourservice>"
to dynamically change the service_name variable upon playbook excecution.
you can then add the second variable to the command also, but be aware with the 'optional' third variable as i'm sure if you do not reference all variables in your playbook you will get an error.
EDIT: You will need to ref both service_name and path variables when you execute the ansible-playbook command, where is the 3rd variable as it doesnt appear to be in your provided code sample?

Get Ansible on windows to print version

I am trying to get an Ansible task to print the version used while running on Windows 10.
I am currently trying something like this:
---
# Source: https://serverfault.com/a/695798
- name: Get version
win_shell: ansible --version
register: ansibleVersion
# How I chose to expose the version collected
- name: Display version
win_msg:
msg: "Ansible Version: {{ ansibleVersion.stdout }}"
display_seconds: 30
However, I am getting this output:
"stderr": "ansible : The term 'ansible' is not recognized as the name of a cmdlet, function, script file, or operable program. \r\nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.\r\n
Full disclosure, I am new to Ansible. I have tried win_command, win_shell, and am not really sure what all to try next.
The Windows machines can be provisioned using ansible but not installed on Windows.
You can configure the Windows machine from a Linux machine as the controller host.
And you can run the ansible-playbook from this controller host which will run on the windows machine.
---
- hosts: all
tasks:
- name: Get Windows version
win_shell: "systeminfo /fo csv | ConvertFrom-Csv | select OS*, System*, Hotfix* | Format-List"
register: windows_version
- name: Print Windows host information
debug:
msg: "{{ windows_version }}"
Save this as main.yml
Add the Windows host IP in hosts file
[win]
172.16.*.*
[win:vars]
ansible_user=user
ansible_password=password
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
Run the playbook using the following command
ansible-playbook -i hosts main.yml
If you want ansible on Windows, then there are other installation methods to run it on Windows.
Also mentioned in the comments.
I have attached some links to setup ansible on Windows 10 subsytem for Linux,
Ansible - Windows Frequently asked questions
Using Ansible through Windows 10's Subsystem for Linux
Hope it solves your issue.
Thank you to all those who answered and commented. The articles were very informative, and I learned a much more about Ansible. The answers put me on the scent of the actual task I made.
To restate my comment on the original question, I had a misunderstanding. Because on my Windows machine I had to add a user ansible, I thought it was being run locally somehow. However, it turns out, Ansible deploys are being run from a Linux VM.
Once I had this misunderstanding cleared up, I realized I needed to use delegate_to: 127.0.0.1 in my Ansible task. Here is my Check Ansible version task:
---
# SEE: https://serverfault.com/a/695798/514234
- name: Check Ansible version
command: ansible --version
register: ansibleVersion
delegate_to: 127.0.0.1
- name: Print version
debug:
msg: "Ansible Version: {{ ansibleVersion.stdout }}"

Is there a better way to conditionally add a user to a group with Ansible?

I have a playbook that provisions a host for use with Rails/rvm/passenger. I'd like to add use the same playbook to setup both test and production.
In testing, the user to add to the rvm group is jenkins. The one in production is passenger. My playbook excerpt below does this based on the inventory_hostname parameter.
It seems like adding a new user:/when: block in the playbook for every testing or production host is the wrong way to go here. Should I be using an Ansible role for this?
Thanks
---
- hosts: all
become: true
...
tasks:
- name: add jenkins user to rvm group when on testing
user: name={{ item }}
shell=/bin/bash
groups=rvm
append=yes
with_items:
- jenkins
when: "'bob.mydomain' in inventory_hostname"
- name: add passenger user to rvm group when on rails production
user: name={{ item }}
shell=/bin/bash
groups=rvm
append=yes
with_items:
- passenger
when: "'alice.mydomain' in inventory_hostname"
Create an inventory file called inventories/testing
[web]
alice.mydomain
[testing:children]
web
This will control what hosts are targeted when you run your playbook against your testing environment.
Create another file called group_vars/testing
rvm_user: jenkins
This file will keep all variables required for running a playbook against the testing environment. Your production file should have the same variables, but with different values.
Finally in your playbook:
---
- hosts: all
become: true
...
tasks:
- name: add user to rvm group
user:
name: "{{ rvm_user }}"
shell: "/bin/bash"
groups: rvm
append: yes
Now, when you want to run your playbook, you execute it like so:
ansible-playbook -i inventories/testing site.yml
Ansible will do the right thing, and look for a testing file in group_vars and read variables from there. It will ignore variables in a file or folder not named after your environment with the exception of a file called all which is intended to be for common variables across playbooks.
Good luck - Ansible is an amazing tool :)

Resources