SlideShare a Scribd company logo
Testing Salt States: Part 1
The Basics
About Me (Jason Denning)
• DevOps Engineer
• SaltStack user for ~ 3 years
• SaltStack Certified Engineer #2
• AWS Certified Architect
• OSS Advocate (first Linux install ~ 1998)
• Pythonista
• jasondenning on GitHub / @jason_denning on Twitter
● Provide analytics and
marketing/segmentation tools for
mobile app developers
● Hosted backend APIs available world-
wide
● Lots of traffic
● Big fans of SaltStack
● upsight.com
WARNING: Work In Progress
● Testing infrastructure is not a common practice
● These slides are rough
● Your Mileage May Vary!
● We should work (together) on improving this
Why Test?
● DevOps: Infrastructure is code
● Code should be tested
● ⇒ Infrastructure should be tested
Why Test? (continued)
● Find errors faster
● Prevent regressions
● Allow others to contribute
● Simplify Code Reviews (CI)
● Improve Documentation
What to Test
● Basic Syntax (linting)
● Individual States
● State Relationships
● Different Environments
● As much as possible (within reason)
Testing Basics
● Tests should run quickly (and automatically)
● Tests should be isolated - know what you’re testing!
● Unit Tests: Test a single ‘unit’ of code
● Integration Tests: Test interactions between units
● Acceptance Tests: Test that code does what we want
Minimal Testing
$ salt-call state.highstate test=True
● Better than blindly applying
states
● Still not what we’re looking for
○ Manual
○ Slow
○ No isolation
○ Error-prone (“Oops, I
didn’t see the red line!”)
First Improvement
Test states individually:
$ salt-call state.sls foo test=True
● Slight improvement
○ More isolation
○ Faster than highstate
● Still not what we want
Testing Basic Syntax of SLS Files
● First Attempt: Verify SLS files are valid YAML
○ Problem: Only works for very basic states - Jinja breaks the test!
○ Problem: What about other renderers?
●
● Improvement: Test that Salt can render the SLS file
○ “salt-call state.sls foo test=True” works for this
○ Alternative: “salt-call state.show_sls foo”
Testing Basic Syntax
$ salt-call state.sls foo test=True
(with syntax error)
$ salt-call state.show_sls foo
(with syntax error)
Note: Better error message!
Testing Basic Syntax
$ salt-call state.show_sls foo
(no syntax error)
Testing Basic Syntax - Notes
● Salt built-ins are useful!
● Better: A separate tool for validating syntax
(somebody should build one!)
● Don’t forget about outputters:
● salt-call state.show_sls foo --output=json
Testing in Isolation
● We need to be sure that test results are not influenced
by previous tests
● Unit testing frameworks handle this automatically
● Ideal: Create a new, clean infrastructure for each test
○ Problem: Tests must run quickly!
● Solutions:
○ Use VMs (still to slow if we’re running lots of tests)
○ Use Containers (e.g. LXC / Docker)
Docker Containers vs. Full VMs
Docker Pros:
● Easy
● Quick to build and destroy
Docker Cons:
● Missing Functionality (testing services will take
more work)
● Linux only
VM Pros:
● Full OS install - services work / any OS
● Easy to manage if using tools such as Vagrant
● Might be identical to your actual environment
VM Cons:
● Slow(er) to build and destroy
Best Practice: Use both! (For different types of test)
Docker: Quickstart
● Docker makes it easy to build & manage LXC containers
● Allows one to quickly customize existing container images
● Mount host directories in the container
Basic Dockerfile (~/saltpdx/Dockerfile):
FROM phusion/baseimage
RUN sudo add-apt-repository -y ppa:saltstack/salt
RUN sudo apt-get update
RUN sudo apt-get -y install salt-minion
VOLUME ["/etc/salt", "/salt/states", "/salt/pillar"]
CMD salt-call state.highstate
● Build an image (tagged salt/test, version 1):
$ docker build -t ‘salt/test:1’ .
● Start a container using the image:
$ docker run --rm -it -v ~/saltpdx/salt:/etc/salt -v ~/saltpdx/states:/salt/states -v /
~/saltpdx/pillar:/salt/pillar salt/test:1
Docker Quickstart
● Docker creates a container
based on the image
● Host directories are
specified using the -v flag
● Docker starts the container
and runs the CMD specified
in the Dockerfile
● --rm flag tells docker to
delete the container after
the command has run
● -it (or -i -t) for interactive
terminal mode (add
‘/bin/bash’ to end of
command to get a shell)
Docker Tips
● Mount host directories as volumes for:
○ Salt configuration
○ States
○ Pillar
○ Logs?
● Configure containers as salt-masterless to avoid networking & PKI
issues
● Use the --rm flag to automatically delete container instances after
they’ve run
● Tag & version images
Docker: Entrypoint
● When you run a Docker container, Docker executes a binary called ENTRYPOINT
● The CMD that you pass to Docker (via Dockerfile or the cli) is passed as an argument to
the ENTRYPOINT
● By default, Docker will use “/bin/sh -c” as the ENTRYPOINT - this can be overridden
● e.g.:
$ docker run --rm --entrypoint /bin/echo salt/test:1 foo
● We can exploit this to make a simple test runner
● Dockerfile:
FROM phusion/baseimage
RUN sudo add-apt-repository -y ppa:saltstack/salt
RUN sudo apt-get update
RUN sudo apt-get -y install salt-minion
VOLUME ["/etc/salt", "/salt/states", "/salt/pillar"]
ADD test_salt.sh /test_salt.sh
RUN chmod +x /test_salt.sh
ENTRYPOINT ["/bin/bash", "/test_salt.sh"]
Docker: Entrypoint (con’t)
● test_salt.sh:
Docker: Entrypoint (con’t)
After building a new image, we can
run:
$ docker run --rm -v / ~/saltpdx/salt:
/etc/salt -v / ~/saltpdx/states:
/salt/states -v / ~/saltpdx/pillar:
/salt/pillar salt/test:2 / highstate
Which will start a container, run “salt-
call state.highstate”, and exit.
Docker: Entrypoint (con’t)
Or, we can run:
$ docker run --rm -v / ~/saltpdx/salt:
/etc/salt -v / ~/saltpdx/states:
/salt/states -v / ~/saltpdx/pillar:
/salt/pillar salt/test:2 / foo
Which will run “salt-call state.
show_sls foo”, then “salt-call state.sls
foo”, and exit.
Next Step: Automation
● We’ve got the basic tools - the next step is to add some automation
● Host-side automation:
○ Starting and destroying containers
○ Determine what states to test
○ Collect & summarize test results
○ Test various permutations (different Linux version, different
grains, etc.)
● Container-side automation
○ Discover & test sub-components (e.g. file templates)
○ Integration/Acceptance/Behavioral Tests
Automation Overview
● Testing is initiated by running a test-controller script on the host
● The test-controller should:
○ Generate a list of states to test and environment permutations
○ Start a container and trigger the test runner
○ Collect test results
○ Destroy the container
○ Repeat for each state
● The Docker image should have a test-runner script that is used as
the ENTRYPOINT
● The test-runner script should:
○ Determine specific tests to run
○ Run the tests
○ Output Results
Next Time - Part 2
● Actual code for these automation scripts
● Behavioral Testing (for acceptance/integration tests)
● Collecting and Summarizing Results in a useful fashion
● Continuous Integration
● Adding Vagrant VMs for additional tests
● Testing multi-machine infrastructures
● …???
Thanks!
Discussion / Questions?
salt@jasondenning.com
GitHub: jasondenning
Twitter: @jason_denning

