Ansible
Automation go brrrrrr
- 0. Prerequisites
- 1. Building Tasks
- 2. Roles
- 3. Ansible Secrets Management
- 4. Network Management with Ansible
- 5. IDEMPOTENCE in Ansible
0. Prerequisites
Linux -> This is a great site to learn basics -> https://linuxjourney.com/ If you are more adventurers -> https://www.reddit.com/r/archlinux/comments/u5by1d/how_does_a_noob_read_the_arch_wiki/
Or you could also take a look at my LFCS, CompTIA Linux+ Courses.
1. Building Tasks
Using host groups
- Purpose of Inventory File
- Helps target Ansible tasks to specific systems
- Enables control and monitoring through host groups
- Sample Inventory File Structure (/etc/ansible/hosts)
- Can use IP address ranges (e.g., 10.0.1.1 through 10.0.1.3)
- Contains different sections:
- All hosts section (different from default ‘all’ group)
- Uses Ansible SSH host variables
- Creates aliases for hosts
- Specific host groups (web servers, database servers, backup servers)
- Variable sections (both group-specific and all-system variables)
- Host Groups Features
- Default ‘all’ group automatically includes every host
- Can create custom host groups
- Allows targeting specific groups of systems
- Variables can be set at different levels:
- Group level
- All systems level
- Individual host level
- Practical Example
- Webservers.yml playbook demonstration:
- Targets web servers host group
- Runs with root privileges (sudo)
- Uses apt package manager
- Performs package uninstallation
- Updates cache for repository definitions
- Execution:
- Uses ansible-playbook command
- Gathers facts from target systems
- Performs specified tasks across grouped systems
- Key Benefits
- Simplifies system management
- Enables easy execution of playbooks against specific groups
- Provides flexible targeting options
- Makes system automation more efficient
Using tags
- Purpose
- Tags allow targeting specific tasks within playbooks
- Provides selective execution of tasks
- Implementation
- Tags can be added at two hierarchy levels:
- Task level
- Play level (for multiple plays with multiple tasks)
- Sample Playbook (tags.yml)
- Contains three tasks:
- Install Apache2 (tag: Apache2)
- Install NTP (tag: NTP)
- Start NTP (tag: NTP_start)
- Using Tags in Commands
- Basic syntax: ansible-playbook –tags [tagname] [playbook]
- Options:
- –tags: Execute specific tagged tasks
- –list-tags: View all available tags in playbook
- –skip-tags: Execute all tasks except specified tagged ones
- Example Commands
- Run NTP installation only:
- ansible-playbook –tags NTP tags.yml
- Skip NTP start:
- ansible-playbook –skip-tags ntp_start tags.yml
- Additional Features
- Cache update optimization example:
- Apache2 installation includes cache update only if existing info is >1 hour old
- Key Points
- Simple and straightforward method
- Popular way to control playbook execution
- One of many methods for controlling Ansible playbooks
- Provides flexibility in task execution
Running tasks against localhost
- Main Concept:
- Efficiently running tasks against Ansible control node using connection local value
- Two primary methods demonstrated
- First Method (controlnode.yml):
- Uses hosts: localhost (predefined, no inventory definition needed)
- Debug feature used to get inventory variable information
- Verbosity levels:
- Range: 0-4
- Level 1 used in example
- Requires -v flag when running playbook
- Default level is 0 (no specification needed)
- Second Method (connection_controlnode.yml):
- Uses connection: local
- Bypasses SSH overhead
- Communicates directly with local node
- More performance-efficient than first method
- Same task execution as first method
- Running the Playbooks:
- Command format: ansible-playbook [filename] -v
- Both methods executed successfully
- Second method slightly faster (approximately 1 second vs 2 seconds)
- Key Points:
- Multiple ways exist to run tasks locally (about 4 methods)
- Connection local approach recommended for maximum performance
- Useful for advanced troubleshooting
- Both methods provide detailed facts about localhost
- Performance Consideration:
- Second method (connection: local) is more efficient due to:
- No SSH overhead
- Direct local communication
- Recommended for performance-critical scenarios
Using the command line to control execution
- Starting at Specific Tasks:
- Command line option: –start-at-task
- Allows skipping initial tasks in playbook
- Syntax: ansible-playbook playbook.yml –start-at-task ‘Task Name’
- Task name must match exactly (use single quotes for names with spaces)
- Useful when initial tasks aren’t required
- Interactive Execution:
- Command line option: –step
- Allows stepping through playbook tasks one by one
- Prompts for confirmation before each task
- User can choose which tasks to execute
- Useful for:
- Troubleshooting playbooks
- Understanding playbook flow
- Selective task execution
- Example Demonstration:
- Used tags.yml playbook with tasks:
- Installing Apache2
- Installing NTP
- Starting NTP service
- Demonstrated both –start-at-task and –step options
- Successfully executed selective tasks
- Important Concepts:
- Idempotency:
- Can run playbooks multiple times safely
- No negative impact on already completed tasks
- Different from traditional scripts
- Example: Won’t reinstall already installed packages
- Naming conventions important for task names
- CLI options provide flexibility in execution
- Benefits:
- Better control over playbook execution
- Enhanced troubleshooting capabilities
- Safer execution through idempotency
- Flexibility in task selection and execution
Specifying variables in the inventory file
- Introduction
- Variables add power to Ansible automation
- Multiple flexible ways to pass variables using inventory file
- Inventory file is a critical component
- Variable Assignment in Inventory File Different methods: a) Host-specific variables
- Example: target6 with backup_file variable
- Direct assignment under host
b) All systems variables
- Using “all:vars” section
- Applies to every system
- Uses built-in automatic host group
c) Host group variables
- Example: web servers group
- Variables specific to group members
- Using Variables in Playbooks
- Syntax: Double curly braces {{variable_name}}
- Example playbook components:
- Host group targeting
- File module usage
- Variable consumption from inventory
- When statement for validation
- Command Line Variables
- Can pass variables via command line
- Example: file_state variable
- Syntax: variable_name=value
- Practical Example
- Created file using playbook
- Used inventory variables for file location
- Command line variable for file state
- Demonstrated cleanup using state=absent
- Key Points
- Variables enhance Ansible flexibility
- Multiple methods for variable assignment
- Important for advanced task execution
- Integration between inventory and playbooks
- Command line options for variable passing
Creating dynamic inventory files
Dynamic Inventory in Ansible
- Purpose: Addresses limitations of static inventory files, especially for cloud infrastructure
- Allows real-time inventory updates through cloud provider APIs
AWS Implementation Example:
Prerequisites:
- Install Python packages:
- python3-pip
- Boto3 (AWS Python package)
- Install Python packages:
Configuration Steps: a. Create Directory Structure:
- Create /opt/ansible/inventory/
b. Create AWS EC2 YAML File:
- File: aws_ec2.yaml
- Contents:
- Plugin: aws_ec2
- AWS access key
- AWS secret key
- Group settings (default: organized by tags)
- Composed section for private IP addressing
c. Modify Ansible Configuration:
- Location: /etc/ansible/ansible.cfg
- Add: enable_plugins = aws_ec2 in inventory section
Testing:
- Command: ansible-inventory –inventory /opt/ansible/inventory/aws_ec2.yaml –list
- Returns: Complete inventory of EC2 instances via AWS API
Key Points:
- Available for all major cloud providers
- Requires appropriate API access/permissions
- Enables real-time inventory management
- Essential for dynamic cloud environments
- Each cloud provider has specific implementation steps
Note: Similar process can be followed for other cloud providers with their respective configurations and requirements.
Using templates
- Introduction to Templates
- Major aspect of configuration management and automation tools
- Ansible supports Jinja2 templating language
- Jinja2 is popular among Python developers
- Template File Structure
- Must have .J2 extension
- Can be named anything
- Example template contains:
- Message from node (using inventory_hostname variable)
- Today’s message (using web server variable)
- Variables can be pulled from facts or defined in playbook
- Playbook Structure (use_templates.yml)
- Applied to web servers host group
- Uses sudo privileges
- Contains variables section:
- Defines web_server_message
- Tasks:
- Ensures Apache2 service is running
- Uses template to create index.html
- Specifies source (Jinja2.J2) and destination (Apache server location)
- Implementation
- Template creates HTML page
- Variables integrated from:
- Target node
- Playbook-defined variables
- Execution using: ansible-playbook use_templates.yml
- Creates/updates index.html on target systems
- Advanced Capabilities
- Templates can include:
- Conditional statements
- Loops
- Filters
- Data transformations
- Arithmetic calculations
- Practical Example Results
- Successfully created web page showing:
- Node identification (from inventory_hostname)
- Custom message (from playbook variable)
- Additional static content
Note: Templates provide powerful functionality for dynamic content generation and configuration management in Ansible.
Conditional Execution
- Purpose & Importance
- Essential for power and flexibility in automation
- Moves beyond static decision-making
- Allows dynamic task execution based on conditions
- WHEN Statement
- Can be applied to tasks
- Executes tasks if condition returns true
- Works with:
- Ansible facts
- Registered variables
- Playbook variables
- Inventory variables
- Custom facts
- Practical Example (cond.yml playbook)
- Targets all hosts
- Requires root privileges
- Contains two main tasks:
a) Upgrade in Redhat
- Condition: ansible_os_family is Redhat
- Uses yum module b) Upgrade in Debian
- Condition: ansible_os_family is Debian
- Uses apt module
- Technical Notes
- No need for double curly brackets in conditions
- Uses direct Python communication
- Implements Jinja2 functionality
- Execution Example
- Playbook checks OS family on all hosts
- Skips Redhat tasks (no Redhat systems)
- Executes Debian updates where applicable
- Typical runtime: 60-120 seconds for updates
- Future Integration
- Can be combined with loops (upcoming feature)
- Enhances automation capabilities
- Provides additional flexibility in task execution
Benefits:
- Simplifies system management
- Enables automated decision-making
- Reduces repetitive tasks
- Provides flexible automation solutions
Using loops
- Introduction
- Ansible automates repetitive IT tasks
- Useful for tasks like changing file permissions or creating user accounts
- Loops work well with conditionals
- Two types: simple loops and complex loops
- Complex loops can iterate over nested lists or retry tasks until conditions are met
- Basic Loop Example (loop1.yml)
- Playbook targets web servers
- Variables section defines ‘packages’ list (Git, Vim, Ruby)
- Uses apt module for installation
- Initially used with_items parameter for iteration
- Deprecation warning suggests more efficient method
- Updated method: directly specify packages in name parameter without loop
- Dictionary Loops (loop2.yml)
- Uses hierarchical structure in variables section
- Contains different website categories (AWS, Microsoft, Google, misc)
- Each entry has author and author ID
- Uses with_dictionary syntax
- Example filters based on author ID condition (as001)
- Debug module displays results
- Benefits
- Reduces code redundancy
- Efficient task completion
- Built-in functionality in modules (like apt)
- Can include conditions within loops
- Flexible iteration through different data structures
- Important Features
- Can use verbose options for detailed execution information
- Supports both simple and complex data structures
- Deprecation warnings help maintain current best practices
- Effective for handling repetitive tasks
- Can combine with conditions for specific matching
- Best Practices
- Use built-in module functionality when available
- Pay attention to deprecation warnings
- Choose appropriate loop type based on data structure
- Consider loops for code efficiency
- Utilize proper construction for optimal task completion
Testing plays with check mode
- Traditional Testing Method
- Usually tested against actual equipment
- Considered relatively safe due to idempotency
- Multiple playbook runs don’t cause damage
- Check Feature
- Alternative to testing on actual equipment
- Command option: –check
- Purpose: Sanity checking before production deployment
- Check Feature Benefits
- Verifies Ansible’s ability to:
- Reach targets
- Gather facts
- Execute playbook plays
- Detect syntax errors
- Identify problems
- Practical Example
- Used use_templates.yml playbook
- Features jinja2 compliance
- Creates web page with message
- Error Detection Example
- Demonstrated with intentional errors:
- Target three unavailability
- Moved jinja2.J2 template
- Shows colorful error display
- After fixing template location (J3 to J2):
- Rerun showed only remaining target availability issue
- Key Takeaway
- Use check feature for debugging before production deployment
- Simple but powerful troubleshooting tool
- Helps prevent issues in production environment
2. Roles
An overview of roles in Ansible
- Roles in Ansible
- Method for organizing and sharing complex Ansible orchestrations
- Automatically loads related components based on file structure
- Components include:
- handlers
- tasks
- files
- templates
- variables
- defaults
- Ansible Galaxy
- Website for hosting and sharing roles
- Includes client tool (part of default Ansible installation)
- Role Directory Structure
- Default location: /etc/ansible/roles/
- Can store roles in any location
- Specify location in playbook
- Edit Ansible config file for additional locations
- Creating Roles using Ansible Galaxy Client
- Command: ansible-galaxy init [role_name]
- Must be in target directory when creating role
- Requires appropriate permissions
- Creates complete directory structure with:
- Directory hierarchy
- Basic YAML files
- Template files with usage comments
- Benefits of Roles
- Promotes code reusability
- Improves infrastructure management
- Enhances Ansible efficiency
- Practical Example
- Created test role “testrole1”
- Generated standard directory structure
- Includes main.yml files in each subdirectory
- Files contain basic templates with usage instructions
Note: Roles should be used where appropriate to maximize Ansible’s capabilities and maintain organized, reusable code.
Using variables in roles
- Variable Definition and Reusability
- Experts create reusable files for common variable definitions
- Concept aligns with Ansible roles functionality
- Role Structure and Defaults
- Located in Ansible roles directory
- Contains ‘defaults’ directory with main.yml
- Default variables can be set in defaults/main.yml
- Example: variable ‘my_var’ set with default value
- Variable Override Options
- Defaults can be overridden through multiple methods
- ‘vars’ directory and its main.yml is one way to override
- CLI provides another override option
- Implementation Example
- roles.yml playbook demonstrates role incorporation
- Targets web servers with root access
- Uses test_role_one
- Tasks directory contains main.yml with debug module
- Debug module prints ‘my_var’ value
- Variable Precedence Demonstration
- Default value shows when no override exists
- Variables in vars/main.yml override defaults
- Example override value: “this is a value from VARs in the role”
- CLI Override Capability
- Highest precedence for variable values
- Syntax: ansible-playbook roles.yml -e “my_var=‘this is an override’”
- Requires proper quoting for strings with spaces
- Single quotes inside double quotes for variable assignment
- Key Concepts
- Easy integration of variables with roles
- Clear variable precedence hierarchy
- Multiple override options available
- Important for flexible and maintainable automation
Using role-based templates
- Role Structure and Templates
- Roles simplify template usage in Ansible playbooks
- Default location: /etc/ansible/roles
- Templates should be placed in the templates directory within the role
- Role structure automatically looks for templates in the template sub-directory
- Task Configuration
- main.yaml in tasks directory contains:
- index.html creation task
- Apache2 service start task
- Jinja template implementation
- Template Implementation
- Jinja template moved to templates directory within role
- No need to keep playbook and template in same directory
- Role structure handles template location automatically
- Variable Handling
- Default values can prevent undefined variable errors
- Default variables set in defaults/main.yaml
- Example:
- Variable: webserver_message
- Default value: “this is a default message”
- Playbook Execution
- Basic execution uses default message
- Can override default by specifying variable:
- ansible-playbook roles.yaml -e “webserver_message=‘this is my real message’”
- Must use single quotes for strings with spaces
- Best Practices
- Use defaults directory to:
- Provide fallback values
- Prevent undefined variable errors
- Set default configurations
- Templates can be easily integrated with roles
- Variables can be overridden during playbook execution
This structure provides organized and flexible template management within Ansible roles.
Roles and Ansible Galaxy
- Purpose & Introduction
- Premier web location for Ansible resources
- Helps with project acceleration and implementation
- Provides downloadable roles and components
- Free resource for Ansible users
- Website Features
- Organized by popular categories on homepage
- Search functionality available
- Filters for specific content types (roles, plugins, modules)
- Contains multiple resource types:
- Roles
- Plugins
- Modules
- Resource Installation
- Provides installation syntax for each component
- Installation process:
- Uses Ansible Galaxy Command
- Default installation path: ~/.ansible/roles
- Creates standard role directory structure:
- README
- defaults
- handlers
- tasks
- Search Example: AWS
- Can search for AWS-related components
- Shows various resources:
- Roles
- Plugins (example showed 48 modules)
- Can filter results by resource type
- Best Practices
- Important to read README files before implementation
- Should review role documentation thoroughly
- Not recommended to implement without understanding documentation
- Benefits
- Inspires new uses for Ansible
- Assists with daily tasks
- Expands beyond basic/familiar uses
- Cost-effective (free) resource
- Helps avoid limited tool usage
- Installation Example
- Demonstrated with AWS inspector role
- Shows practical implementation
- Creates proper directory structure
- Maintains standard Ansible organization
Role management
- Ansible’s Simplicity
- Ansible is known for being simple and straightforward
- Role management follows this simple approach
- Configuration Settings
- Location: /etc/ansible/ansible.cfg
- Important setting: roles_path in default section
- Uncommenting roles_path sets default location for roles
- Default path: /etc/ansible/roles
- Role Installation Options a) Using Default Directory:
- Uncomment roles_path in ansible.cfg
- Roles automatically install to /etc/ansible/roles
- Requires sudo permissions due to directory restrictions
b) Custom Installation:
- Leave roles_path commented
- Use -p flag with install command
- Manually specify installation path
- Installing Roles from Ansible Galaxy
- Command: ansible-galaxy install [role-name]
- Example demonstrated: ansible-network.aws role
- Sudo required for installation in default directory
- Role Removal
- Use standard Linux remove command
- Simply delete role files from directory
Best Practices:
- Plan role installation locations carefully
- Maintain centralized control over role locations
- Ensure proper permissions for role management
Note: The approach emphasizes simplicity while maintaining control over role organization and management.
3. Ansible Secrets Management
- Introduction to Secrets
- Secrets refer to passwords, tokens, and sensitive information in Ansible code
- Clear text secrets in code pose security risks
- Risk increases when code is shared in public repositories (GitHub, Ansible Galaxy)
- Ansible Vault - File Level Encryption
- Uses AES encryption with shared secrets
- Basic Commands:
- ansible-vault create: Creates new encrypted file
- ansible-vault encrypt: Encrypts existing file
- ansible-vault edit: Edits encrypted file
- Running encrypted playbooks:
- Use –ask-vault-pass flag
- System prompts for vault password
- Variable Level Encryption
- More granular approach than full file encryption
- Using encrypt_string:
- Command: ansible-vault encrypt_string @prompt
- Encrypts specific strings rather than entire files
- Generates encrypted syntax for playbook use
- Implementation Example
- Encrypted strings can be placed in variables section of playbook
- Reference encrypted variables in tasks
- Running playbooks with encrypted variables:
- Requires vault password for decryption
- Use –ask-vault-pass flag
- Playbook remains unencrypted while variables are secured
- Benefits
- Flexible security options (file or variable level)
- Easy implementation
- Maintains code readability while protecting sensitive data
- Allows selective access to secrets
- Compatible with version control and sharing
4. Network Management with Ansible
- Core Benefits and Strengths
- Automates repetitive network tasks
- Separates data model from execution layer
- Supports multi-vendor networks and devices
- Uses SSH and HTTPS for secure management
- Access to vast number of shared modules and roles
- Ensures strong security during management and automation
- IP Address Management a) Playbook Example (ip_address.yml):
- Runs against localhost with local connection
- Variables handling:
- Default gateway in dotted decimal (e.g., 10.10.0.1)
- Network mask in dotted decimal notation
- Converts between formats
b) IP Address Manipulation Features:
- Creates network address with prefix
- Displays default gateway
- Uses IP address filter for format conversion
- Calculates next usable host address
- Converts between:
- IP addresses to integers
- Back to IP format with prefix notation
c) Key Filters:
- IP address filter: formats network/prefix display
- IPV4 filter: converts back to IP format
- Integer conversion capabilities
- Network Device Support a) Supported Vendors:
- Arista
- Cisco devices with various OS:
- ASA operating systems
- IOS
- IOS XE
- Nexus OS
- F5 BIG-IP
- Junos OS
- Many other vendors (majority of network vendors supported)
- Connection Methods and Challenges a) Traditional Requirements:
- SSH and Python typically needed on managed nodes
- Many network devices lack native Python support
b) Alternative Connection Options:
- Network CLI
- NETCONF
- HTTP API
- Local (legacy/proprietary approach, declining in use)
- Trend toward Linux/Unix-based systems with Python support
- Extended Functionality and Integration a) Enhancement Options:
- Built-in modules
- Custom modules
- Plugins for enhanced internal functionality
- Roles from Ansible Galaxy
b) Implementation Considerations:
- Growing vendor support for Python/Linux
- Increasing integration capabilities
- Focus on automation and orchestration across IT infrastructure
- Flexibility in connection methods
- Strong community support and resources
- Best Practices
- Regular practice with IP address manipulation
- Utilizing built-in filters and mechanisms
- Understanding various connection methods
- Leveraging available modules and roles
- Keeping up with vendor-specific implementations
5. IDEMPOTENCE in Ansible
- Definition and Core Concept:
- Idempotence means executing commands repeatedly without changing the final result/target state
- Originally used as a programming term before becoming crucial in IT administration
- Considered a major selling point and essential feature of Ansible
- Ensures predictable and consistent system states
- Historical Challenges (Pre-Ansible):
- Traditional automation scripts faced significant issues:
- Scripts would execute partially (e.g., 12 lines successful, crash on 13th line)
- Upon rerun, would fail immediately due to previously executed steps
- No built-in state awareness
- Couldn’t maintain consistency across multiple executions
- No way to track what had already been done
- Ansible’s Implementation of Idempotence:
a) State Management:
- Uses built-in state examination
- Tracks current state of resources
- Compares desired state vs current state
- Only makes changes when necessary
b) Package Management Example:
- For uninstallation:
- Uses state: absent
- Checks if package exists
- Removes if present
- Takes no action if already absent
- For installation:
- Verifies if package is installed
- Installs only if absent
- Skips if already present
- Maintains desired state without redundant operations
- Handling Non-Idempotent Commands:
a) Solution Approaches:
- Building state information into commands
- Using registration mechanisms
- Implementing state verification
b) Practical Example (register_state.yml):
Target Configuration:
- Works with webservers group
- Uses target variable: /temp/idempotent.txt
Task Sequence:
File Creation (Idempotent):
- Uses copy module
- Sources from local files directory
- Creates idempotent.txt on target
- Skips if file already exists
File Modification (Non-Idempotent):
- Uses sed command
- Replaces word “file” with “change”
- Creates temporary file during process
- Moves to target destination
State Verification:
- Uses grep command
- Searches for word “change”
- Returns status code:
- 0 = success (change found)
- Non-zero = failure (change not found)
- Provides verification mechanism
- Benefits and Importance:
Infrastructure Consistency:
- Maintains desired state across systems
- Prevents configuration drift
- Ensures predictable results
Operational Advantages:
- Safe to run playbooks multiple times
- No risk of damaging existing configurations
- Reduces human error
- Simplifies automation processes
Management Benefits:
- Reliable system state management
- Easier troubleshooting
- Consistent deployment processes
- Improved automation reliability
- Best Practices:
- Always verify module idempotence capabilities
- Implement state checking for non-idempotent commands
- Use built-in Ansible modules when possible
- Test playbooks multiple times to ensure idempotent behavior
- Document any non-idempotent operations