Sunday, July 12, 2026

Rubrik Backup Service (RBS)


Rubrik Backup Service (RBS) is the core service responsible for performing and managing backup and recovery operations on a Rubrik node. It coordinates communication between the Rubrik cluster and the protected workloads (VMware, Hyper-V, databases, file systems, etc.).

For Linux
---
- name: (Red Hat) Download the Rubrik Connector
get_url:
url: "https://{{ rubrik_cluster_ip }}/connector/rubrik-agent.x86_64.rpm"
dest: /tmp/rubrik-agent.x86_64.rpm
validate_certs: no
force: no
- name: (Red Hat) Install the Connector
yum:
name: /tmp/rubrik-agent.x86_64.rpm
state: present


- name: (Red Hat) Start and Enable the Rubrik Services (RHEL 7+)
systemd:
name: rubrikagents
state: started
enabled: yes
when: ansible_distribution_major_version|int > 6


For Windows
---
- name: (Windows) Create a Temporary Download Location
win_file:
path: C:\Temp
state: directory

- name: (Windows) Download the Rubrik Connector
win_get_url:
url: "https://{{ rubrik_cluster_ip }}/connector/RubrikBackupService.zip"
dest: C:\Temp\RubrikBackupService.zip
validate_certs: no
force: no

- name: (Windows) Unzip the Connector Archive
win_unzip:
src: C:\Temp\RubrikBackupService.zip
dest: C:\Temp\

- name: (Windows) Install the Rubrik Connector
win_package:
path: C:\Temp\RubrikBackupService.msi
state: present
creates_service: 'Rubrik Backup Service'
wait: yes

- name: (Windows) Set Logon for the Rubrik Connector Service
win_service:
username: "{{ ansible_user }}"
password: "{{ ansible_password }}"
name: 'Rubrik Backup Service'

Powershell
Get-Service -Name "Rubrik Backup Service"
Start-Service -Name "Rubrik Backup Service"
Stop-Service -Name "Rubrik Backup Service"

Redhat Servers Under AD



packages
# dnf install sssd realmd oddjob oddjob-mkhomedir adcli krb5-workstation samba-common-tools samba-common authselect-compact openldap-clients policycoreutils-python

# vi /etc/resolv.conf
search <ad.local>

$ nslookup -type=SRV _ldap._tcp.<ad.local>



Firewall

Service Port Protocol Notes
DNS 53 UDP and TCP
LDAP 389 UDP and TCP
LDAPS 636 TCP Optional
Samba 445 UDP and TCP For AD Group Policy and Objects (GPOs)
Kerberos 88 UDP and TCP
Kerberos 464 UDP and TCP Used by kadmin for setting and changing a password
LDAP Global Catalog 3268 TCP If the id_provider = ad option is being used
LDAPS Global Catalog 3269 TCP Optional
NTP 123 UDP Optional
NTP 323 UDP optional



To ensure that the server can correctly communicate with Active Directory
# update-crypto-policies --set DEFAULT:AD-SUPPORT
# realm list
# realm discover <ad.local>
# realm join <ad.local> -U Administrator # AD admin account
# getent passwd administrator@<ad.local>
Configure SSSD and Home Directory Creation
# authselect select sssd with-mkhomedir --force


cat /etc/sssd/sssd.conf
[sssd]
domains = <ad.local>
config_file_version = 2
services = nss, pam
default_domain_suffix = <ad.local>

[domain/<ad.local>]
ad_domain = <ad.local>
krb5_realm = <AD.LOCAL>
realmd_tags = manages-system joined-with-samba
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True/False
use_fully_qualified_names = True #false means users can log in with their username itself (without the @<ad.local> suffix)
fallback_homedir = /home/%u@%d
access_provider = ad


# systemctl restart sssd
# systemctl restart nscd
# systemctl enable --now oddjobd # for homedir creation
# id <ad.local>

Control Access
Limit to Specific users/Groups
# realm permit user1@example.com
# realm permit user2@example.com user3@example.com

Allow AD group
sudo realm permit -g <group_name>
sudo realm permit -g '<group_name_1>' '<group_name_2>'


Allow All
# realm permit --all
Deny all
# realm deny--all


Sudo Access for AD Groups

# visudo -f /etc/sudoers.d/domain_admins
user1@example.com ALL=(ALL) ALL # Single user
%sysadmins@example.com ALL=(ALL) ALL # AD group (prefix with %)
%domain\ admins@example.com ALL=(ALL) ALL # Group with spaces in the name (escape spaces with backslash)