More Related Content

ODP
JavaScript Object Oriented Programming Cheat Sheet
PDF
PPT
Java servlets
PDF
Broadcast Receivers in Android
PPT
programming with python ppt
PPT
Power Point Presentation on Open Source Software
PPTX
Introduction to java
PPTX
Loops PHP 04
JavaScript Object Oriented Programming Cheat Sheet
Java servlets
Broadcast Receivers in Android
programming with python ppt
Power Point Presentation on Open Source Software
Introduction to java
Loops PHP 04

What's hot (20)

PPT
Java EE Introduction
PDF
Python Programming Language | Python Classes | Python Tutorial | Python Train...
PPT
Python Programming ppt
PPTX
PDF
How to use github to evaluate developers
PDF
JAX-RS 2.0: RESTful Web Services
PPTX
Java script
PPTX
Introduction to the Python
PDF
HTML CSS Basics
PPT
Java applets
PPTX
Java 9 Module System Introduction
PPSX
Introduction to Java
PPTX
Python Basics
PPTX
PPTX
Java/Servlet/JSP/JDBC
PPT
PHP variables
PPTX
Backend Programming
PPTX
Introduction to Web Architecture
PPTX
Calling SOAP and REST API's from PL/SQL
PPTX
Typescript Fundamentals
Java EE Introduction
Python Programming Language | Python Classes | Python Tutorial | Python Train...
Python Programming ppt
How to use github to evaluate developers
JAX-RS 2.0: RESTful Web Services
Java script
Introduction to the Python
HTML CSS Basics
Java applets
Java 9 Module System Introduction
Introduction to Java
Python Basics
Java/Servlet/JSP/JDBC
PHP variables
Backend Programming
Introduction to Web Architecture
Calling SOAP and REST API's from PL/SQL
Typescript Fundamentals
Ad

