Friday, December 12, 2025

Executeing a command in Pod of Kubernetes or Openshift

 I am working on an application which is hosted in kubernetes and currently it does not support any kind of API. The only way to automate the workflow what we are trying to achieve is to login into one of the pod of that application and run a commds which will run the conciliation 

 So i have written a ansible playbook and to keep it simple i have installed kubernetes python library on the target machine using which i am accessing the kubernetes application  

pip install kubernetes

Once done i have wrote a ansible playbook the config are loaded from ~/.kube/config file on that server and below is the sample playbook. here am executing a sample play which is printing the nginx pod host name but it can be replace with the actual command we want to run

- name: Execute command inside a Kubernetes pod selected by label
hosts: all
gather_facts: no
collections:
- kubernetes.core
vars:
namespace: "default" ## add namespace here
label_selector: "app=nginx" # add lable selector here
container_name: "" # optional — leave empty to use default container
exec_command: "/usr/bin/hostname" # command to run inside the container
tasks:
- name: Get pods matching label selector
kubernetes.core.k8s_info:
api_version: v1
kind: Pod
namespace: "{{ namespace }}"
label_selectors:
- "{{ label_selector }}"
register: pod_list

- name: Fail if no pods found
fail:
msg: "No pods found with label {{ label_selector }} in {{ namespace }}"
when: pod_list.resources | length == 0

- name: Select the first pod
set_fact:
target_pod: "{{ pod_list.resources[0].metadata.name }}"

- debug:
msg: "Selected pod: {{ target_pod }}"

- name: Exec command inside pod
kubernetes.core.k8s_exec:
namespace: "{{ namespace }}"
pod: "{{ target_pod }}"
container: "{{ container_name | default(omit) }}"
command: "{{ exec_command }}"
register: exec_output

- debug:
var: exec_output.stdout

Sample output



Wednesday, December 10, 2025

RHEL patching with Insight and Anisble - without writing the code

 Hello Guys,

While working i got a request that client want to patch the rhel servers with a specific CVES not the whole and at last they want to reboot the system as well so i have work on it and come to know its a very straight forward flow where i can build the playbook in a insights and patch it using ansible 

Login into the insights and make sure your system which you are planning to patch is registered with insights and move to security --> Vulnerability --> systems here you will find the list of system which you are planning to patch 



select the system and you will see the list of CVEs you can select the cves and click on plan remediation


 a dialog box will open you can select the existing playbook or you can select new playbook and click next for couple of time and your playbook is ready



now you need to create a project in Ansible of type insights

Once done you have your playbook is downloaded and ready to patch create a template just shown in the picture and you are all set just make sure name of host in your inventory in ansible and name of server in the insight show be the same 

when you will run it you will be able to see the same CVE get getting patch on your rhel machine


and its not only batch but also rebooted the system and its also informing the insight using insights client utility which all patches are applied in the system so insights based on this info remove the CVEs for that system.


and now if we check in the insights the same CVEs are missing for that system 


let me know what needs to be automated

Ansble Data migration from 2.4 to 2.5

 Hello Guys,


Recently while working i got a request to where a customer wanted to migrated the data from AWX to an Ansible AAP container based platform I tried to come up with an approach which is of least risk cant use 

I have use the API which can help in fetching all the required configurations and can be then imported back into the system. Downside is credentials and users can't be migrated as it contains sensitive information which is not expose to API here are the playbook

 ---

- name: export all aap config
hosts: ctrl
gather_facts: true
tasks:
- name: Export all assets
awx.awx.export:
controller_host: <ip address of controller>
controller_username: admin
controller_password: <password of controller>
validate_certs: false
all: True
register: export_output
delegate_to: localhost
run_once: true

- name: all assets from our export
ansible.builtin.debug:
var: export_output
- name: Display export completion message
debug:
msg: "AAP configuration export completed successfully."

- name: Save export to file
ansible.builtin.copy:
content: "{{ export_output.assets }}"
dest: "/home/nrathi/org.json"
delegate_to: ctrl
run_once: true

to import the playbook we need to place the file in the new AAP system with the import playbook and import it 

---
- name: export all aap config
hosts: ctrl
gather_facts: true
tasks:
- name: Display start message
debug:
msg: "Starting AAP configuration Import process."