# visudo -cf /etc/sudoers.d/domain_admins # verify sudo




Leave AD
# realm leave example.com
Noraml Troubleshtting
# systemctl stop sssd
# rm -rf /var/lib/sss/db/*
# systemctl start sssd

ansible.cfg


The ansible.cfg file is the main configuration file that controls how Ansible behaves globally or per project.

Where Ansible Looks for ansible.cfg (VERY IMPORTANT)

Order of precedence:

ANSIBLE_CONFIG (environment variable)
./ansible.cfg (current project directory) ✅
~/.ansible.cfg (user home)
/etc/ansible/ansible.cfg (system-wide)

💡 First one found → used

Ansible Vault

 Ansibel Vault

Ansible Vault performs various operations. Specifically, it can
Encrypt/Decrypt a file
View an encrypted file without breaking the encryption
Edit an encrypted file
Create an encrypted file
Generate or reset the encrypted key

Ansible Vault uses AES256 encryption

The ansible-vault create command is used to create the encrypted file.
# ansible-vault create test_vault # it will prompt for a password
New Vault password:
Confirm New Vault password:

# cat test_vault
$ANSIBLE_VAULT;1.1;AES256
34363365356262323333626363616366383161393739663331373231386563306632323163336231
6537393461353932353035373561636461633738396662640a316165346666303439303030623032
62653534643866343465313134373862343839646434353130393764366632393237656265303531
3062613639663865310a383137316133653435643236336635626661323736646336323434643164
6162
Ansibel Vault id

# ansible-vault create --vault-id password@prompt multi_vault.yml
New vault password (password):
Confirm new vault password (password):

Edit File
# ansible-vault edit multi_vault.yml

Decrypting File
# ansible-vault edit multi_vault.yml
once decrypt the file can be opened using cat

While running playbook
# ansible-playbook --ask-vault-pass multi_vault.yml

Change/reset password for vault
# ansible-vault rekey multi_vault.yml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful


Multi Vault
Ansible Vault allows operators to work with multiple vaults, each uniquely identified by a vault ID.
Vault IDs provide a “hint” to indicate the correct password to use when decrypting a vault file.

# Encrypt staging config with "mte & prod" vault ID
# ansible-vault encrypt --vault-id mte@prompt config/sec_mte.yml
# ansible-vault encrypt --vault-id prod@prompt config/sec_prod.yml
# ansible-playbook site.yml -i inventory.ini --vault-id staging@prompt --vault-id prod@vault_prod_pass.txt

Configuring Vault IDs in ansible.cfg
# ansible.cfg
[defaults]
# Comma-separated list of vault identity sources
vault_identity_list = dev@~/.vault_pass_dev, staging@~/.vault_pass_staging, prod@~/.vault_pass_prod

Ansible Variables_1






Ansible_Facts

Ansible implements fact collecting through the a module called the setup module.
It collects detailed information (called facts) from managed nodes.
It collects detailed information (called facts) from managed nodes.
By default, Ansible automatically runs setup at the start of every play.


$ ansible ubuntu -m setup


- name: Gather facts manually
hosts: all
tasks:
- name: Run setup module
ansible.builtin.setup:
- debug:
msg: "Host {{ ansible_hostname }} has {{ ansible_memtotal_mb }} MB RAM"


Filtering Facts

Collect only specific facts
- name: Get only network-related facts
ansible.builtin.setup:
filter: ansible_default_ipv4

- name: Get only facts that start with 'ansible_processor'
ansible.builtin.setup:
filter: 'ansible_processor*'
- name: Get only facts that start with 'ansible_processor' and 'ansible_mem'
ansible.builtin.setup:
filter: 'ansible_processor*', 'ansible_mem*'

$ ansible all -m setup -a 'filter=ansible_all_ipv6_addresses'

Gather_Subset
Control what facts to collect
- name: Gather only minimal facts
ansible.builtin.setup:
gather_subset:
- min

Other options:
all (default)
hardware
network
virtual
ohai
facter


gather_subset: ! 'all,!hardware' # Gather all facts except hardware facts
gather_subset: ! 'all,!network' # Gather all facts except network facts
gather_subset: ! 'all,!virtual' # Gather all facts except virtual facts
gather_subset: ! 'all,!ohai' # Gather all facts except ohai facts
gather_subset: ! 'all,!facter' # Gather all facts except facter facts

