Ansible playbook failed when running a shell script - ansible

So I created this Ansible playbook to:
copy a zip file and unzip it
copy a zip file and unzip it
make script inside the file executable
run the script
enable 2 services
- name: fideliplaybook
hosts: k8scluster
tasks:
- name: copying file with playbook
become: true
copy:
src: /home/lc/lc.zip
dest: /home/lc/
mode: 755
- name: Update apt cache and install unzip
become: true
command: apt install unzip
- name: unzip file
become: true
unarchive:
src: /home/lc/lc.zip
dest: /home/lc/
- name: make script executable
become: true
file: dest=/home/lc/lc/install.sh mode=755
- name: Execute the script
become: true
command: sh /home/lc/lc/install.sh
- name: Enable service 1
become: true
command: systemctl enable service1.service
- name: Enable service 2
become: true
command: systemctl enable service1.service
the issue that I am facing here that when ansible is trying to execut the script "install.sh"
it somehow fails becuse script cant find 2 other scripts although the other scripts are in the same file.
so 3 scripts are in lc.zip but when running install.sh with ansible it cant find the 2 other scripts.
I fixed the issue by typing the full path of the 2 scripts inside the first script.
but anyone have an idea why this issue occuers.
one more quistion when i used ansible hosts file to define hosts and variables it didnt worked with INI like this:
[webservers]
www[01:50].example.com
It only woks In YAML:
...
webservers:
hosts:
www[01:50].example.com:
Anyone know why?

About the script not finding the other two scripts, you should update the full path to the other two scripts if the path is always fixed OR if you want to use the relative path, you can try the following,
- name: Execute the script
become: true
command: sh install.sh
args:
chdir: /home/lc/lc/
And the inventory looks fine. Here is a test to confirm.
# cat test.ini
[webservers]
tstsrv[7:8]
# ansible-playbook -i test.ini test.yaml -u admin -k
SSH password:
PLAY [webservers] ***********************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [tstsrv8]
ok: [tstsrv7]
TASK [print hostname] ***********************************************************************************************************************************************
changed: [tstsrv8]
changed: [tstsrv7]
PLAY RECAP **********************************************************************************************************************************************************
tstsrv7 : ok=2 changed=1 unreachable=0 failed=0
tstsrv8 : ok=2 changed=1 unreachable=0 failed=0
#
Consider script module dedicated for running scripts on targets, if possible.

Related

How to load environment variable in the file to current shell via ansible

my environment:
OS: ubuntu/focal and current user: ubuntu
I'm trying to append some environment variable content to /etc/environment file. Then want to load these setting on current shell via ansible
ubuntu#infra-node1:~$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
LC_ALL="en_US.UTF-8"
LANG="en_US.UTF-8"
LANGUAGE="en_US:en"
EDITOR="vi"
http_proxy=http://myproxy:8080
no_proxy=10.1.1.0/24,127.0.0.1
as owner of file /etc/environment is root, I need to take root to manipulate file then load this file to current user(ubuntu) shell space.
so, relevant ansible configuration like
$ cat ./ansible.cfg
[defaults]
inventory = ./hosts
forks = 3
become = true
become_method = sudo
become_user = root
and play book file like
$ cat top.yaml
---
- name: set environment
gather_facts: false
hosts: infra
roles:
- role: environment
tags: environment
$ cat roles/environment/tasks/main.yaml
---
- name: deploy environment file
copy:
src: environment
dest: /etc/environment
backup: yes
- name: load environment
become: false
shell: source /etc/environment
args:
executable: /bin/bash
it was able to run but failed to check environment variable
ubuntu#infra-node1:~$ ansible-playbook -i hosts -t environment top.yaml
PLAY [set environment]
TASK [environment : deploy environment file]
ok: [10.1.1.31]
TASK [environment : load environment]
changed: [10.1.1.31]
PLAY RECAP
10.1.1.31: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ubuntu#infra-node1:~$ env | grep proxy
how to achieve that target properly via ansible???
please help.
Thanks a lot in advance.
BR//

How do I use ansible_become_password on different target in the same playbook

