nikdoof.com

/technotes/ ansible

Ansible

Variable Prompts

Prompts for individual vars_prompt variables will be skipped for any variable that is already defined through the command line --extra-vars option, or when running from a non-interactive session (such as cron or Ansible AWX). See Defining variables at runtime.

---
- hosts: all
  vars_prompt:

    - name: username
      prompt: What is your username?
      private: no

    - name: password
      prompt: What is your password?

  tasks:

    - name: Print a message
      ansible.builtin.debug:
        msg: 'Logging in as {{ username }}'

Tagging

Play Tagging

Tags can be applied to plays, this will tag all subtasks

- hosts: all
  tags: ntp
  tasks: []

Role Tagging

Roles can be tagged in the playbook including them, without the use of import_role and include_role. Those functions actually modify the behaviour of the tags

roles Value in Playbooks

roles:
  - role: rolename
    tags:
      - roletag

import_role

Tags are applied to all the tasks inside the role, but not the import_role task itself

- import_role: bob
  tags:
    - bob

include_role

Tags are applied to the include_role task only, and not any sub tasks within the role.

- include_role: bob
  tags:
    - bob

block Tagging

Tags on blocks work as expected, it’ll tag the block and also subtasks. This is useful for grouping actions with a singular tag, without editing every single task.

- name: RHEL OS specific tasks
  tags:
    - rhel
  block:
    - name: Do something
    ...

include_tasks Tagging

By default, Ansible does not apply tag inheritance to dynamic re-use with include_role and include_tasks. If you add tags to an include, they apply only to the include itself, not to any tasks in the included file or role. This allows you to execute selected tasks within a role or task file - see Selectively running tagged tasks in re-usable files when you run your playbook.

If you want tag inheritance, you probably want to use imports. However, using both includes and imports in a single playbook can lead to difficult-to-diagnose bugs. For this reason, if your playbook uses include_* to re-use roles or tasks, and you need tag inheritance on one include, Ansible offers two workarounds. You can use the apply keyword:

- name: Apply the db tag to the include and to all tasks in db.yaml
  include_tasks:
    file: db.yml
    # adds 'db' tag to tasks within db.yml
    apply:
      tags: db
  # adds 'db' tag to this 'include_tasks' itself
  tags: db

Or you can use a block:

- block:
   - name: Include tasks from db.yml
     include_tasks: db.yml
  tags: db

Linting

Writing Custom Lint Rules

Each rule definition should have the following:

Function Types

def matchtask(self, task: Dict[str, Any], file: "Optional[Lintable]" = None) -> Union[bool, str]

def matchplay(self, file: "Lintable", data: "odict[str, Any]") -> List["MatchError"]

def matchyaml(self, file: Lintable) -> List[MatchError]:

def matchtasks(self, file: "Lintable") -> List["MatchError"]

def matchdir(self, lintable: "Lintable") -> List["MatchError"]

def matchlines(self, file: "Lintable") -> List["MatchError"]

def match(self, line: str) -> Union[bool, str]

Packaging

Add the following to your setup.cfg

[options]

packages =
    ansiblelint.rules.custom.yodel

package_dir =
    ansiblelint.rules.custom.yodel = rules

Ansible Vault

Ansible Vault can be used to encrypt values within a playbook, allowing the sharing of secrets in a safe and secure way.

Providing passwords to Ansible

# Providing the vault passwords manually
ansible-playbook -i etc/sit/ecom playbooks/vm-configure.yml --vault-id default_vault@prompt

# Using the passwordstate-client
$ ansible-playbook -i inventory playbooks/vm-configure.yml --vault-id default_vault@../ansible-tools/passwordstate-client.py

# Or, just ask for a password
$ ansible-playbook -i inventory playbooks/vm-configure.yml --ask-vault-pass

Encrypting a file

$ ansible-vault encrypt --vault-id <vault_id>@prompt filename

Encrypting a string

$ echo -n 'stringtoencrypt' | ansible-vault encrypt_string --vault-id <vault_id>@prompt

Using Secrets with to_json

You need to use the vault_to_text=True option on to_json from Ansible 2.3+ to ensure the values are decrypted and presented in plain text format.

- name: Create webhook config json
  copy:
    dest: /etc/webhook/hooks.json
    owner: root
    group: root
    mode: 0644
    content: "{{ www_webhook_hooks | default([]) | to_json(vault_to_text=True) }}"
  register: webhook_config

Custom Client for Ansible Vault Passwords

Integration between Ansible Vault and other password storage tools can be done by creating a “client” script that returns the password in clear text form. A client script should do the following:

Using with a Playbook run

$ ansible-playbook --vault-id vault-id@path/to/script.py

Snippets

Failure Protection

Use retries and until to avoid tasks failing due to a package manager being locked.

    - name: Install package (Ubuntu)
      apt:
        deb: "/tmp/{{ package_name }}"
      register: apt_res
      retries: 5
      until: apt_res is success

Speed up the stat module

The stat module calculates the checksum and the md5 of the file in order to get the required data. If you just want to check if the file exists use:

- name: Verify swapfile status
  stat:
    path: "{{ common_swapfile_location }}"
    get_checksum: no
    get_md5: no
    get_mime: no
    get_attributes: no
  register: swap_status
  changed_when: not swap_status.stat.exists