Set timeout for fact gathering
- ansible.builtin.setup:
gather_timeout: 10

set_fact → create custom facts
Set_fact is a powerful module that allows you to create custom facts during playbook execution.

- name: Set a variable
set_fact:
my_var: "hello"

- name: Set multiple variables
set_fact:
env: "prod"
version: "1.2.3"

Append to a list variable
- name: Append to a list variable
set_fact:
my_list: "{{ my_list | default([]) + ['new_item'] }}"

Update a dictionary variable
- name: Update a dictionary variable
set_fact:
my_dict: "{{ my_dict | default({}) | combine({'key': 'value'}) }}"

Loop with set_fact
- name: Create a list of hostnames
set_fact:
hostnames: "{{ hostnames | default([]) + [item] }}"
loop: "{{ ansible_play_hosts }}"

- name: Build list dynamically
set_fact:
servers: "{{ servers | default([]) + [item] }}"
loop:
- web1
- web2


hostvars → access facts of other hosts
Hostvars is a powerful Ansible variable that allows you to access the facts and variables of other hosts in your inventory.
This can be particularly useful when you need to reference information about other hosts during playbook execution.

HOSTVARS VERSUS HOST_VARS
Please be warned that hostvars is computed when you run Ansible, while host_vars is a directory that you can use to define variables for a particular system.

What is hostvars?
👉 It is a dictionary of all hosts and their variables.

hostvars['hostname']['variable_name']


- name: Access hostvars
hosts: all
tasks:
- name: Show IP address of another host
debug:
msg: "The IP address of {{ item }} is {{ hostvars[item]['ansible_default_ipv4']['address'] }}"
loop: "{{ ansible_play_hosts }}"

Local facts
Local facts are custom facts that you can create on the managed nodes themselves.
They are stored in the /etc/ansible/facts.d/ directory on the managed nodes.
Local facts are useful for storing information that is specific to a particular host and may not be easily gathered through the setup module.
You can place one or more files on the remote host machine in the
/etc/ansible/facts.d directory. These files can be in JSON or INI format and must have a .json or .ini extension. When Ansible runs the setup module, it will automatically read these files and include the custom facts in the gathered facts for that host.

These facts are available as keys of a special variable named ansible_local.

To create a local fact, you can create a JSON or INI file in the /etc/ansible/facts.d/ directory on the managed node. For example, you could create a file called /etc/ansible/facts.d/custom_facts.json with the following content:

{
"custom_fact": "This is a custom fact"
}
Once you have created the local fact file, you can access the custom fact in your playbooks using the ansible_local variable. For example:
- name: Access local fact
hosts: all
tasks:
- name: Show custom fact
debug:
msg: "The custom fact is: {{ ansible_local.custom_facts.custom_fact }}"
Dynamic Inventory Script
An Ansible dynamic inventory script must support two command-line flags:
--host=<hostname> for showing host details
--list for listing groups


Magic Variables
Ansible provides several magic variables that are automatically available in your playbooks. These variables provide information about the playbook execution context, such as the current host, group, and task. Some commonly used magic variables include:

hostvars A dict whose keys are Ansible hostnames and values are dicts that map variable names to values for that host. This variable is useful for accessing variables of other hosts in the inventory.

inventory_host name The name of the current host as known in the Ansible inventory, might include domain name
inventory_hostname_short Name of the current host as known by Ansible, without the domain name(e.g., myhost)
group_names A list of all groups that the current host is a member of

- ansible_play_hosts: A list of all hosts in the current play
- ansible_play_batch: A list of hosts in the current batch (when using serial)
- ansible_play_name: The name of the current play
- ansible_play_role_names: A list of roles applied to the current play
- ansible_play_task_name: The name of the current task
- ansible_play_hosts_all: A list of all hosts in the inventory
- ansible_play_hosts_all_groups: A list of all groups in the inventory
- ansible_play_hosts_all_hosts: A list of all hosts in the inventory
- ansible_play_hosts_all_groups_hosts: A dictionary of all groups and their hosts in the inventory
- ansible_play_hosts_all_groups_hosts_vars: A dictionary of all groups, their hosts, and their variables in the inventory
- ansible_play_hosts_all_groups_hosts_vars_hostvars: A dictionary of all groups, their hosts, their variables, and the hostvars for each host in the inventory



