In a Nutshell (🌰)
- Playbooks in SSM are Ansible-based automation scripts for infrastructure management
- They provide idempotent, declarative configuration across multiple devices
- Playbooks can be stored locally or in remote repositories
- Variables and templates allow for flexible, reusable playbooks
- Playbooks can be executed manually or triggered by automations
What are Playbooks in SSM?
In Squirrel Servers Manager, playbooks are Ansible-based automation scripts that define a series of tasks to be executed across your infrastructure. Playbooks allow you to automate complex operations, ensure consistent configurations, and manage your devices at scale.

Key Components of the Playbooks Model
1. Playbook Structure
Playbooks are written in YAML and consist of several key elements:
- Plays: Groups of tasks that run against specific hosts
- Tasks: Individual actions to be performed
- Handlers: Tasks that only run when notified by other tasks
- Roles: Reusable collections of tasks, handlers, and variables
- Variables: Dynamic values that can be used throughout the playbook
- Templates: Files with variable placeholders that get filled in during execution
2. Playbook Storage
SSM supports multiple ways to store and manage playbooks:
Local Playbooks: Stored directly in SSM
- Created and edited through the SSM interface
- Immediately available for execution
- Version controlled within SSM
Remote Playbooks: Stored in external repositories
- Git repositories (GitHub, GitLab, etc.)
- Integration with version control systems
- Collaborative development workflows
- Automatic synchronization
3. Playbook Execution
Playbooks can be executed in several ways:
Manual Execution: Run directly by users
- Target specific devices or groups
- Set variables at runtime
- Monitor execution in real-time
Scheduled Execution: Run at specified times
- Regular maintenance tasks
- Off-hours operations
- Recurring configurations
Playbook Lifecycle
Playbooks in SSM follow a defined lifecycle:
- Creation: Playbook is written or imported into SSM
- Testing: Playbook is tested against development or staging environments
- Deployment: Playbook is made available for production use
- Execution: Playbook is run against target devices
- Monitoring: Execution progress and results are tracked
- Maintenance: Playbook is updated as requirements change
- Versioning: Changes are tracked through version control
Real-World Examples
Example 1: System Updates and Security Hardening
Problem:
You need to ensure all servers are regularly updated and follow security best practices.
Solution using the Playbooks Model:
# system_maintenance.yml
- name: System Updates and Security Hardening
hosts: all
become: true
vars:
security_level: high
reboot_if_needed: false
tasks:
- name: Update package cache
apt:
update_cache: yes
when: ansible_os_family == "Debian"
- name: Upgrade all packages
apt:
upgrade: dist
when: ansible_os_family == "Debian"
- name: Install security packages
apt:
name:
- fail2ban
- ufw
- unattended-upgrades
state: present
when: ansible_os_family == "Debian"
- name: Configure firewall
ufw:
rule: allow
port: "{% raw %}{{ item }}{% endraw %}"
proto: tcp
loop:
- 22
- 80
- 443
- name: Enable firewall
ufw:
state: enabled
policy: deny
- name: Configure automatic updates
template:
src: auto-updates.j2
dest: /etc/apt/apt.conf.d/20auto-upgrades
when: ansible_os_family == "Debian"
- name: Reboot if required
reboot:
when: reboot_if_needed and ansible_os_family == "Debian"
This playbook:
- Updates the package cache
- Upgrades all installed packages
- Installs security-related packages
- Configures and enables a firewall
- Sets up automatic updates
- Optionally reboots the system if needed
You can schedule this playbook to run weekly across all your devices, ensuring consistent security practices.
Example 2: Application Deployment
Problem:
You need to deploy a web application across multiple servers with environment-specific configurations.
Solution using the Playbooks Model:
---
# deploy_webapp.yml
- name: Deploy Web Application
hosts: web_servers
become: true
vars:
app_version: "1.2.3"
app_env: production
app_port: 8080
db_host: "{% raw %}{{ hostvars['db_server']['ansible_host'] }}{% endraw %}"
tasks:
- name: Install dependencies
apt:
name:
- nodejs
- npm
state: present
when: ansible_os_family == "Debian"
- name: Create application directory
file:
path: /opt/myapp
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Download application package
get_url:
url: "https://example.com/releases/myapp-{% raw %}{{ app_version }}{% endraw %}.tar.gz"
dest: /tmp/myapp.tar.gz
- name: Extract application package
unarchive:
src: /tmp/myapp.tar.gz
dest: /opt/myapp
remote_src: yes
owner: www-data
group: www-data
- name: Configure application
template:
src: config.js.j2
dest: /opt/myapp/config.js
notify: restart application
- name: Create systemd service
template:
src: myapp.service.j2
dest: /etc/systemd/system/myapp.service
notify: reload systemd
- name: Start and enable application service
systemd:
name: myapp
state: started
enabled: yes
handlers:
- name: reload systemd
systemd:
daemon_reload: yes
- name: restart application
systemd:
name: myapp
state: restarted
This playbook:
- Installs required dependencies
- Creates the application directory
- Downloads and extracts the application package
- Configures the application with environment-specific settings
- Sets up a systemd service for the application
- Starts and enables the service
You can use this playbook to deploy your application to different environments by changing the variables.
Playbook Patterns
1. Configuration Management
SSH Security Configuration
Ensure consistent SSH security settings across all servers
File: configure_ssh.yml
---
# configure_ssh.yml
- name: Configure SSH Security
hosts: all
become: true
tasks:
- name: Update SSH configuration
lineinfile:
path: /etc/ssh/sshd_config
regexp: '{% raw %}{{ item.regexp }}{% endraw %}'
line: '{% raw %}{{ item.line }}{% endraw %}'
state: present
loop:
- { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
- { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
- { regexp: '^#?X11Forwarding', line: 'X11Forwarding no' }
- { regexp: '^#?MaxAuthTries', line: 'MaxAuthTries 3' }
notify: restart ssh
handlers:
- name: restart ssh
service:
name: sshd
state: restarted
- This playbook targets all hosts in your inventory
- It uses the lineinfile module to modify specific lines in the SSH configuration
- The loop allows multiple configuration changes with a single task
- Changes only happen if the current configuration differs from desired state
- The handler ensures SSH service is restarted only if configuration changes
2. Application Lifecycle Management
Application Lifecycle Management
Manage the complete lifecycle of applications with a single playbook
File: app_lifecycle.yml
---
# app_lifecycle.yml
- name: Application Lifecycle Management
hosts: app_servers
become: true
vars:
app_state: present # Options: present, absent, updated
app_version: '2.0.0'
tasks:
- name: Install application
block:
- name: Download application
get_url:
url: 'https://example.com/app-{% raw %}{{ app_version }}{% endraw %}.zip'
dest: '/tmp/app-{% raw %}{{ app_version }}{% endraw %}.zip'
- name: Install application
unarchive:
src: '/tmp/app-{% raw %}{{ app_version }}{% endraw %}.zip'
dest: '/opt/applications/'
remote_src: yes
when: app_state == 'present' or app_state == 'updated'
- name: Remove application
file:
path: '/opt/applications/app-{% raw %}{{ app_version }}{% endraw %}'
state: absent
when: app_state == 'absent'
- This playbook uses a variable (app_state) to control its behavior
- The block construct groups related tasks together
- Conditional execution (when clause) determines which actions to perform
- The same playbook handles installation, updates, and removal
- Version control is managed through variables for easy updates
3. Infrastructure Provisioning
Web Server Provisioning
Set up a complete web server with HTTPS in one playbook
File: provision_webserver.yml
---
# provision_webserver.yml
- name: Provision Web Server
hosts: new_servers
become: true
tasks:
- name: Install web server packages
apt:
name:
- nginx
- php-fpm
- certbot
state: present
- name: Configure virtual host
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{% raw %}{{ domain_name }}{% endraw %}.conf
- name: Enable virtual host
file:
src: /etc/nginx/sites-available/{% raw %}{{ domain_name }}{% endraw %}.conf
dest: /etc/nginx/sites-enabled/{% raw %}{{ domain_name }}{% endraw %}.conf
state: link
- name: Obtain SSL certificate
command: >
certbot --nginx -d {% raw %}{{ domain_name }}{% endraw %} -d www.{% raw %}{{ domain_name }}{% endraw %}
--non-interactive --agree-tos --email {% raw %}{{ admin_email }}{% endraw %}
args:
creates: /etc/letsencrypt/live/{% raw %}{{ domain_name }}{% endraw %}/fullchain.pem
- This playbook targets newly added servers to set up a complete web stack
- It installs all required packages in a single task
- Templates are used for configuration files to customize for each domain
- Symbolic links enable the virtual host configuration
- The creates parameter ensures the SSL certificate is only obtained if it doesn't exist
Best Practices
💡 Do's
- Write idempotent playbooks that can be run multiple times safely
- Use roles to organize and reuse playbook components
- Test playbooks in development environments before production
- Use variables for values that might change
- Include proper error handling and validation
- Document your playbooks with comments and README files
⛔ Don'ts
- Don't hardcode sensitive information like passwords or API keys
- Don't write playbooks that make irreversible changes without confirmation
- Don't ignore failed tasks without proper handling
- Don't create overly complex playbooks that are hard to maintain
- Don't forget to version control your playbooks
Common Misconceptions
Misconception 1: Playbooks are just scripts
Reality: While scripts execute commands sequentially, playbooks are declarative and idempotent. They define the desired state of the system and only make changes when necessary to achieve that state.
Misconception 2: Playbooks require deep Ansible knowledge
Reality: SSM provides templates and examples that make it easy to get started with playbooks. The web interface simplifies creation, editing, and execution, reducing the learning curve.
Misconception 3: Playbooks are only for large-scale deployments
Reality: Playbooks are valuable for infrastructures of any size. Even with just a few devices, playbooks ensure consistency and save time on repetitive tasks.