My playbook has a task to copy a file from the local box to the remote box and the last task has to use sudo to root. I am not getting it to work.
In my inventory I am trying to use I am just trying to get it to work then I can lock it down with ansible vault. I just need to see it work first.
[logserver]
mylogserver ansible_ssh_user=myuser ansible_become_password=mypassword
In my playbook the last task using the -host param to do the work on the remote box, earlier task copies file to remote server but then I add a remote host to get the work done.
# Cat file and append destination file
- name: cat files to destination file
hosts: mylogserver
gather_facts: no
become_exe: "sudo su - root"
tasks:
- name: cat contents and append to destination file
shell:
cmd: /usr/bin/cat /var/tmp/test_file.txt >> /etc/some/target_file.txt
For example, the inventory
shell> cat hosts
test_11 ansible_ssh_user=User1 ansible_become_password=mypassword
[logserver]
test_11
and the playbook
shell> cat pb.yml
- hosts: logserver
gather_facts: false
become_method: su
become_exe: sudo su
become_user: root
become_flags: -l
tasks:
- command: whoami
become: true
register: result
- debug:
var: result.stdout
work as expected
shell> ansible-playbook -i hosts pb.yml
PLAY [logserver] ******************************************************************************
TASK [command] ********************************************************************************
changed: [test_11]
TASK [debug] **********************************************************************************
ok: [test_11] =>
result.stdout: root
PLAY RECAP ************************************************************************************
test_11: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Notes:
Configuration of the method, e.g. become_method: su, is missing. See DEFAULT_BECOME_METHOD. The default is 'sudo'. For details see Using Become Plugins
See details of the plugin from the command line shell> ansible-doc -t become su
Use become_flags to specify options to pass to su, e.g. become_flags: -l
Use become_user to specify the user you 'become' to execute the task, e.g. become_user: root. This example is redundant. 'root' is the default
Specify become: true if the task shall use the configured escalation. The default is 'false'. See DEFAULT_BECOME
Configure sudoers, e.g.
- command: grep User1 /usr/local/etc/sudoers
become: true
register: result
- debug:
var: result.stdout
gives
TASK [debug] ***************************************************************
ok: [test_11] =>
result.stdout: User1 ALL=(ALL) ALL
Encrypt the password
Remove the password from inventory hosts and put it into a file, e.g. in host_vars
shell> cat hosts
test_11 ansible_ssh_user=User1
[logserver]
test_11
shell> cat host_vars/test_11/ansible_become_password.yml
ansible_become_password: mypassword
Encrypt the password
shell> ansible-vault encrypt host_vars/test_11/ansible_become_password.yml
Encryption successful
shell> cat host_vars/test_11/ansible_become_password.yml
$ANSIBLE_VAULT;1.1;AES256
35646364306161623262653632393833323662633738323639353539666231373165646238636236
3462386536666463323136396131326333636365663264350a383839333536313937353637373765
...
Test the playbook
shell> ansible-playbook -i hosts pb.yml
PLAY [logserver] ******************************************************************************
TASK [command] ********************************************************************************
changed: [test_11]
TASK [debug] **********************************************************************************
ok: [test_11] =>
result.stdout: root
...

Why ansible doesn't do the task at first attempt in Gitlab?

I am executing some ansible playbooks via gitlab-ci and what I could see is
Ansible playbook executing successfully through pipeline, but it doesn't produce the output it is intended to do
When I retry the gitlab job, it produces the output I needed.
This is one of the many playbooks I am executing through gitlab:
1_ca.yaml
---
- hosts: 127.0.0.1
connection: local
tasks:
- name: Create ca-csr.json
become: true
copy:
dest: ca-csr.json
content: '{"CN":"Kubernetes","key":{"algo":"rsa","size":2048},"names":[{"C":"US","L":"Portland","O":"Kubernetes","OU":"CA","ST":"Oregon"}]}'
- name: Create ca-config.json
become: true
copy:
dest: ca-config.json
content: '{"signing":{"default":{"expiry":"8760h"},"profiles":{"kubernetes":{"usages":["signing","key encipherment","server auth","client auth"],"expiry":"8760h"}}}}'
- name: Create the ca.pem & ca-key.pem
# become: true
shell: |
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
Basically what does this do is, it creates some certs I needed.
But in the first attempt even though pipeline passes and it doesn't generate these certs. When I restart (running the same job for the second time) that particular job in gitlab it generates these certs.
Why this is happening?
This is how my .gitlab-ci.yaml looks like:
Create-Certificates:
stage: ansible-play-books-create-certs
retry:
max: 2
when:
- always
script:
- echo "Executing ansible playbooks for generating certficates"
- ansible-playbook ./ansible-playbooks/1_ca/1_ca.yaml
- ansible-playbook ./ansible-playbooks/1_ca/2_admin.yaml
- ansible-playbook ./ansible-playbooks/1_ca/3_kubelet.yaml
- ansible-playbook ./ansible-playbooks/1_ca/4_kube-controller.yaml
- ansible-playbook ./ansible-playbooks/1_ca/5_kube-proxy.yaml
- ansible-playbook ./ansible-playbooks/1_ca/6_kube-scheduler.yaml
- ansible-playbook ./ansible-playbooks/1_ca/7_kube-api-server.yaml
- ansible-playbook ./ansible-playbooks/1_ca/8_service-account.yaml
- ansible-playbook ./ansible-playbooks/1_ca/9_distribute-client-server-cert.yaml
# when: delayed
# start_in: 1 minutes
tags:
- banuka-gcp-k8s-hard-way
PS: These ansible playbooks are executing in the ansible host itself, not in remote servers. So I can log into the ansible master server and check if these files are created or not.
running your playbook without the last shell module produces the follwing output:
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [127.0.0.1] **************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [127.0.0.1]
TASK [Create ca-csr.json] *****************************************************************************************************************************************************************************************
[WARNING]: File './ca-csr.json' created with default permissions '600'. The previous default was '666'. Specify 'mode' to avoid this warning.
changed: [127.0.0.1]
TASK [Create ca-config.json] **************************************************************************************************************************************************************************************
[WARNING]: File './ca-config.json' created with default permissions '600'. The previous default was '666'. Specify 'mode' to avoid this warning.
changed: [127.0.0.1]
PLAY RECAP ********************************************************************************************************************************************************************************************************
127.0.0.1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
and checking the existence:
$ ls ca* -al
-rw------- 1 root root 155 Aug 17 02:48 ca-config.json
-rw------- 1 root root 129 Aug 17 02:48 ca-csr.json
so although it's quite dirty way of writing a playbook - it works.
Why is it dirty ? :
you're not using any inventory
you should use local_action and not connection: local for local tasks
you are misusing ansible that is multi-node configuration management to do a bash script task
so in conclusion - there's nothing wrong with your ansible playbook - or maybe the file permissions (?) and if it does not run - you should look more in the gitlab-ci direction.
you need to provide more details on Gitlab-CI setup but - maybe the stage is not correct ?

