# login as user ubuntu, use python3 and relogin as root
- hosts:
- vm1
- vm2
become: yes
vars:
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_user: ubuntu
tasks:
- include: "{{ inventory_hostname }}.yml"
# show host
- debug:
msg="{{ ansible_user_id }}"
# show host
- debug:
msg="{{ inventory_hostname }}"
# show host groups
- debug:
msg: "{{ group_names }}"
- debug:
var: hostvars[inventory_hostname]
- debug:
msg: "{{ ansible_system_vendor }} / {{ ansible_product_name }}"
- debug:
msg: "ansible_default_ipv4["address"]"
when: ansible_default_ipv4.gateway == "1.2.3..4"
- debug:
msg: "{{ vms | length }}"
- debug:
msg="{{ playbook_dir }} / {{ inventory_dir }} / {{ role_path }}"
- name: Dictonary to list
debug:
msg="{{ my_packages | join(' ') }}"
- name: set default value
debug:
msq: "{{ my_variable | default('bar') }}"
- set_facts:
ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('foo', true) }}"
vars:
os_cloud: "{{ lookup('env','OS_CLOUD') | default('dev-foo', true) }}"
os_user: "{{ os_cloud.split('-')[1] | default(lookup('env','OS_USERNAME'), true) | default(lookup('env','USER'), true)}}"
# check if directory exists
- block:
- name: Remove default configuration
file:
state: absent
path: /etc/icinga/objects
when: check_path.stat.exists == false
- name: Deploy configuration
git:
repo: git@git.example.com:foo/icinga.git
dest: /etc/icinga/objects
accept_hostkey: yes
notify: icinga restart
when: check_path.stat.exists == false
- name: Directory exists already
debug:
msg: "Do something else..."
when: check_path.stat.exists
- name: get env variable
debug:
msg: "{{ lookup('env','HOME') }}"
- name: Copy directory on remote when not already exists
command: cp -a /tmp/foo /tmp/bar
args:
creates: /tmp/bar
# check if package installed
- name: Check if package is already installed
command: dpkg-query -W package_name
register: dpkg_query
changed_when: false
failed_when: dpkg_query.rc > 1
- name: Install package
package:
name: package_name
when: dpkg_query.rc > 0
# if / else condition
- set_fact:
second_var: "{{ 'foo' if first_var != 'stable' else 'bar' }}"
- set_fact:
second_var: "{{ ( first_var != 'stable' ) | ternary('foo','bar') }}"
- name: Configure locale
locale_gen:
name: "{{ item }}"
with_items:
- de_DE.UTF-8
- en_US.UTF-8
# get distribution
- setup:
filter: ansible_distribution
- debug:
msg: "{{ ansible_distribution }}"
- setup:
- debug:
msg: "{{ ansible_facts | to_nice_json }}"
- name: Configure timezone
# todo: (require dbus package)
# timezone:
# name: "Europe/Berlin"
# hwclock: local
copy:
content: "Europe/Berlin"
dest: /etc/timezone
tags: timezone
- name: Add directory to PATH variable
lineinfile:
dest: "/home/foo/.profile"
backrefs: yes
regexp: 'PATH=(["]*)((?!.*?/home/foo/bin).*?)(["]*)$'
line: 'PATH=\1\2:/home/foo/bin\3'
- name: Generate SSH key for a user with customized comment
user:
name: nagios
generate_ssh_key: yes
ssh_key_comment: nagios@{{ inventory_hostname }}
- name: check current timezone
shell: cat /etc/timezone
register: get_timezone
- name: set /etc/timezone
shell: echo "{{ timezone }}" > /etc/timezone
when: '"{{ timezone }}" not in get_timezone.stdout'
notify: update tzdata
- name: Deploy SSH key to inventory groups
authorized_key:
user: root
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
delegate_to: "{{ item }}"
with_items: "{{ }}"
with_items:
- "{{ groups.webserver }}"
- "{{ groups['proxy-server'] }}"
ignore_errors: yes
# when: inventory_hostname in groups['www']
- name: Get parameter from ini file from localhost
debug:
msg: "User in production is {{ lookup('ini', 'user section=production file=users.ini') }}"
- name: Remove /foo/bar if its a directory
stat:
path: /foo/bar
register: path
- file:
path: /foo/bar
state: absent
when: path.stat.isdir is defined and path.stat.isdir
- name: Configure network
copy:
content: |
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address {{ ansible_default_ipv4.address }}
netmask 255.255.255.0
gateway 10.0.3.254
dest: /etc/network/interfaces
- name: Configure DNS
copy:
content: |
nameserver 10.0.3.1
domain example.com
search example.com
dest: /etc/resolv.conf
- name: get public IP address from ipify.org
ipify_facts:
- debug:
msg: "{{ ipify_public_ip }}"
# list VMs
- name: List VMs
virt:
command: list_vms
register: vms
- debug:
msg: "{{ item }}"
with_items: "{{ vms.list_vms }}"
- debug:
msg: "{{ hostvars['www.example.com']['ansible_ssh_host_key_ecdsa_public'] }}"
- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml
# Create LV
- stat:
path: /dev/vg1/images
register: p
- name: Create LV /dev/vg1/images
lvol:
vg: vg1
lv: images
# size: "100%FREE"
size: 430G
when: not p.stat.exists
# Create filesystem
- name: Format /dev/vg1/images
filesystem:
fstype: ext4
dev: /dev/vg1/images
# Create mountpoint for filesystem
- name: Configure /etc/fstab
mount:
path: /var/lib/libvirt/images
src: /dev/vg1/images
fstype: ext4
state: mounted
# ipaddr filter
- hosts: localhost
vars:
my_ip: "{{ ansible_default_ipv4.network }}/{{ ansible_default_ipv4.netmask }}"
tasks:
- debug: msg="network {{ my_ip | ipaddr('network') }}"
- debug: msg="netmask {{ my_ip | ipaddr('netmask') }}"
# get host ip addresses
- debug: var=ansible_all_ipv4_addresses
- debug: var=ansible_default_ipv4.address
- debug: msg="{{ ansible_virtualization_type }}"
# lxc, kvm, VMware
- debug: msg="{{ ansible_virtualization_role }}"
# host, guest
# override systemd service
- name: Create /etc/systemd/system/apache2.service.d directory
file:
path: /etc/systemd/system/apache2.service.d
state: directory
owner: root
group: root
mode: 0755
- name: Override apache2.service
ini_file:
dest: /etc/systemd/system/apache2.service.d/override.conf
section: "{{ item.section }}"
option: "{{ item.option }}"
value: "{{ item.value }}"
no_extra_spaces: yes
with_items:
- { section: Service, option: PIDFile, value: "/var/run/apache2/apache2.pid" }
- { section: Service, option: Restart, value: "on-failure" }
- { section: Service, option: RestartSec, value: "30s" }
notify:
- systemctl daemon-reload
- name: Check if the disk is partitioned and also ignore sda
stat: path=/dev/{{item}}1
with_items: disk_var
when: item != 'sda'
register: device_stat
- name: Create GPT partition table
command: /sbin/parted -s /dev/{{ item.item }} mklabel gpt
with_items: device_stat.results
when:
- not item | skipped
- item.stat.exists == false
- name: Remove all cronjobs
shell: crontab -r
become: true
become_user: "{{ default_user }}"
ignore_errors: yes
- set_fact:
dl_url: http://git.example.com/script.sql
- name: get sql
uri:
method: GET
headers:
PRIVATE-TOKEN: "your_private_token"
url: "{{ dl_url }}"
dest: /tmp/bar.sql
environment:
http_proxy: http://router.example.com:3128
- name: Check if the disk is partitioned and also ignore sda
stat: path=/dev/{{item}}1
with_items: disks
when: item != "sda"
register: device_stat
- name: Create GPT partition table
command: /sbin/parted -s /dev/{{ item.item }} mklabel gpt
with_items: device_stat.results
when:
- not item | skipped
- item.stat.exists == false
- name: Create rsnapshot daily backup
cron:
name: rsnapshot daily backup
hour: 1
minute: 25
job: /usr/bin/rsnapshot daily
- name: Create rsnapshot weekly backup
cron:
name: rsnapshot weekly backup
hour: 2
minute: 25
weekday: 1
job: /usr/bin/rsnapshot weekly
- name: Create rsnapshot monthly backup
cron:
name: rsnapshot monthly backup
hour: 3
minute: 25
day: 1
job: /usr/bin/rsnapshot monthly
# dconf (read values with "dconf watch /" command)
# https://docs.ansible.com/ansible/2.4/dconf_module.html
- name: Read currently available keyboard layouts in Gnome
dconf:
key: /org/gnome/desktop/input-sources/sources
state: read
register: dconf
become: yes
become_user: "{{ default_user }}"
- debug:
msg: "{{ dconf }}"
- name: Configure Gnome
dconf:
key: "{{ item.key }}"
value: "{{ item.value }}"
with_items:
- { key: "/com/canonical/indicator/datetime/show-date", value: "true" }
become: yes
become_user: "{{ default_user }}"
# all nodes except
- name: show all the hosts matching the pattern, ie all but the group www
debug:
msg: "{{ item }}"
with_inventory_hostnames:
- all:!www
# format json output
- debug:
msg: "{{ hostvars[inventory_hostname] | to_nice_json }}"
- name: Force reboot on HP Gen8 nodes
shell: "{{ item }}"
async: 1
poll: 0
with_items:
- sync
- sleep 2 && echo 1 > /proc/sys/kernel/sysrq
- sleep 2 && echo b > /proc/sysrq-trigger
when: ansible_product_name == "ProLiant DL380p Gen8"
- name: Print item index
debug:
msg: "{{ item }} with index {{ idx + 1 }}"
loop:
- a
- b
- c
loop_control:
index_var: idx
- name: Prepare Nginx VHosts
copy:
content: |
server {
listen 80;
listen [::]:80 ;
server_name {% if idx == 0 %}_{% else %}{{ item }}{% endif %};
root /var/www/{{ item }}/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
dest: /etc/nginx/sites-available/{{ item }}
owner: root
group: root
mode: 0644
loop: "{{ vhosts }}"
loop_control:
index_var: idx
# list to file (template)
- name: Deploy HAProxy network_allowed.cfg configuration
copy:
dest: /etc/haproxy/network_allowed.cfg
content: |
{% for item in acl_network_allowed %}
{{ item }}
{% endfor %}
mode: 0644
owner: root
group: root
notify: restart haproxy
# test-me:
{{ ansible_env.HOME }}
"ansible_distribution_release": "bionic",
"ansible_distribution_major_version": "18",
"ansible_distribution_version": "18.04",
when: ansible_distribution_major_version|int < 20
addresses: [{{ ansible_default_ipv4.address }}/24]
#gateway4: {{ ansible_default_ipv4.address.split('.')[0:3] | join('.') }}.1
gateway4: {{ ansible_default_ipv4.gateway }}
# dns
# sudo apt install -y python-dnspython
- debug:
msg: "{{ lookup('dig','www.example.com' ) }}"
# nginx
- name: Configure nginx sites
copy:
content: |
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
autoindex on;
}
location ~ /\.git {
deny all;
}
}
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: 0644
notify: service nginx restart
# calculate ip
- hosts: localhost
vars:
mgmt_net: 10
ipmi_net: 20
ip: "{{ lookup('dig', 'www.example.com').split('.') }}"
tasks:
- debug:
msg: "{{ ip[0] }}.{{ ipmi_net }}.{{ ip[2] }}.{{ ip[3] }}"
- debug:
msg: "{{ lookup('dig', 'www.example.com') | replace('.{{ mgmt_net }}.', '.{{ ipmi_net }}.') }}"
- name: Upload file into s3 object storage
os_object:
cloud: "{{ os_cloud }}"
name: fstab
container: config
filename: /etc/fstab
- name: Install a deb package dirctly from the internet
apt:
deb: https://example.com/python-ppq_0.1-1_all.deb
- name: Update APT cache and remove useless packages / dependencies
apt:
update_cache: yes
upgrade: yes
autoclean: yes
autoremove: yes
- name: when inventory_hostname in dictonary
loop: "{{ www }}"
when: "inventory_hostname == item"
- debug:
msg: |
os_cloud: {{ os_cloud }}
os_user: {{ os_user }}
- name: Debconf example
debconf:
name: "{{ debconf.name }}"
question: "{{ debconf.question }}"
value: "{{ debconf.value }}"
vtype: "{{ debconf.vtype }}"
loop:
- { name: "percona-xtradb-cluster-server-5.7", question: "percona-xtradb-cluster-server-5.7/root-pass", value: "{{ database_password }}", vtype: "password" }
- { name: "percona-xtradb-cluster-server-5.7", question: "percona-xtradb-cluster-server-5.7/re-root-pass", value: "{{ database_password }}", vtype: "password" }
loop_control:
loop_var: debconf
no_log: true
changed_when: false
- name: Install hardware relevant packages
package:
name: "{{ item }}"
loop:
- lm-sensors
- hddtemp
when: ansible_virtualization_role == "host"
- name: Mark package as hold in APT
dpkg_selections:
name: "{{ item }}"
selection: hold
loop:
- docker-ce
- linux-image-generic
- name: Ensure files exists
file:
path: /etc/file.conf
mode: 0644
owner: root
group: root
state: touch
# when group names contains strings
when: group_names | select('foo','bar') | list | count > 0
# or condition with multiple lines
when: >
var1 != "success" or
var2 != "foo"
# parse json
when: (output_text.stdout | from_json).is_master
- name: Check HW RAID
shell: storcli /c0/v0 show J
register: output
- set_fact:
hwraid_output: "{{ output.stdout | from_json }}"
- debug:
msg: "{{ hwraid_output.Controllers[0]['Response Data']['Virtual Drives'][0]['State'] }}"
- name: Disable lvmetad
command: "sed -i 's/use_lvmetad = 1/use_lvmetad = 0/g' {{ tmp_rootfs_mount }}/etc/lvm/lvm.conf"
replace:
path: "{{ tmp_rootfs_mount }}/etc/lvm/lvm.conf"
regexp: 'use_lvmetad = (.*)$'
replace: 'use_lvmetad = 0'
# check whather file exists
- debug:
msg: "host file already exists"
when: etchosts is exists
vars:
etchosts: "/etc/hosts"
- name: generate dh params
command: sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
args:
creates: /etc/ssl/certs/dhparam.pem
- name: upgrade software
command: /opt/software/bin/upgrade
args:
removes: etc/software/software.conf.upgradeDocker
- name: Ensure some containers are stopped and dont autostart on boot
docker_container:
name: "{{ item }}"
restart_policy: no
state: stopped
loop:
- container1
- container2
- name: Gather container list
command: "docker ps --filter status=running --format {{ '{{.Names}}' }}"
register: containers
- name: Enable autostart for running containers
shell: docker update --restart=always $(docker ps -q)Find disk by model
- name: Find disk by model
find:
paths: /dev/disk/by-id
patterns: "*SSDPEL1K375GA*"
excludes: "*part*"
file_type: link
register: find_result
- debug:
msg: "{{ (find_result.files | first).path }}"
- debug:
msg: "{{ item.path }}"
with_items: "{{ find_result.files }}"
- stat:
path: "{{ (find_result.files | first).path }}"
register: stat_result
- debug:
msg: "{{ stat_result.stat.lnk_source }}"
- name: Get current nginx container version
shell: docker inspect --format=\{\{' .Config.Image '\}\} nginx | cut -d':' -f2
register: result
changed_when: falseTemplate
- include_vars:
file: customers.yml
name: customers
- blockinfile:
dest: stunnel.conf
block: "{{ lookup('template', 'stunnel.j2') }}"
marker: "; {mark} ANSIBLE MANAGED BLOCK FOR {{ cust }}"Variables
# variable contains variable
vars:
os_env: dev
user_name_dev: user1dev
user_name: "{{ vars['user_name_' + os_env] }}"
- debug:
msg: "{{ ansible_facts.cmdline.BOOTIF }}"
- debug:
msg: "{{ ansible_default_ipv4.macaddress }}"
- name: Print some debug information
vars:
msg: |
Module Variables ("vars"):
--------------------------------
{{ vars | to_nice_json }}
Environment Variables ("environment"):
--------------------------------
{{ environment | to_nice_json }}
GROUP NAMES Variables ("group_names"):
--------------------------------
{{ group_names | to_nice_json }}
GROUPS Variables ("groups"):
--------------------------------
{{ groups | to_nice_json }}
HOST Variables ("hostvars"):
--------------------------------
{{ hostvars | to_nice_json }}
debug:
msg: "{{ msg.split('\n') }}"
tags: debug_info
- setup:
- name: Debug vars to /tmp/vars.json
copy:
content: "{{ vars | to_nice_json }}"
dest: /tmp/vars.json
- name: Display all variables/facts known for a host
debug:
var: hostvars[inventory_hostname]
tags: debug_infoInclude role inside of task
- include_role:
apply:
become: true
name: "{{ role_item }}"
loop_control:
loop_var: role_item
loop:
- my-role1APT
- name: Install a .deb package from the internet.
apt:
deb: https://example.com/python-ppq_0.1-1_all.deb
Replace string
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
# remove digits
os_type: "{{ inventory_hostname.split('-')[1] | regex_replace('[0-9]', '') }}"Cofigure snapd proxy
- hosts: localhost
tasks:
- name: Configure snap proxy
become: yes
ini_file:
path: /etc/systemd/system/snapd.service.d/http-proxy.conf
section: Service
option: Environment
value: '"http_proxy=http://proxy.example.com:8080"'
mode: 0644
create: yes
notify: restart snapd
handlers:
- name: restart snapd
systemd:
name: snapd
state: restarted
daemon_reload: yes- name: Find storage disks by model
find:
paths: /dev/disk/by-id
patterns: "*SSDPE2KX080T8*"
excludes: "*part*"
file_type: link
register: find_result
- set_fact:
storage_disks_path: []
- name: Get storage disk device path
set_fact:
storage_disks_path: "{{ storage_disks_path }} + [ '{{ item.path }}' ]"
with_items: "{{ find_result.files }}"
- debug:
msg: "{{ item.0 }}_{{ item.1 }}"
with_together:
- "{{ range(1, (storage_disks_path | length) + 1) | list + range(1, (storage_disks_path | length) + 1) | list }}"
- "{{ range(1, (storage_disks_path | length) * 2 + 1, 2) | list + range(2, (storage_disks_path | length) * 2 + 2, 2) | list }}"
- debug:
msg: "{{ item.0 }}_{{ item.1 }}"
with_together:
- "{{ storage_disks_path }}"
- "{{ range(1, (((storage_disks_path | length)) + 1) * 2, 2) | list }}"
- debug:
msg: "{{ item.0 }}_{{ item.1 }}"
with_together:
- "{{ storage_disks_path }}"
- "{{ range(2, (((storage_disks_path | length)) + 1) * 2, 2) | list }}"
- debug:
msg: "{{ item }}"
with_sequence: start=0 end="{{ (storage_disks.files | length) * 2}}"
- debug:
msg: "{{ item.1.path }}-{{ item.0 }}"
with_nested:
- [ 1, 2 ]
- "{{ storage_disks.files | length }}"
- debug:
msg: "{{ item.path }}_{{ idx + 1}}"
loop:
"{{ storage_disks_result.files + storage_disks_result.files }}"
loop_control:
index_var: idx
- set_fact:
- base_list: [1, 2, 3, 4]
- exclude_list: [2, 4]
- add_list: [5, 6]
tasks:
- debug:
msg: "{{ base_list | union(add_list) | difference(exclude_list) }}"
- set_fact:
device:
- sdb: 2
- sdc: 3
- sdd: 4
- name: Debug device var
debug:
msg: "{% for key, value in item.iteritems() %}{% for i in range(value) %} {{ key }} {{ loop.index }} {% endfor %}{% endfor %}"
loop: "{{ device }}"
- set_fact:
Fruits:
Apple: 'Red'
Orange: 'Orange'
Grapes: 'Greem'
- name: Ansible dictionary loop Example
debug:
msg: "Key is {{ item.key}} and color is {{item.value}}"
with_dict: "{{ Fruits }}"
- set_fact:
myvar: "hello1"
- name: Ansible loop with conditional example
debug:
msg: "{{ item }}"
with_items:
- "hello1"
- "hello2"
- "hello3"
when: item == "{{ myvar }}"
- "{{ 'python-mysqldb' if ansible_distribution_version is version('18.00','<') else 'python3-mysqldb' }}"
- "{{ 'python-pymysql' if ansible_distribution_version is version('18.00','<') else 'python3-pymysql' }}"
- name: Extract database port
set_fact:
nova_database_port: "{{ nova_database_address.split(':')[1] | default(default_mysql_port) }}"
# group_by
https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#handling-os-and-distro-differences
- set_fact:
group_extra_vars: "{{ os_env }}.{{ inventory_hostname.split('-')[1] | regex_replace('[0-9]', '') }}.{{ ansible_distribution_release }}.{{ ansible_product_name | replace(' ','-') | lower }}"
- name: Load extra vars
group_by:
key: "{{ group_extra_vars }}"
tags: always
- name : Find files bigger than 100mb in size
find:
paths: /var/log
file_type: file
patterns:
- '^[a-z]*_[0-9]{8}\.log$'
- '^_[0-9]{2,4}_.*.log$'
- '^[a-z]{1,5}_.*log$'
size: 100m
use_regex: yes
register: outputParted
- name: "Create partitions on devices"
block:
- name: install parted
package:
name: parted
state: present
- name: "Read device information /dev/sda"
parted:
device: "/dev/sda"
unit: MiB
register: device_info
- name: "Add new partition /dev/sda2"
parted:
device: "/dev/sda"
number: "2"
part_type: primary
flags: [ lvm ]
state: present
part_end: "100%"
part_start: "{{ device_info.partitions[0].end + 1}}MiB"
- name: "Add device to exising volume group {{ volumeGroup }}."
lvg:
vg: "{{ volumeGroup }}"
pvs: "/dev/sda1,/dev/sda2"Json
- command: lshw -json -c bus
register: lshw_json
- debug:
msg: "{{ ( lshw_json.stdout | from_json | to_nice_json ) }}"
- set_fact:
motherboard: "{{ (lshw_json.stdout | from_json)[0].product }}"Jinja2
# format long Jinja2 expression
- set_fact:
ip_address: >-
{{ ( api_response
| map(attribute='fixed_ips')
| map('from_json')
| selectattr('ip_address', 'match', '^192')
| list
| first
).ip_address
}}
# Recursively find /tmp files older than 4 weeks and equal or greater than 1 megabyte
- find:
paths="/tmp"
age="1d"
size="1m"
recurse=yessecurity.nesting: "{{ 'true' if item in ['nomad-client1', 'nomad-client2', 'nomad-client3'] else 'false' }}"- name: Retry download file from URL
get_url:
url: https://example.com/path/to/file
dest: /path/to/target
register: exporter_compressed_download
until: exporter_compressed_download.status_code == 200
retries: 60
delay: 5# keep line break
lookup('file', '/etc/foo.txt', rstrip=False)
# lookup
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/url_lookup.html# split util last part and join
my_string.split(".")[:-1] | joinAPT
- name: Add Percona Ubuntu focal repository
apt_repository:
repo: deb [arch=amd64] http://repo.example.com/foo/apt focal main
update_cache: yes
- name: Install libssl1.1 package
apt:
deb: http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1l-1ubuntu1.3_amd64.deb
update_cache: yes
when: (ansible_lsb.major_release | int > 20)
- name: Enable universe repository
apt_repository:
repo: deb http://archive.ubuntu.com/ubuntu {{ ansible_distribution_release }} universe
ansible_loop
https://blog.ordix.de/neuerungen-in-ansible-ab-version-2-8
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html#extended-loop-variables
https://stackoverflow.com/questions/29276198/ansible-how-to-construct-a-variable-from-another-variable-and-then-fetch-its-v
https://docs.ansible.com/ansible/latest/collections/ansible/utils/index_of_lookup.html
- name: "Get pevious / next control element"
set_fact:
prev: "{{ ansible_loop.previtem | default(ansible_loop.allitems[ansible_loop.length | int -1]) }}"
next: "{{ ansible_loop.nextitem | default(ansible_loop.allitems[0]) }}"
loop: "{{ groups['control'] | select('search', inventory_hostname.split('-')[0]) | sort }}"
when:
- element == inventory_hostname
loop_control:
extended: yes
loop_var: element
- set_fact:
ctl_nodes: "{{ groups['control'] | sort }}"
- set_fact:
current_ctl_node_id: "{{ lookup('ansible.utils.index_of', ctl_nodes, 'eq', inventory_hostname) }}"
- debug:
msg: "{{ lookup('ansible.utils.index_of', groups['control'], 'eq', inventory_hostname) }}"
- debug:
msg: "current_ctl_node_id: {{ current_ctl_node_id }}"
- debug:
msg: "{{ ctl_nodes[current_ctl_node_id | int - 1] }} / {{ ctl_nodes[current_ctl_node_id | int + 1] }}"
# nested / double loop
- name: Deploy SSH key for CI/CD users
copy:
src: ~/.ssh/{{ item[1] }}
dest: /home/{{ item[0] }}/.ssh/
owner: "{{ item[0] }}"
group: "{{ item[0] }}"
mode: 0600
with_nested:
- [ gitlab-runner, cicd ]
- [ id_rsa, id_rsa.pub ]Restart SSH connection
- name: reset ssh connection
meta: reset_connectionCreate splitted CEPH OSD LVs
- name: Create splitted CEPH OSD LVs
lvol:
vg: ceph{{ item.0 }}
lv: ceph-block_data{{ item.1 }}
size: 50%VG
with_together:
- "{{ range(1, (storage_disks_result.files | length) + 1) | list + range(1, (storage_disks_result.files | length) + 1) | list }}"
- "{{ range(1, (storage_disks_result.files | length) * 2 + 1, 2) | list + range(2, (storage_disks_result.files | length) * 2 + 2, 2) | list }}"Enforcing diff mode
tasks:
- name: This task will not report a diff when the file changes
ansible.builtin.template:
src: secret.conf.j2
dest: /etc/secret.conf
diff: false