Extra variable with the command-line option -e var=value
$ ansible-playbook playbook.yml -e "my_var=value"
$ ansible-playbook playbook.yml -e "my_var=value" -e "my_list=['item1', 'item2']"
$ ansible-playbook playbook.yml -e "my_dict={'key1': 'value1', 'key2': 'value2'}"

plug-ins


To see the list of available plug-ins
$ ansible-doc -t inventory -l

To see plug-in-specific documentation and examples
$ ansible-doc -t inventory <plugin name>

Ansible_9 Automation Execution Environment (EE)_latest

 What are execution environment,


All jobs with AAP are executed within containers, also known as Execution Environments, as a way to isolate jobs from the host system.
They contains the Ansble tools, collections, and roles and software librariers needed for your automation content. This is to reduce complexity and ensure that jobs run consistently across different systems.

Execution environments provide a standardized environment for running Ansible playbooks, making it easier to manage dependencies and avoid conflicts with the host system's configuration.


To create a custom execution environment, you can use Ansible Builder.
Ansible Builder allows you to define the necessary dependencies, collections, and roles required for your automation tasks. It helps you create a reproducible and portable execution environment that can be shared across different systems and teams.

Ansible Builder
Ansible Builder is a tool that allows you to create custom execution environments for Ansible Automation Platform (AAP). It helps you define the necessary dependencies, collections, and roles required for your automation tasks. By using Ansible Builder, you can create a reproducible and portable execution environment that can be shared across different systems and teams.

# ansible-builder --version
Creating custom execution environments
# mkdir -p my_execution_env; cd my_execution_env ; mkdir files; cd files ; touch ansible.cfg

The ansible.cfg file will contain information what AutomationHub Servers, we woule like to download collections from. You can also specify other configuration options as needed.


cat ansible.cfg
[galaxy]
server_list = automation_hub, ansible-galaxy
[galaxy_server.automation_hub]
url=https://automationhub.example.com/api/galaxy/v3/
token=<your_token_here>
validate_certs=False

[galaxy_server.ansible-galaxy]
url=https://galaxy.ansible.com/api/
token=<your_token_here>
validate_certs=False

# tocuch execution-environment.yml # also know as build definition file
The execution-environment.yml file will define the base image and build steps, any additional dependencies, collections, or roles that you want to include in your custom execution environment. This file is used by Ansible Builder to build the execution environment. # Essentially, everyting we need for creating the execution environment.

vi execution-environment.yml
---
version: 3
build_arg_defaults:
EE_BASE_IMAGE: "quay.io/ansible/ansible-runner:latest"
ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: "--ignore-certs"
dependencies:
galaxy: requirements.yml
galaxy:
collections:
- name: ansible.posix
version: "1.5.0"
- name: community.general
version: "6.4.0"
python: requirements.txt
python:
- boto3
- botocore
- boto
- boto3-stubs
system: bind-utils, git, openssh-clients
images:
base_image: "quay.io/ansible/ansible-runner:latest"

additional_build_steps:
prepend:
- RUN echo "Custom build step: Installing additional packages"
- RUN yum install -y jq

optional:
labels:
com.example.description: "Custom Execution Environment for Ansible Automation Platform"
com.example.version: "1.0.0"
options:
build_arg_defaults:
EE_BASE_IMAGE: "quay.io/ansible/ansible-runner:latest"
ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: "--ignore-certs"

# podman login quay.io
# podman login automationhub.example.com


Building the execution environment
Once you have defined your execution-environment.yml and ansible.cfg files, you can build the custom execution environment using the ansible-builder command. This will create a container image that includes all the necessary dependencies, collections, and roles specified in your configuration files.
# ansible-builder create -v 3 # this step is optional, it will create a new execution environment based on the execution-environment.yml file and the ansible.cfg file. It will also create a requirements.yml file that lists all the collections and roles that are included in the execution environment.

# tree context

# ansible-builder build -f execution-environment.yml -t my_custom_execution_env:latest -v 3 --no-cache
# podman image ls


# podman login quay.io --tls-verify=false


Sunday, April 26, 2026

Ansible_Facts

 Facts


Ansible implements fact collecting through the a module called the setup module.
It collects detailed information (called facts) from managed nodes.
It collects detailed information (called facts) from managed nodes.
By default, Ansible automatically runs setup at the start of every play.


$ ansible ubuntu -m setup


- name: Gather facts manually
hosts: all
tasks:
- name: Run setup module
ansible.builtin.setup:
- debug:
msg: "Host {{ ansible_hostname }} has {{ ansible_memtotal_mb }} MB RAM"


