Ansible snippet

None

Table des matières

Running ansible

Proxy jump (bastion)

ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q ansible_user@bastion"'

Overloading default variables

ansible-playbook firewall/playbook.yml -i myHost:22,  --extra-vars "@firewall/vars.yml" --user user-ansible

To run only task with specific tags add “-t”

Run as user

- name: Run a touch command as the splunk user
  command: "touch /tmp/toto"
  become: true
  become_user: "splunk"

If package acl is not installed :

TASK [. : Run a touch command as the splunk user] ************************************
fatal: [vault]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: changing ownership of '/var/tmp/ansible-tmp-1590248740.8311727-147619513728589/': Operation not permitted\nchown: changing ownership of '/var/tmp/ansible-tmp-1590248740.8311727-147619513728589/AnsiballZ_command.py': Operation not permitted\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"}

Variables on command line

ansible-playbook deploy/playbook.yml --user user-ansible -i myHost, --extra-vars "maven_artificat_version=0.1.2 other_variable=foo"

Run addhoc shell command

ansible all -m shell -a "cat /etc/passwd" -i myHost:22, --user user-ansible --become

muHost | CHANGED | rc=0 >>
root❌0:0:root:/root:/bin/bash
daemon❌1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin❌2:2:bin:/bin:/usr/sbin/nologin
sys❌3:3:sys:/dev:/usr/sbin/nologin
sync❌4:65534:sync:/bin:/bin/sync
games❌5:60:games:/usr/games:/usr/sbin/nologin
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
lp❌7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail❌8:8:mail:/var/mail:/usr/sbin/nologin

Various

Loop until a condition is met

- shell: /usr/bin/foo
  register: result
  until: result.stdout.find("all systems go") != -1
  retries: 5
  delay: 10

Loop against dictionnary

filter_instances:
  filter01:
    project: "EventHub01"
    service: "filter"
    instance: "relai01"

  filter02:
    project: "EventHub02"
    service: "filter"
    instance: "relai01"
- name: Template sink.properties file
  template:
    src: sink.properties.j2 
    dest: "/tmp/dev/{{ filter_instances[item]['service'] }}.{{ filter_instances[item]['instance'] }}.sink.properties"
  loop: "{{ filter_instances.keys() | list }}"

Run a single command with dynamic var

- name: Dump mongo database
  vars:
    dump_directory: "/dump/{{ ansible_date_time.iso8601_basic }}"
  command: "docker exec -it 02df8fc10e0a /usr/bin/mongodump --host 127.0.0.1 --forceTableScan --db rocketchat --out {{ dump_directory }}"
  register: dump_result

Create user and group

traefik_user: traefik
traefik_group: traefik
- name: Create Traefik group
  group:
    name: "{{ traefik_group }}" 
    state: present
    system: yes

- name: Create Traefik user
  user:
    name: "{{ traefik_user }}"
    comment: For running services
    groups:  "{{ traefik_group }}" 
    shell: /bin/bash
    create_home: no
    append: yes
    system: yes    

Git clone https with a self-signed certificate

- git:
    repo: "https://gitlab.net.lan"
    dest: "/opt/src"
    version: master
  environment:
    GIT_SSL_NO_VERIFY: 'true'

Create directory

- name: "Create directory"
  file:
    path: "{{ splunk_home }}/etc/apps/splunk_instrumentation/local/"
    state: directory
    owner: "{{ splunk_user }}"
    group: "{{ splunk_group }}"     

Remove / delete directory

- name: Remove empty directory {{ backup_root }}/{{ dump_time }}
  file:
    path: "{{ backup_root }}/{{ dump_time }}"
    state: absent

find files using pattern and unarchive most recent

- name: List backup
  find:
    paths: "/home/backup"
    file_type: file
    recurse: no
    patterns: "^dump_.*?\\.tgz$"
    use_regex: yes
  register: files_matched

- name: Get latest file
  set_fact:
    latest_file: "{{ files_matched.files | sort(attribute='mtime',reverse=true) | first }}"
  register: last_backup

- debug:
   msg: "{{ last_backup }}"

- name: Extract backup in directory
  unarchive:
     src: "{{ latest_file.path }}"
     dest: /tmp
     remote_src: yes

Wait for file to be deleted

- name: Making sure that the lock file absent or removed
  wait_for:
    path:  "{{lockfile}}"
    delay: 10
    timeout: 30
    state: absent

Conditional task based on file presence

- name: Stat the file 
  stat:
    path: '/tmp/file'
  register: infa_domain_file

- name: Install if the domain file does not exist
  become: yes
  import_tasks: user_install.yml
  when: not infa_domain_file.stat.exists

Download a file and extract

traefik_path: /opt/traefik
traefik_src: https://github.com/containous/traefik/releases/download/v2.2.0/traefik_v2.2.0_linux_amd64.tar.gz
- name: Unarchive 
  unarchive:
    src: "{{ traefik_src }}"
    dest: "{{ traefik_path }}"
    remote_src: yes

Download a file and check integrity