- name: Export all assets
awx.awx.import:
controller_host: 192.168.64.67:8443
controller_username: admin
controller_password: primod123
validate_certs: false
assets: "{{ lookup('file', 'org.json') | from_json() }}"
delegate_to: localhost

- name: Display export completion message
debug:
msg: "AAP configuration Import completed successfully."


Thursday, June 26, 2025

OpenSource Complaince Management with Ansible

 Hello Guys,

recently i was working on a project for a compliance management and i was looking for a open source tool which can help me with identify the state of my server against the compliance policy. So after a some quick search i come across OpenSCAP which is an open source compliance management tool and solve my problem so i wrote a simple playbook which help me to identify the issue and also help me fix it 

here is the playbook which i write 

---
- name: Check for known CVEs
hosts: all
tasks:
- name: Install OpenSCAP (if not already installed)
ansible.builtin.package:
name: openscap-scanner
state: present

- name: Run OpenSCAP scan
ansible.builtin.command: oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_cis /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
register: cve_scan

- name: Save CVE report to file
copy:
content: "{{ inventory_hostname }},{{ cve_scan.stdout }}"
dest: /var/ansible/cve_results.csv

delegate_to: localhost 

let me know your thought on this

 

Saturday, April 5, 2025

Get Notification on Failed hosts in Ansible Play

 Hello Guys,

I was working on a writing a simple playbook of making sure that the nginx service should be up and running. while writing i realise that just making sure that service is up and running is not enough so I have added one more module which make sure firewall port 80 is opened permanently I have added the same. I have also added handlers to reload the firewall to make sure changes are permanent. 

  Then I have realise I need to  also make sure that if the Linux host is unreachable then also i should get an alert stating server is unreachable 

i know its a limited use case but i am using it with EDA (event driven ansible) .

Below is the playbook i have came up with

---
- name: Restarting the Nginx if port 80 is down
hosts: all
gather_facts: false
force_handlers: true
ignore_unreachable: true
tasks:
- name: Ping the host
ansible.builtin.ping:
register: ping_result

- name: Ping is not successful
ansible.builtin.debug:
msg: "{{inventory_hostname}} is not from Ansible Controller...!"
when: ping_result.unreachable is defined

- name: Add unreachable hosts to a list
ansible.builtin.set_fact:
unreachable_hosts: "{{ unreachable_hosts | default([]) + [inventory_hostname] }}"
when: ping_result.unreachable is defined

- name: Firewalld |Open port 80 using firewalld
ansible.posix.firewalld:
port: 80/tcp
permanent: yes
state: enabled
notify: Reload firewalld to apply changes
when: ping_result.unreachable is not defined

- name: Make sure service is up and running | Nginx service
ansible.builtin.service:
name: nginx
state: started
become: true
register: nginx_restart
when: ping_result.unreachable is not defined

- name: Genrate Email content to Send in Email | Server is unreachable
ansible.builtin.template:
src: email_alert.html.j2
dest: /tmp/alert_email.html
run_once: true
delegate_to: 127.0.0.1
when: ping_result.unreachable is defined

- name: Email Alert if fail server is unreachable
when: ping_result.unreachable is defined
mail:
host: smtp.gmail.com
port: 587
subtype: html
to:
- "vijay9867206455@gmail.com"
subject: "Alert: Host not reachable on SSH {{ inventory_hostname }}"
body: "{{ lookup('file', '/tmp/alert_email.html') }}"
username: "abc@gmail.com"
password: "your_secure_password"
run_once: true
delegate_to: 127.0.0.1
changed_when: True
handlers:
- name: Reload firewalld | To apply changes
ansible.builtin.service:
name: firewalld
state: reloaded


below is the html template i am using

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title> Host Down</title>
<style>
table {
width: 100%;
border-collapse: collapse;
font-family: Arial, sans-serif;
background-color: #FF0000;
margin: 0 auto;
}
th, td {
padding: 12px;
border: 1px solid #ddd;
text-align: left;
}

th {
background-color: #17469E;
color: white;
text-transform: uppercase;
font-size: 14px;
}

td {
background-color: #f9f9f9;
font-size: 14px;
}