Filtering Facts

Collect only specific facts
- name: Get only network-related facts
ansible.builtin.setup:
filter: ansible_default_ipv4

- name: Get only facts that start with 'ansible_processor'
ansible.builtin.setup:
filter: 'ansible_processor*'
- name: Get only facts that start with 'ansible_processor' and 'ansible_mem'
ansible.builtin.setup:
filter: 'ansible_processor*', 'ansible_mem*'

$ ansible all -m setup -a 'filter=ansible_all_ipv6_addresses'

Gather_Subset
Control what facts to collect
- name: Gather only minimal facts
ansible.builtin.setup:
gather_subset:
- min

Other options:
all (default)
hardware
network
virtual
ohai
facter


gather_subset: ! 'all,!hardware' # Gather all facts except hardware facts
gather_subset: ! 'all,!network' # Gather all facts except network facts
gather_subset: ! 'all,!virtual' # Gather all facts except virtual facts
gather_subset: ! 'all,!ohai' # Gather all facts except ohai facts
gather_subset: ! 'all,!facter' # Gather all facts except facter facts

Set timeout for fact gathering
- ansible.builtin.setup:
gather_timeout: 10

set_fact → create custom facts
Set_fact is a powerful module that allows you to create custom facts during playbook execution.

- name: Set a variable
set_fact:
my_var: "hello"

- name: Set multiple variables
set_fact:
env: "prod"
version: "1.2.3"

Append to a list variable
- name: Append to a list variable
set_fact:
my_list: "{{ my_list | default([]) + ['new_item'] }}"

Update a dictionary variable
- name: Update a dictionary variable
set_fact:
my_dict: "{{ my_dict | default({}) | combine({'key': 'value'}) }}"

Loop with set_fact
- name: Create a list of hostnames
set_fact:
hostnames: "{{ hostnames | default([]) + [item] }}"
loop: "{{ ansible_play_hosts }}"

- name: Build list dynamically
set_fact:
servers: "{{ servers | default([]) + [item] }}"
loop:
- web1
- web2


hostvars → access facts of other hosts
Hostvars is a powerful Ansible variable that allows you to access the facts and variables of other hosts in your inventory.
This can be particularly useful when you need to reference information about other hosts during playbook execution.

HOSTVARS VERSUS HOST_VARS
Please be warned that hostvars is computed when you run Ansible, while host_vars is a directory that you can use to define variables for a particular system.

What is hostvars?
👉 It is a dictionary of all hosts and their variables.

hostvars['hostname']['variable_name']


- name: Access hostvars
hosts: all
tasks:
- name: Show IP address of another host
debug:
msg: "The IP address of {{ item }} is {{ hostvars[item]['ansible_default_ipv4']['address'] }}"
loop: "{{ ansible_play_hosts }}"

Local facts
Local facts are custom facts that you can create on the managed nodes themselves.
They are stored in the /etc/ansible/facts.d/ directory on the managed nodes.
Local facts are useful for storing information that is specific to a particular host and may not be easily gathered through the setup module.
You can place one or more files on the remote host machine in the
/etc/ansible/facts.d directory. These files can be in JSON or INI format and must have a .json or .ini extension. When Ansible runs the setup module, it will automatically read these files and include the custom facts in the gathered facts for that host.

These facts are available as keys of a special variable named ansible_local.

To create a local fact, you can create a JSON or INI file in the /etc/ansible/facts.d/ directory on the managed node. For example, you could create a file called /etc/ansible/facts.d/custom_facts.json with the following content:

{
"custom_fact": "This is a custom fact"
}
Once you have created the local fact file, you can access the custom fact in your playbooks using the ansible_local variable. For example:
- name: Access local fact
hosts: all
tasks:
- name: Show custom fact
debug:
msg: "The custom fact is: {{ ansible_local.custom_facts.custom_fact }}"
Dynamic Inventory Script
An Ansible dynamic inventory script must support two command-line flags:
--host=<hostname> for showing host details
--list for listing groups


Magic Variables
Ansible provides several magic variables that are automatically available in your playbooks. These variables provide information about the playbook execution context, such as the current host, group, and task. Some commonly used magic variables include:

hostvars A dict whose keys are Ansible hostnames and values are dicts that map variable names to values for that host. This variable is useful for accessing variables of other hosts in the inventory.