Similar to Testing Salt States (part 1) (20)

PPTX
SaltConf2015: SaltStack at Scale Automating Your Automation
PDF
Understanding salt modular sub-systems and customization
PDF
Intelligent infrastructure with SaltStack
PPTX
Automating Your Salt Tests
PDF
Introduction to Systems Management with SaltStack
PDF
Event driven architecture with SaltStack
PDF
SaltStack – (Not) just another Automation & Remote Execution Tool
PDF
Saltstack for Ansible users
PDF
Saltcheck: a tool in the salt toolbox
PPTX
SaltStack Configuration Management
ODP
Configuration Management and Salt
PDF
[TechTalks] Learning Configuration Management with SaltStack (Advanced Concepts)
PDF
Configuration management and orchestration with Salt
PDF
Orchestrate Event-Driven Infrastructure with SaltStack
PPTX
SaltStack Advanced Concepts
PDF
Salt Essentials 1st Edition Craig Sebenik
PDF
Why SaltStack ?
PDF
Containerised Testing at Demonware : PyCon Ireland 2016
PPTX
Salty OPS – Saltstack Introduction
PDF
SaltStack Configuration Management Best Practices
SaltConf2015: SaltStack at Scale Automating Your Automation
Understanding salt modular sub-systems and customization
Intelligent infrastructure with SaltStack
Automating Your Salt Tests
Introduction to Systems Management with SaltStack
Event driven architecture with SaltStack
SaltStack – (Not) just another Automation & Remote Execution Tool
Saltstack for Ansible users
Saltcheck: a tool in the salt toolbox
SaltStack Configuration Management
Configuration Management and Salt
[TechTalks] Learning Configuration Management with SaltStack (Advanced Concepts)
Configuration management and orchestration with Salt
Orchestrate Event-Driven Infrastructure with SaltStack
SaltStack Advanced Concepts
Salt Essentials 1st Edition Craig Sebenik
Why SaltStack ?
Containerised Testing at Demonware : PyCon Ireland 2016
Salty OPS – Saltstack Introduction
SaltStack Configuration Management Best Practices
Ad

Recently uploaded (20)

PDF
project resource management chapter-09.pdf
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
WOOl fibre morphology and structure.pdf for textiles
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Getting Started with Data Integration: FME Form 101
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PPTX
A Presentation on Touch Screen Technology
PDF
Mushroom cultivation and it's methods.pdf
PDF
Encapsulation theory and applications.pdf
PDF
1 - Historical Antecedents, Social Consideration.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Hindi spoken digit analysis for native and non-native speakers
PDF
Enhancing emotion recognition model for a student engagement use case through...
project resource management chapter-09.pdf
Univ-Connecticut-ChatGPT-Presentaion.pdf
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
A comparative analysis of optical character recognition models for extracting...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Web App vs Mobile App What Should You Build First.pdf
WOOl fibre morphology and structure.pdf for textiles
Digital-Transformation-Roadmap-for-Companies.pptx
cloud_computing_Infrastucture_as_cloud_p
Getting Started with Data Integration: FME Form 101
MIND Revenue Release Quarter 2 2025 Press Release
Assigned Numbers - 2025 - Bluetooth® Document
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
A Presentation on Touch Screen Technology
Mushroom cultivation and it's methods.pdf
Encapsulation theory and applications.pdf
1 - Historical Antecedents, Social Consideration.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Hindi spoken digit analysis for native and non-native speakers
Enhancing emotion recognition model for a student engagement use case through...