Ansible when statement with variable from another task

can someone help me please?
I want to create a folder at host "cfme_tester-0".
For this I check variable "osp_version" from "undercloud-0" host and based on the result I should create a folder at the "cfme_tester-0" host.
Here is my playbook:
- name: take openstack version
hosts: undercloud-0
become: true
become_user: stack
tasks:
- name: creating flavor
shell: |
source /home/stack/stackrc
cat /etc/rhosp-release | egrep -o '[0-9]+' | head -1
register: osp_version
ignore_errors: True
- debug: msg="{{ osp_version.stdout }}"
- name: set up CFME tester
hosts: cfme_tester-0
become: yes
become_user: root
tasks:
- name: Run prepare script for OSP10
debug:
shell: |
cd /tmp/cfme/ && mkdir osp10
when: "'10' in osp_version.stdout"
- name: Run prepare script for OSP13
debug:
shell: |
cd /tmp/cfme/ && mkdir osp13
when: "'13' in osp_version.stdout"
But an error occurs:
TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [undercloud-0] => {
"msg": "10"
}
PLAY [set up CFME tester] *****************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [cfme_tester-0]
TASK [Run prepare script for OSP10] *******************************************************************************************************************************************************************************
fatal: [cfme_tester-0]: FAILED! => {"msg": "The conditional check ''10' in osp_version.stdout' failed. The error was: error while evaluating conditional ('10' in osp_version.stdout): 'osp_version' is undefined\n\nThe error appears to have been in '/root/infrared/rhos-qe-core-installer/playbooks/my_setup.yaml': line 20, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Run prepare script for OSP10\n ^ here\n"}
to retry, use: --limit #/root/infrared/rhos-qe-core-installer/playbooks/my_setup.retry
PLAY RECAP ********************************************************************************************************************************************************************************************************
cfme_tester-0 : ok=1 changed=0 unreachable=0 failed=1
undercloud-0 : ok=3 changed=1 unreachable=0 failed=0
Variables are per-host (because otherwise, what happens when you run a task on multiple hosts and register a variable?). In your first task, you are setting the osp_version variable for host undercloud-0.
If you want to use this variable in your second play, which is running on cfme_tester-0, then you should read the Magic Variables, and How To Access Information About Other Hosts section of the Ansible documentation. You'll need to refer to the variable via the hostvars dictionary, so your second play will look like:
- name: set up CFME tester
hosts: cfme_tester-0
become: yes
become_user: root
tasks:
- name: Run prepare script for OSP10
shell: |
cd /tmp/cfme/ && mkdir osp10
when: "'10' in hostvars['undercloud-0'].osp_version.stdout"
- name: Run prepare script for OSP13
shell: |
cd /tmp/cfme/ && mkdir osp13
when: "'13' in hostvars['undercloud-0'].osp_version.stdout"
...but note that if you're just creating a directory, you would be better off just using the file module instead:
- name: Run prepare script for OSP10
file:
path: /tmp/cfme/osp10
state: directory
when: "'10' in hostvars['undercloud-0'].osp_version.stdout"

Ansible file creation fails without any error

After running the the below Ansible Yaml file the output shows file is created and the content is changed
The YAML File
---
- hosts: all
gather_facts: yes
connection: local
tasks:
- name: Check the date on the server.
action: command touch /opt/b
- name: cat the Content
action: command cat /opt/b
Running the Playbook
root#my-ubuntu:/var/lib/awx/projects/test# ansible-playbook main.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [ansible-ubuntu-1604-db]
TASK [Check the date on the server.] *******************************************
changed: [ansible-ubuntu-1604-db]
[WARNING]: Consider using file module with state=touch rather than running touch
TASK [cat the Content] *********************************************************
changed: [ansible-ubuntu-1604-db]
PLAY RECAP *********************************************************************
ansible-ubuntu-1604-db : ok=3 changed=2 unreachable=0 failed=0
The Message Display changed=2 and tasks doesnt created any file
ubuntu#ansible-ubuntu-1604-db:~$ ls -l /opt/
total 0
The Env
Ansible Controller on the MAC Local Desktop
Taget Node is on Cloud
With connection: local in your playbook, you tell Ansible to execute all tasks on your local ansible controller. So file is created on your local machine.
Remove connection: local and try again.

Resources