td.label {
font-weight: bold;
background-color: #e0e0e0;
}

.title {
text-align: center;
font-size: 18px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}

.container {
width: 80%;
margin: 0 auto;
}
</style>
</head>

<body>

<p>Dear Team,</p>

<p>This is an automated alert to inform you:</p>
<p>Host isnot reachable from ansible on required ssh or WinRM </p>

<table>
<tr>
<th>Host</th>
</tr>
<tr>
<td>{{ inventory_hostname }}</td>
</tr>
</table>
<p>Best regards,<br/>abc@gmail.com</p>

</body>

</html>


#ansible-playbook -i inventory restart_nginx.yml 


Tuesday, February 25, 2025

Lock Linux users if do not login for 30 days

 Hello Guys,

Few days back a kind of strange requirement come to me where as an they wanted to lock the localuser if he/she do not login into the system for more than 30 days 

  1. He/She should not be able to login into the system
  2. SSH into the system
  3. His/Her account should be lock
---
- name: Lock users who have not logged in the last 30 days (excluding system users)
hosts: linux_servers
become: yes
tasks:

- name: Get list of users who have not logged in within 30 days
ansible.builtin.shell: "lastlog -b 30 | awk 'NR>1 && $3!=\"Never\" {print $1}'"
register: inactive_users
changed_when: false

- name: Get list of system users (UID < 1000)
ansible.builtin.shell: "awk -F: '$3 < 1000 {print $1}' /etc/passwd"
register: system_users
changed_when: false

- name: Display inactive users
ansible.builtin.debug:
var: inactive_users.stdout_lines

- name: Display system users (excluded)
ansible.builtin.debug:
var: system_users.stdout_lines

- name: Lock inactive users (excluding system users)
ansible.builtin.command: "usermod --lock {{ item }}"
loop: "{{ inactive_users.stdout_lines }}"
when: item not in system_users.stdout_lines and item not in ["root", "nrathi", "nobody", "other_imp_user"]


Enjoy...guys

Tuesday, February 18, 2025

Enable/Disable USB Support on Windows machines using ansible

 Hello Guys,

Couple of months past i was working on a project where i need to write a ansible playbook which can enable or disable the USB storage capability. I mean windows should not detect the USB devices if i connect to a computer and enforce it so i did a google search a found out the registry key for it.Then i started converting it in a playbook which look like this

---
- name: Disable_Enable USB ports on Windows Operating system
hosts: all
gather_facts: true
tasks:
- name: Check if server are reachable or not
ansible.windows.win_ping:
register: ping_result

# - debug:
# msg: "{{ ping_result }}"

- name: Disable USB storage devices
win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Services\USBSTOR
name: Start
data: 4
type: dword
state: present
register: usb_dis
when:
- usb_disable|default(true)|bool == true

- name: Enable USB storage devices
register: usb_en
win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Services\USBSTOR
name: Start
data: 3
type: dword
state: present
when:
- usb_disable|default(true)|bool == false

- name: Reboot system after whitelisting USB device (if required)
win_reboot:
reboot_timeout: 120
ignore_errors : true
when: usb_en.changed or usb_dis.changed

 By default it disable the usb on the windows computer

To Disable the USB

ansible-playbook -i inventory usb.yml

To Enable USB

ansible-playbook -i inventory usb.yml -e usb_disable=false

Tuesday, February 11, 2025

Ansible Lock user after 3 unsuccessful login attempt

 Hello Guys,

How to lock a user after 3 unsuccessful login attempt and after the cooldown time of 10 min the account get reactivated . we its a well establish windows command as well but when you have to do it on the large scale or you need to enforce it so that it never get overwritten we need automation for that and i know wrote a playbook for that which will make sure that.

- name: Set user lockout after 3 attempt
win_command: net accounts /lockoutthreshold:3
register: userLockout
args:
creates: C:\userLockout.lock

- name: Create userLockout.lock
win_copy:
dest: C:\userLockout.lock
content: ""
force: no
when: userLockout

- name: Set lockout duration to 10 min
win_command: net accounts /lockoutduration:10
register: lockduration
args:
creates: C:\lockduration.lock

- name: Create lockduration.lock
win_copy:
dest: C:\lockduration.lock
content: ""
force: no
when: lockduration