Testing Salt States (part 1)

  • 1. Testing Salt States: Part 1 The Basics
  • 2. About Me (Jason Denning) • DevOps Engineer • SaltStack user for ~ 3 years • SaltStack Certified Engineer #2 • AWS Certified Architect • OSS Advocate (first Linux install ~ 1998) • Pythonista • jasondenning on GitHub / @jason_denning on Twitter
  • 3. ● Provide analytics and marketing/segmentation tools for mobile app developers ● Hosted backend APIs available world- wide ● Lots of traffic ● Big fans of SaltStack ● upsight.com
  • 4. WARNING: Work In Progress ● Testing infrastructure is not a common practice ● These slides are rough ● Your Mileage May Vary! ● We should work (together) on improving this
  • 5. Why Test? ● DevOps: Infrastructure is code ● Code should be tested ● ⇒ Infrastructure should be tested
  • 6. Why Test? (continued) ● Find errors faster ● Prevent regressions ● Allow others to contribute ● Simplify Code Reviews (CI) ● Improve Documentation
  • 7. What to Test ● Basic Syntax (linting) ● Individual States ● State Relationships ● Different Environments ● As much as possible (within reason)
  • 8. Testing Basics ● Tests should run quickly (and automatically) ● Tests should be isolated - know what you’re testing! ● Unit Tests: Test a single ‘unit’ of code ● Integration Tests: Test interactions between units ● Acceptance Tests: Test that code does what we want
  • 9. Minimal Testing $ salt-call state.highstate test=True ● Better than blindly applying states ● Still not what we’re looking for ○ Manual ○ Slow ○ No isolation ○ Error-prone (“Oops, I didn’t see the red line!”)
  • 10. First Improvement Test states individually: $ salt-call state.sls foo test=True ● Slight improvement ○ More isolation ○ Faster than highstate ● Still not what we want
  • 11. Testing Basic Syntax of SLS Files ● First Attempt: Verify SLS files are valid YAML ○ Problem: Only works for very basic states - Jinja breaks the test! ○ Problem: What about other renderers? ● ● Improvement: Test that Salt can render the SLS file ○ “salt-call state.sls foo test=True” works for this ○ Alternative: “salt-call state.show_sls foo”
  • 12. Testing Basic Syntax $ salt-call state.sls foo test=True (with syntax error) $ salt-call state.show_sls foo (with syntax error) Note: Better error message!
  • 13. Testing Basic Syntax $ salt-call state.show_sls foo (no syntax error)
  • 14. Testing Basic Syntax - Notes ● Salt built-ins are useful! ● Better: A separate tool for validating syntax (somebody should build one!) ● Don’t forget about outputters: ● salt-call state.show_sls foo --output=json
  • 15. Testing in Isolation ● We need to be sure that test results are not influenced by previous tests ● Unit testing frameworks handle this automatically ● Ideal: Create a new, clean infrastructure for each test ○ Problem: Tests must run quickly! ● Solutions: ○ Use VMs (still to slow if we’re running lots of tests) ○ Use Containers (e.g. LXC / Docker)
  • 16. Docker Containers vs. Full VMs Docker Pros: ● Easy ● Quick to build and destroy Docker Cons: ● Missing Functionality (testing services will take more work) ● Linux only VM Pros: ● Full OS install - services work / any OS ● Easy to manage if using tools such as Vagrant ● Might be identical to your actual environment VM Cons: ● Slow(er) to build and destroy Best Practice: Use both! (For different types of test)
  • 17. Docker: Quickstart ● Docker makes it easy to build & manage LXC containers ● Allows one to quickly customize existing container images ● Mount host directories in the container Basic Dockerfile (~/saltpdx/Dockerfile): FROM phusion/baseimage RUN sudo add-apt-repository -y ppa:saltstack/salt RUN sudo apt-get update RUN sudo apt-get -y install salt-minion VOLUME ["/etc/salt", "/salt/states", "/salt/pillar"] CMD salt-call state.highstate ● Build an image (tagged salt/test, version 1): $ docker build -t ‘salt/test:1’ . ● Start a container using the image: $ docker run --rm -it -v ~/saltpdx/salt:/etc/salt -v ~/saltpdx/states:/salt/states -v / ~/saltpdx/pillar:/salt/pillar salt/test:1
  • 18. Docker Quickstart ● Docker creates a container based on the image ● Host directories are specified using the -v flag ● Docker starts the container and runs the CMD specified in the Dockerfile ● --rm flag tells docker to delete the container after the command has run ● -it (or -i -t) for interactive terminal mode (add ‘/bin/bash’ to end of command to get a shell)
  • 19. Docker Tips ● Mount host directories as volumes for: ○ Salt configuration ○ States ○ Pillar ○ Logs? ● Configure containers as salt-masterless to avoid networking & PKI issues ● Use the --rm flag to automatically delete container instances after they’ve run ● Tag & version images
  • 20. Docker: Entrypoint ● When you run a Docker container, Docker executes a binary called ENTRYPOINT ● The CMD that you pass to Docker (via Dockerfile or the cli) is passed as an argument to the ENTRYPOINT ● By default, Docker will use “/bin/sh -c” as the ENTRYPOINT - this can be overridden ● e.g.: $ docker run --rm --entrypoint /bin/echo salt/test:1 foo ● We can exploit this to make a simple test runner ● Dockerfile: FROM phusion/baseimage RUN sudo add-apt-repository -y ppa:saltstack/salt RUN sudo apt-get update RUN sudo apt-get -y install salt-minion VOLUME ["/etc/salt", "/salt/states", "/salt/pillar"] ADD test_salt.sh /test_salt.sh RUN chmod +x /test_salt.sh ENTRYPOINT ["/bin/bash", "/test_salt.sh"]
  • 22. Docker: Entrypoint (con’t) After building a new image, we can run: $ docker run --rm -v / ~/saltpdx/salt: /etc/salt -v / ~/saltpdx/states: /salt/states -v / ~/saltpdx/pillar: /salt/pillar salt/test:2 / highstate Which will start a container, run “salt- call state.highstate”, and exit.
  • 23. Docker: Entrypoint (con’t) Or, we can run: $ docker run --rm -v / ~/saltpdx/salt: /etc/salt -v / ~/saltpdx/states: /salt/states -v / ~/saltpdx/pillar: /salt/pillar salt/test:2 / foo Which will run “salt-call state. show_sls foo”, then “salt-call state.sls foo”, and exit.
  • 24. Next Step: Automation ● We’ve got the basic tools - the next step is to add some automation ● Host-side automation: ○ Starting and destroying containers ○ Determine what states to test ○ Collect & summarize test results ○ Test various permutations (different Linux version, different grains, etc.) ● Container-side automation ○ Discover & test sub-components (e.g. file templates) ○ Integration/Acceptance/Behavioral Tests
  • 25. Automation Overview ● Testing is initiated by running a test-controller script on the host ● The test-controller should: ○ Generate a list of states to test and environment permutations ○ Start a container and trigger the test runner ○ Collect test results ○ Destroy the container ○ Repeat for each state ● The Docker image should have a test-runner script that is used as the ENTRYPOINT ● The test-runner script should: ○ Determine specific tests to run ○ Run the tests ○ Output Results
  • 26. Next Time - Part 2 ● Actual code for these automation scripts ● Behavioral Testing (for acceptance/integration tests) ● Collecting and Summarizing Results in a useful fashion ● Continuous Integration ● Adding Vagrant VMs for additional tests ● Testing multi-machine infrastructures ● …???