Examples¶
Learn Mooncake through practical, runnable examples. Follow the learning path below or jump to topics that interest you.
Running Examples
All examples are runnable YAML configurations. Try them with:
🎓 Learning Path¶
Follow these examples in order to build your Mooncake skills from beginner to advanced.
Level 1: Getting Started (5 minutes)¶
01 - Hello World ⭐¶
Your first Mooncake configuration
Learn the basics: running shell commands and printing output.
- name: Hello from Mooncake
shell: echo "Running on {{os}}/{{arch}}"
- name: Show system info
print: "CPU cores: {{cpu_cores}}, Memory: {{memory_total_mb}}MB"
You'll learn:
- Basic step syntax (name + action)
- Using system facts (os, arch, cpu_cores)
- Shell and print actions
Time: 2 minutes
Level 2: Variables & Facts (10 minutes)¶
02 - Variables and Facts ⭐¶
Define custom variables and use auto-detected system information
- vars:
app_name: MyApp
version: "1.0.0"
- name: Install {{app_name}}
shell: echo "Installing {{app_name}} v{{version}} on {{os}}"
- name: Show detected facts
print: |
OS: {{os}}
Distribution: {{distribution}}
Package Manager: {{package_manager}}
Python: {{python_version}}
You'll learn:
- Defining variables with
vars - Templating with
{{ variable }} - Auto-detected facts (os, distribution, package_manager)
- Multi-line output with
print
Time: 5 minutes
Level 3: File Operations (15 minutes)¶
03 - Files and Directories ⭐⭐¶
Create, manage, and modify files and directories
- name: Create config directory
file:
path: ~/.config/myapp
state: directory
mode: "0755"
- name: Create config file
file:
path: ~/.config/myapp/settings.yml
state: file
content: |
app_name: myapp
version: 1.0
mode: "0644"
- name: Create symlink
file:
path: ~/bin/myapp
state: link
target: /usr/local/bin/myapp
You'll learn:
- Creating directories with permissions
- Writing file content inline
- Creating symlinks
- File states: file, directory, link, absent
Time: 8 minutes
Level 4: Control Flow (20 minutes)¶
04 - Conditionals ⭐⭐¶
Execute steps based on conditions
- name: Install on macOS
shell: brew install neovim
when: os == "darwin"
- name: Install on Ubuntu
shell: apt install -y neovim
become: true
when: os == "linux" && package_manager == "apt"
- name: Check if file exists
shell: test -f ~/.config/app.conf
register: config_exists
ignore_errors: true
- name: Create config if missing
file:
path: ~/.config/app.conf
state: file
when: config_exists.rc != 0
You'll learn:
whenconditionals (==, !=, &&, ||)- Platform-specific execution
registerto capture resultsignore_errorsfor optional checks
Time: 10 minutes
06 - Loops ⭐⭐¶
Iterate over lists to avoid repetition
- vars:
packages:
- neovim
- ripgrep
- fzf
- tmux
- name: Install package
shell: brew install {{item}}
with_items: "{{packages}}"
- name: Deploy dotfile
copy:
src: "{{item.src}}"
dest: "~/{{item.name}}"
with_filetree: ./dotfiles
when: item.is_dir == false
You'll learn:
with_itemsloops over listswith_filetreeloops over directory contents- Accessing loop item properties
Time: 10 minutes
Level 5: Advanced Techniques (30 minutes)¶
05 - Templates ⭐⭐¶
Render configuration files from templates
- name: Render nginx config
template:
src: ./nginx.conf.j2
dest: /etc/nginx/nginx.conf
mode: "0644"
vars:
port: 8080
workers: 4
ssl_enabled: true
Template (nginx.conf.j2):
worker_processes {{ workers }};
server {
listen {{ port }};
{% if ssl_enabled %}
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
{% endif %}
}
You'll learn:
- Jinja2 template syntax
- Variables in templates
{{ var }} - Conditionals in templates
{% if %} - Loops in templates
{% for %}
Time: 12 minutes
07 - Register ⭐⭐¶
Capture and use step results
- name: Check service status
shell: systemctl is-active nginx
register: nginx_status
ignore_errors: true
- name: Start if not running
service:
name: nginx
state: started
when: nginx_status.rc != 0
become: true
- name: Show result
print: "Service was {{nginx_status.stdout}}"
You'll learn:
- Capturing command output with
register - Accessing result properties (rc, stdout, stderr)
- Conditional execution based on results
- Building dependent workflows
Time: 8 minutes
08 - Tags ⭐⭐¶
Selective execution with tags
- name: Install dependencies
shell: npm install
tags: [dev, setup]
- name: Build production
shell: npm run build
tags: [prod, build]
- name: Run tests
shell: npm test
tags: [test, ci]
Run specific workflows:
mooncake run config.yml --tags dev # Only dev-tagged steps
mooncake run config.yml --tags prod,ci # prod OR ci steps
You'll learn:
- Tagging steps for organization
- Filtering execution by tags
- Building workflow stages (dev, test, prod)
Time: 6 minutes
Level 6: Production Patterns (45 minutes)¶
09 - Sudo ⭐⭐⭐¶
Execute privileged operations securely
- name: Install system package
shell: apt update && apt install -y docker.io
become: true
- name: Add user to docker group
shell: usermod -aG docker {{ansible_user}}
become: true
Run with sudo password:
You'll learn:
become: truefor sudo operations- Password handling (interactive, file, env var)
- Security best practices
Time: 10 minutes
10 - Multi-File Configs ⭐⭐⭐¶
Organize large configurations
# main.yml
- include: ./vars/defaults.yml
- include: ./tasks/setup.yml
- include: ./tasks/install.yml
- include: ./tasks/configure.yml
# vars/defaults.yml
- vars:
app_name: webapp
version: "2.0.0"
# tasks/setup.yml
- name: Create directories
file:
path: "{{item}}"
state: directory
with_items:
- /opt/{{app_name}}
- /var/log/{{app_name}}
You'll learn:
includefor splitting configs- Variable sharing across files
- Organizing by function (vars, tasks, handlers)
- Building modular configurations
Time: 15 minutes
11 - Execution Control ⭐⭐⭐¶
Advanced error handling and control
- name: Download with retry
shell: curl -O https://example.com/file.tar.gz
timeout: 10m
retries: 3
retry_delay: 30s
register: download
- name: Verify download
shell: sha256sum file.tar.gz
register: checksum
failed_when: "'abc123' not in checksum.stdout"
- name: Conditional changed detection
shell: make install
register: result
changed_when: "'installed' in result.stdout"
You'll learn:
timeoutfor long operationsretriesandretry_delayfor resiliencefailed_whenfor custom failure detectionchanged_whenfor accurate change tracking- Building robust production workflows
Time: 20 minutes
12 - Unarchive ⭐⭐¶
Extract and manage archives
- name: Download tarball
download:
url: https://example.com/app.tar.gz
dest: /tmp/app.tar.gz
checksum: sha256:abc123...
- name: Extract to destination
unarchive:
src: /tmp/app.tar.gz
dest: /opt/app
strip_components: 1
creates: /opt/app/bin/app
- name: Cleanup
file:
path: /tmp/app.tar.gz
state: absent
You'll learn:
- Downloading with checksum verification
- Extracting tar, tar.gz, zip archives
strip_componentsfor path manipulationcreatesfor idempotency- Complete download-extract-install pattern
Time: 12 minutes
🎯 Real-World Projects¶
Dotfiles Management ⭐⭐⭐¶
Complete dotfiles deployment and configuration
A production-ready example showing:
- Cross-platform dotfiles (macOS/Linux)
- Git repository management
- Symlink creation with backup
- Shell configuration (zsh, bash)
- Tool installation (vim, tmux, git)
- Platform detection and adaptation
Code preview:
- name: Clone dotfiles repo
shell: git clone https://github.com/user/dotfiles.git ~/.dotfiles
creates: ~/.dotfiles
- name: Backup existing dotfiles
shell: cp "{{item}}" "{{item}}.backup-{{timestamp}}"
with_filetree: ~/.dotfiles
when: item.is_file and lookup('file', '~/' + item.name) is defined
- name: Create symlinks
file:
src: ~/.dotfiles/{{item.name}}
dest: ~/{{item.name}}
state: link
with_filetree: ~/.dotfiles
when: item.is_file
What you'll build:
- Automated dotfiles deployment
- Backup strategy before changes
- Conditional installation based on OS
- Tool-specific configurations
Time: 30 minutes
Idempotency Demonstration ⭐⭐¶
Understanding Mooncake's idempotency guarantees
Learn how Mooncake ensures operations are safe to run multiple times:
# Run this multiple times - only changes on first run
- name: Create directory
file:
path: /opt/myapp
state: directory
# ✅ First run: changed=true (created)
# ✅ Second run: changed=false (already exists)
- name: Download file
download:
url: https://example.com/file.tar.gz
dest: /tmp/file.tar.gz
checksum: sha256:abc123...
# ✅ First run: changed=true (downloaded)
# ✅ Second run: changed=false (checksum matches)
- name: Install package
shell: apt install -y neovim
creates: /usr/bin/nvim
# ✅ First run: changed=true (installed)
# ✅ Second run: skipped (binary exists)
You'll learn:
- How Mooncake detects changes
- Using
createsfor idempotency - Checksum-based file operations
- State-based file management
- Why idempotency matters
Time: 15 minutes
📂 Browse By Action Type¶
-
Shell Commands
Examples using
shellandcommandactions -
File Operations
Examples using
file,copy,templateactions -
Variables & Logic
Examples using variables, conditionals, loops
-
Advanced Patterns
Error handling, multi-file, execution control
💡 Quick Tips¶
Start with Hello World
New to Mooncake? Begin with 01 - Hello World and follow the learning path in order.
Dry-Run Everything
Always test with --dry-run first to see what will happen:
Mix and Match
All techniques can be combined. For example:
This combines: loops, conditionals, sudo, tags, and variables!Test in Safe Environment
Some examples modify system state. Use a VM or container for testing, especially examples 09-12.
🔗 See Also¶
- Actions Reference - Complete action documentation
- Variables Guide - Working with variables and facts
- Control Flow - Conditionals, loops, and tags
- Quick Reference - One-page cheat sheet
- Best Practices - Production patterns and tips
Ready to start? → Begin with Hello World ⭐