- name: Set reset the lockout timeout after 10 min
win_command: net accounts /lockoutwindow:10
register: lockoutwindow
args:
creates: C:\lockoutwindow.lock

- name: Create lockoutwindow.lock
win_copy:
dest: C:\lockoutwindow.lock
content: ""
force: no
when: lockoutwindow

Time Sync Windows machine using Ansible

 Hello Guys,

I know you have been waiting for a automation which can help to sync the time of windows server/Desktop to local NTP server using ansible

    In the previous blog i have shared a playbook how you can use it to setup a NTP server on rhel or centos box in this will be using a playbook to connect with windows client to sync them with local ntp server.

so here is the playbook 


---
- name: Configure NTP server on Windows and synchronize time
hosts: all
#become: yes
force_handlers: True
gather_facts: false
tasks:

# - name: Install NTP service
# win_feature:
# name: NTP
# state: present

##This step is not necessary but added for asthetics so ip is not shown but fqdn looks more appling
- name: Configure NTP server on windows host
ansible.builtin.copy:
dest: C:\Windows\System32\drivers\etc\hosts
content: |
{{ ntp_server }} rhel.ntpserver.local
# notify:
# - restart ntpd

- name: Synchronize time with NTP server
ansible.windows.win_powershell:
script: |
w32tm /config /manualpeerlist:"rhel.ntpserver.local" /syncfromflags:manual /reliable:YES
w32tm /resync
notify:
- restart w32time
ignore_errors: true

handlers:
# - name: restart ntpd
# win_service:
# name: ntpd
# state: restarted

- name: restart w32time
win_service:
name: w32time
state: restarted


to run the ansible playbook 


ansible-playbook -i inventory_file ntp_client.yml -e ntp_server = "ip address of ntpserver"


Enjoy and let me know what automation you want to work on...

Tuesday, November 19, 2024

Setup A NTP Server to sync the windows machines locally

 Hello Guys,

I have working on a problem where i need to sync the windows machines in isolated network.So I have suggested that we need to have a local NTP server and keep syncing to it periodically. I have wrote a ansible playbook to setup NTP/chrony  server but it can be achive manually as well.

For syncing the windows machines as well we can do it locally but i have sestup a playbook which login on windows machine and syncup the time using the timeserver which we have setup.

---
- name: Set up NTP server on RHEL 9 using Chrony
hosts: all
become: yes
tasks:
- name: check if chrony is installed
shell: rpm -qa | grep chrony
register: chrony_installed
ignore_errors: True
check_mode: False
changed_when: False

- name: print
debug:
msg: "chrony is installed"
when: chrony_installed.rc == 0
- name: Install chrony package
yum:
name: chrony
state: present
when: chrony_installed.rc != 0

- name: Configure chrony as an NTP server
copy:
dest: /etc/chrony.conf
content: |
# Use the default CentOS pool servers
pool 2.centos.pool.ntp.org iburst

# Allow NTP client access from the local network
allow 192.168.1.0/24

#Allow NTP client to access from local network hostonly
allow 192.168.56.0/24

# Serve time even if not synchronized to any NTP server
local stratum 10

# Specify log file
logdir /var/log/chrony

# Dump measurements when chronyd exits
dumpdir /var/lib/chrony

# Save drift file
driftfile /var/lib/chrony/drift

notify:
- restart chronyd

- name: Enable and start chronyd service
systemd:
name: chronyd
enabled: yes
state: started

- name: Ensure firewalld is running
ansible.builtin.service:
name: firewalld
state: started
enabled: yes

- name: Open UDP port 123 for NTP (Chrony) on the server
ansible.posix.firewalld:
port: "{{ item }}/udp"
permanent: true
state: enabled
immediate: true
loop:
- 123
- 323
notify:
- Reload firewalld
handlers:
- name: restart chronyd
systemd:
name: chronyd
state: restarted

- name: Reload firewalld
ansible.builtin.service:
name: firewalld
state: reloaded


For syncing the we can go to time and date setting and  enter the IP address of the NTP server in the internet time section and click sync now. Alternatively we can also write a playbook if we want to do it in bulk which i will cover in the next article. Cheers and enjoy...!