Ansible Playbooks
Ansible is the preferred provisioner for complex configurations in Klarity ImageFactory. It provides a powerful, declarative language for describing the desired state of a system, ensuring that components are idempotent and maintainable across different operating systems.
Playbook Structure and Requirements
All Ansible playbooks used in ImageFactory must adhere to specific formatting and structural requirements to ensure they can be executed correctly by the backend workers.
- Valid YAML: The playbook must be a syntactically correct YAML file.
- Hosts Definition: Every play in the playbook must have the
hostsattribute set to eitherdefaultorall. This is because ImageFactory executes the playbook against a single target instance during the build process. - Privilege Escalation: For tasks requiring root or administrator privileges, use
become: yes. This is standard practice for installing packages or modifying system configurations.
Playbook Validation
ImageFactory performs automated validation of playbooks against a predefined JSON schema. This schema ensures that the playbook structure is compatible with the ImageFactory execution environment. The validation schema is stored at artifacts/ansible_schemas/playbook.json within the system.
If a playbook fails validation, the component creation or version update will be rejected with a detailed error message indicating the structural issue.
Directory Structure for System Components
System components follow a standardized directory structure to separate logic for different operating systems:
component-name/
├── linux/
│ ├── playbook.yml
│ └── tasks/
│ └── main.yml
└── windows/
├── playbook.yml
└── tasks/
└── main.yml
Example Linux Playbook
---
- hosts: all
become: yes
tasks:
- name: Install security updates
apt:
upgrade: dist
update_cache: yes
when: ansible_os_family == "Debian"
- name: Install common utilities
package:
name:
- curl
- vim
- git
state: present
Advanced Execution Control
ImageFactory provides several mechanisms for fine-tuning how Ansible playbooks are executed:
Ansible Tags
You can use tags to selectively execute specific parts of a playbook. This is useful for large playbooks where only a subset of tasks needs to run for a particular image.
Extra Variables
Distributions can define ansible_extra_vars, which are passed to the playbook at runtime. These variables can be used to customize the behavior of the playbook based on the specific OS version or cloud provider.
Skipped Tags
Similarly, distributions can define skipped_tags to exclude certain tasks from execution. This is often used to skip tasks that are known to be incompatible with a specific distribution or environment.
Component Properties
When a component is added to an image template, users can define component properties. These are key-value pairs that are automatically injected into the Ansible execution environment as variables.
For example, if a component has a property named app_version with the value 2.1.0, it can be accessed in the playbook as {{ app_version }}.
Best Practices
To ensure your Ansible components are reliable and efficient, follow these best practices:
- Idempotency: Always write tasks that can be run multiple times without changing the result. Use modules like
apt,yum,template, andfilewhich are idempotent by design. - Check Mode Support: Where possible, ensure your tasks support Ansible's check mode (
--check). This allows for dry-runs to verify what changes would be made. - Error Handling: Use
failed_whenandignore_errorsjudiciously to handle expected failure scenarios gracefully. - OS Conditionals: Use the
ansible_facts(e.g.,ansible_os_family,ansible_distribution) to write cross-platform playbooks that adapt to the target environment. - Modular Tasks: Break down large playbooks into smaller, logical task files included via
include_tasksorimport_tasks.