- name: Download filebeat using get_url
  become: yes
  get_url:
    url: https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.6.2-amd64.deb
    dest: /opt/src/
    mode: 0755
    checksum: sha512:ae712a9dc6e1b13536fa7555d3bba926f75e58f3ac249078e059ec5bab38ebca6cfb897369e0d8eb76cabdc4434a43194bc10b569b71d1bdfe3ec388708f6be4  filebeat-7.6.2-amd64.deb
    group: filebeat
    owner: filebeat

Services

Create systemd service

- name: Copy traefik systemd unit file into place 
  template:
    src: traefik.unit.j2
    dest: /etc/systemd/system/traefik.service
    owner: root
    group: root
    mode: 0644

traefik.unit.j2

[Unit]
Requires=network.target
After=network.target

[Service]
Type=simple
User={{ traefik_user }}
ExecStart={{ traefik_path }}/traefik
Restart=on-abnormal

[Install]
WantedBy=multi-user.target

Enable and start service.

- name: Enable and start traefik service.
  service:
    name: traefik
    state: "started"
    enabled: "enabled"

Check services status and start it if not up

- name: ensure that services are running
  service: 
    name: "{{ item }}"
    state: started
    enabled: yes
  with_items:
    - firewall
    - fail2ban
    - postfix

Force reconnection (usecase : iptables)

- name: Configure the firewall service.
  service:
    name: firewall
    state: "{{ firewall_state }}"
    enabled: "{{ firewall_enabled_at_boot }}"
  async: 30
  poll: 0
    
- name: Waiting for resurection
  wait_for_connection:
    delay: 3
    timeout: 300    

Start a program and wait for port available

- name: Start tomcat
  become: yes
  become_user: tomcat
  async: 10
  poll: 0
  shell:
	 "startup.sh"
  args:
	chdir: "/opt/tomcat/bin" 

- name: Validate if tomcat is UP
  tags: tomvalidate
  wait_for:
	host: "localhost"
	port: 8080
	delay: 10
	timeout: 30
	state: started
	msg: "Tomcat server is not running"

Execute multiple commands in a Single Shell

- name: Multiple command
  become: yes
  shell: |
	echo -e "\n Change directory to Splunk"
	cd /opt/splunk
	echo -e "\n Present working directory is" `pwd`

Reboot

- name: Reboot the server and wait for it to come back up.
  reboot:

Allow program to bind port below 1024

- name: Set capability on the binary file to be able to bind to TCP port <1024
  shell: "/usr/sbin/setcap 'cap_net_bind_service=+ep' /opt/traefik/traefik"

Package

Package Installation

- name: Ensure packages are installed.
  apt:
    pkg:
        - postfix
        - opendkim
        - opendkim-tools    
    state: present
    install_recommends: no
    update_cache: yes
	cache_valid_time: 3600

Install remote package

- name: Install filebeat deb file from url
  apt: 
    deb: https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.6.2-amd64.deb

Upgrade a Single package

- name: Update cache and upgrade openssl
  apt:
   name: openssl
   state: latest
   update_cache: yes

Update & Upgrade All the packages installed

- name: Ansible Update Cache and Upgrade all Packages
  register: updatesys
  apt:
   name: "*"
   state: latest
   update_cache: yes

- name: check the stats
  debug:
   msg:  "{{updatesys.stdout_lines}}"

Check if packages are installed

- name: Get package facts
  package_facts:
	manager: auto

- name: Validating if the package is installed 
  debug: 
	msg: "{{item}} is installed"
  when: '"{{item}}" in ansible_facts.packages'
  with_items:
	- traefik
	- filebeat

Debug - display variable content

- name: Check the Uptime
  shell: "uptime"
  register: Uptime

- debug: var=Uptime

Debug - display file content

- name: Display the file
  shell: cat /tmp/file.txt
  register: displaylist
      
- debug: msg="{{displaylist.stdout_lines}}"

Jinja Template

Apply template

- name: "Template Splunk user-prefs.conf"
  template:
    src: user-prefs.conf.j2
    dest: "/opt/splunk/etc/system/local/user-prefs.conf"
    owner: "splunk"
    group: "splunk"  

Loop over array

variables definition

firewall_allowed_tcp_ports_in: []

firewall_allowed_tcp_ports_in:
 - 443
 - 80

firewall_additional_rules: 
    - "iptables -I OUTPUT 1 -p tcp --dport 80 -m owner --uid-owner _apt -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT"

jinja template

{# Add a rule for each open port #}
{% for port in firewall_allowed_tcp_ports_in %}
	iptables -A INPUT  -m tcp -p tcp --dport {{ port }} -j ACCEPT
{% endfor %}

# Additional custom rules.
{% for rule in firewall_additional_rules %}
{{ rule }}
{% endfor %}

Join array

postfix_mydestination:
  - localdomain
  - localhost
  - localhost.localdomain
  - mysite.site
mydestination = {{ postfix_mydestination | join(', ') }}

Conditionnal

firewall_log_output_dropped_packets: true
{% if firewall_log_dropped_packets %}
	ip6tables -A INPUT -m limit --limit 15/minute -j LOG --log-level 7 --log-prefix "Dropped by firewall: "
{% else %}	
	# Dont't log
{% endif %}

Related