There are tons of new tools being released for AWS every single day. But even with all that innovation, the simple fact is that you can’t always rely on the tools someone else has built; sometimes you’ve got to dive in and build your own. It may sound daunting, but there’s a lot of help out there.
The Ansible community on GitHub is always available for suggestions and advice (and to yell at you if you aren’t playing by the rules!). The upside of building your own modules is significant, though: with customized tools tailored to your exact needs, you’ll be able to streamline the automated processes even more than before.
For example, I recently needed a module for creating Application Load Balancers (ALBs). I tried using shell commands to initialize the Command Line Interface (CLI), but the process was prone to issues due to the lack of error handling, making it less “automatic” and more “manual.” So I set about creating a new Ansible module. Modules are standalone scripts that allow Ansible to run and manage remote machines. These modules can be called repeatedly throughout multiple Ansible playbooks—the configuration, deployment, and orchestration language Ansible uses.
Ansible Playbooks & Modules
Each Ansible playbook describes a policy you want a remote machine to invoke while being used to manage the configuration and deployment of remote resources. They can do a lot more, though. Playbooks also allow for sequencing multi-tier rollouts (involving rolling updates) or even delegating actions to other hosts, all while interacting with monitoring services and load balancers. It’s pretty awesome, once you get the hang of it.
Ansible modules are the functional code blocks which serve as the tools in your Ansible playbook. Think of it this way: playbooks are the instruction manual, and modules are your toolset. More specifically, modules are reusable standalone scripts that can be used by the Ansible API, or any scripts that can be used in a series to construct your playbooks.
Why I Love Ansible for Automation
Ansible is a powerful open-source automation engine which allows for software provisioning, configuration management, and application deployment. Ansible runs a variety of automation tools to scale your infrastructure with your business’s growth and the shifting demands of your users on your application.
What differentiates Ansible from other automation tools such as Puppet or Chef is its flexibility. Ansible allows conditional coding and works across a variety of platforms, which is essential for automating releases so you can save time, money and resources by removing that pesky error-prone human factor. Automating is also the key to scalability.
Ansible allows you to manage remote resources without copying and pasting code over and over again, thus letting you reuse modules to simplify complex workflows or configurations. While, the CLI will run changes every time, Ansible will only make changes when they are needed. (If you’ve spent any time building your own CLI modules, you’re probably doing your happy dance right now thinking about reuse!)
This is because Ansible is idempotent, meaning that the results of performing an operation once should be the same as performing the operation repeatedly, without any intervening actions. This is great time-saving tool since you won’t need to manually detect changes or worry about instability in outcomes.
More than that, Ansible’s playbooks are developed in basic text and expressed in YAML, which, compared to Chef’s Ruby and Puppet’s proprietary language, makes rolling out changes much easier and faster. A recent project I did required 6 months to configure the management of a package installation along with configuring all the changes on a number of servers with Chef. With Ansible, we did it in a single day.
Like everything, Ansible isn’t a magical fix-all elixir, but its incredible flexibility and ease of use far outweigh its limitations.
Getting Started with Custom Ansible Modules
The first thing to do is to see what already exists. Head over to GitHub and see if someone has already done what you’re looking to do, or done something close that you can modify. You don’t have to find the perfect, bug-free solution; you’re just looking for the starting point that gets you past the empty editor window.
Whether you’re modifying a module or starting from scratch, keep these guidelines and best practices in mind. The Ansible community on GitHub is an amazing resource, and people are happy to help you solve your problem as long as you play by the rules.
So keep all this in mind and start automating:
- Coding Standards: Ansible has a lot of coding standards. Follow them. It’s a heck of a lot more efficient for everyone in the long run.
- Reviewing Code: Ansible automatically alerts you on testing standards for unit tests, which facilitates code reviews.
- The Importance of Aliases: Use common and consistent aliases across your modules (name, source, destination etc.).
- Give Back to the Community: If you want to contribute your modules for Ansible to deploy and package, make sure each is a single-script—no zip files, no helper scripts, just one single file!
- Modules should only return in JSON, with no standard errors or tracebacks:
- All errors must be handled with only JSON files going out.
- Help yourself out by configuring your module to give helpful errors like “incorrectly formatted variable” or “can’t set X because Y is wrong.”
If you’re new to all this, writing custom Ansible modules can seem overwhelming, but the payoff is well worth that initial learning curve. Use the GitHub community, and if you have any questions, feel free to drop us a line in the Contact form below.