inventory_host name The name of the current host as known in the Ansible inventory, might include domain name
inventory_hostname_short Name of the current host as known by Ansible, without the domain name(e.g., myhost)
group_names A list of all groups that the current host is a member of

- ansible_play_hosts: A list of all hosts in the current play
- ansible_play_batch: A list of hosts in the current batch (when using serial)
- ansible_play_name: The name of the current play
- ansible_play_role_names: A list of roles applied to the current play
- ansible_play_task_name: The name of the current task
- ansible_play_hosts_all: A list of all hosts in the inventory
- ansible_play_hosts_all_groups: A list of all groups in the inventory
- ansible_play_hosts_all_hosts: A list of all hosts in the inventory
- ansible_play_hosts_all_groups_hosts: A dictionary of all groups and their hosts in the inventory
- ansible_play_hosts_all_groups_hosts_vars: A dictionary of all groups, their hosts, and their variables in the inventory
- ansible_play_hosts_all_groups_hosts_vars_hostvars: A dictionary of all groups, their hosts, their variables, and the hostvars for each host in the inventory



Extra variable with the command-line option -e var=value
$ ansible-playbook playbook.yml -e "my_var=value"
$ ansible-playbook playbook.yml -e "my_var=value" -e "my_list=['item1', 'item2']"
$ ansible-playbook playbook.yml -e "my_dict={'key1': 'value1', 'key2': 'value2'}"


Ansible Variables

 Variables


Variables can be used in tasks, as well as in template files.
You reference variables by using {{ variable }}. Ansible replaces this {{ variable }} with the value of the variable value

eg
vars:
conf_file: /etc/nginx/sites/default
Ansible will substitute "{{ conf_file }}" with /etc/nginx/sites/default when it executes this task.


Ansible uses the Jinja2 template engine to implement templating
We use the .j2 extension to indicate that the file is a Jinja2 template. However, we can use a any extension if you like.
Ansible also uses the Jinja2 template engine to evaluate variables in playbooks.


Loop
When you want to run a task with each item from a list, you can use loop.
A loop executes the task multiple times, each time replacing item with different values from the specified list.

Handlers
Handlers are one of the conditional forms, A handler is similar to a task, but it runs only if it has been notified by a task. A task will run the notification if Ansible recognizes that the task was changed.

handlers:
- name: Restart nginx
service:
name: nginx
state: restarted

- name: Manage nginx
template:
src:
dest:
notify: Restart nginx

Handlers usually run at the end of the play after all of the tasks have been run.

To force a notified handler in the middle of a play, we need to use flush_handlers
- name: Restart nginx
meta: flush_handlers

If a play contains multiple handlers, the handlers always run in the order that they are defined in the handlers section, not the notification order.
They run only once, even if they are notified multiple times.



Variables in Separate Files
vars_files:
- nginx.yml

viewing the value of variables
To view the values of variables, you can use the debug module. The debug module allows you to print the value of a variable to the console during playbook execution.

- name: Print the value of a variable
debug:
var: variable_name

- debug: var=myvarname

Variable Interpolation
- name: Display the variable
debug:
msg: "The file used was {{ conf_file }}"

Variables can be concatenated between the double braces by using the tilde operator ~, as shown here:
- name: Concatenate variables
debug:
msg: "The URL is https://{{ server_name ~'.'~ domain_name }}/"

Registering Variables
The register keyword allows you to capture the output of a task and store it in a variable for later use.
- name: Capture output of whoami command
command: whoami
register: login

Example of using register to capture the output of a command and then display it using the debug module:
---
- name: Show return value of command module
hosts: fedora
gather_facts: false
tasks:
- name: Capture output of id command
command: id -un
register: login
- debug: var=login
- debug: msg="Logged in as user {{ login.stdout }}"
...

Output of the above playbook:
TASK [Capture output of id command] ******************************************************************************************
changed: [localhost]

TASK [debug] ****************************************************************************************************************
ok: [localhost] => {
"login": {
"changed": true,
"cmd": ["id", "-un"],
"delta": "0:00:00.003123",
"end": "2024-06-01 12:00:00.000000",
"rc": 0,
"start": "2024-06-01 12:00:00.000000",
"stderr": "",
"stdout": "user"
}
}
TASK [debug] ****************************************************************************************************************
ok: [localhost] => {
"msg": "Logged in as user user"
}

The changed key is present in the return value of all Ansible modules, and Ansible uses it to determine whether a state change has occurred. For the command and shell modules, this will always be set to true unless overridden with the changed_when clause
- name: Capture output of whoami command
command: whoami
register: login
changed_when: false

The cmd key contains the invoked command as a list of strings.
The rc key contains the return code. If it is nonzero, Ansible willassume the task failed to execute successfully.
The stderr key contains any text written to standard error, as a single string.
The stdout key contains any text written to standard out, as a single string.
The stdout_lines key contains any text written to split by newlines, as a list of strings.

ACCESSING DICTIONARY KEYS IN A VARIABLE
If a variable contains a dictionary, you can access the keys of the dictionary by using either a dot (.) or a subscript ([])
{{ result.stat }}
{{ result['stat'] }}
result['stat']['mode']
result['stat'].mode
result.stat['mode']
result.stat.mode

- name: Display result.stat detail
debug: var=result['stat'][stat_key]

- name: Access dictionary keys using dot notation
debug:
msg: "The command was {{ login.cmd }} and the return code was {{ login.rc }}"
- name: Access dictionary keys using subscript notation
debug:
msg: "The command was {{ login['cmd'] }} and the return code was {{ login['rc'] }}"


Ansible_inventory Parameters

 Inventory Parameters

inventory is called as collection of hosts
inventory parameters are variables or settings you define in your inventory file to control how hosts and groups behave during playbook execution.

ansible_host # Hostname or IP address to SSH to
ansible_port # Port to SSH to
ansible_user # User to SSH as
ansible_password # Password to use for SSH authentication
ansible_ssh_private_key_file # SSH private key to use for SSH authentication
ansible_become=true
ansible_become_user=root
ansible_become_method=sudo(or)su
localhost ansible_connection=local

Custom variable
web1 app_port=8080 env=prod

ansible_connection
Ansible supports multiple transports to connect hosts
The default transport, smart

Ansible will check whether the locally installed SSH client supports a feature called ControlPersist. If the SSH client supports ControlPersist, Ansible will use the local SSH client.
If not, the smart transport will fall back to using a Python-based SSH client library called Paramiko.

ansible_shell_type
Ansible works by making SSH connections to remote machines and then invoking scripts. By default, Ansible assumes that the remote shell is the Bourne shell located at /bin/sh, and will generate the appropriate command-line parameters that work with that. It creates temporary directories to store these scripts.

Ansible also accepts csh, fish, and (on Windows) powershell as valid values for this parameter. Ansible doesn’t work with restricted shells.

ansible_python_interpreter
Ansible needs to know the location of the Python interpreter on the remote machine
ansible_python_interpreter="/usr/bin/env python3"

ansible_*_interpreter
If you are using a custom module that is not written in Python, you can use this parameter to specify the location of the interpreter

eg
[web]
web1 ansible_host=192.168.1.10 ansible_user=ec2-user ansible_port=22

[web]
web1
web2

[web:vars]
ansible_user=ec2-user
ansible_ssh_private_key_file=/home/user/key.pem

eg
web1 app_port=8080 env=prod


Pattern Matching Inventory
$ ansible web -m ping
$ ansible 'web:&prod' -m ping
$ ansible 'web:!db' -m ping

Operators
: → OR
& → AND
! → NOT

$ ansible-inventory --list
$ ansible-inventory --graph

Ansible automatically defines a group called all (or *)
$ ansible all -a "date"
or
$ ansible '*' -a "date"


Bill Baker of Microsoft came up with the distinction between treating servers as pets versus treating them like cattle.
The “cattle” approach to servers is much more scalable
20 servers are named web1.example.com, web2.example.com ... and so on

[web]
web[1:20].example.com

web-a.example.com, web-b.example.com, and so on....
[web]
web-[a:t].example.com



Ansible will let you add hosts and groups to the inventory during the execution of a playbook.
Adding Entries at Runtime with add_host and group_by
This is useful when managing dynamic clusters, such as Redis Sentinel.

add_host
The add_host module adds a host to the inventory; this is useful if you’re using Ansible to provision new virtual machine instances

- name: Add the host
add_host
name: hostname
groups: web,staging
myvar: myval

group_by
Ansible’s group_by module allows you to create new groups while a playbook is executing.
Any group you create will be based on the value of a variable that has been set on each host, which Ansible refers to as a fact.

- name: Create groups based on Linux distribution
group_by:
key: "{{ ansible_facts.distribution }}"