{"id":153,"date":"2019-02-21T12:01:00","date_gmt":"2019-02-21T12:01:00","guid":{"rendered":"https:\/\/opstree.com\/blog\/\/2019\/02\/21\/best-practices-of-ansible-role\/"},"modified":"2021-01-04T22:12:21","modified_gmt":"2021-01-04T16:42:21","slug":"best-practices-of-ansible-role","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2019\/02\/21\/best-practices-of-ansible-role\/","title":{"rendered":"Best Practices of Ansible Role"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">I have written about Ansible Roles in my career. But when I talk about the \u201cBest Practice of writing an Ansible Role\u201d, half of them were not following the best practices. <\/span><\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">When I started writing this blog, I had only limited knowledge of Ansible Roles and about the practices being followed. But reading more on Ansible roles has helped in enhancing my knowledge.<\/span><\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">Without the proper understanding of the Architecture of Ansible Role, I was incapable of enjoying all the functionality for writing an Ansible Role. Earlier, I used \u201ccommand\u201d and \u201cshell\u201d modules for writing an Ansible Role.<\/span><span style=\"font-weight:400;\"> Here, in this blog, I&#8217;ve discussed the best practices of Ansible Role. Let&#8217;s <\/span><\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">read these in detail.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<p><!--more--><\/p>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Advantages of Best Practices<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\">\r\n<ul>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Completing the task using Full Functionality.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Vandalized Architecture helps to create Ansible roles as Utilities that can be used further using different values.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Applying best practices helps you to learn new things every day.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Following \u201cConvention Over Configuration\u201d makes your troubleshooting much easier.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Helps you to grow your Automation skills.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">You don\u2019t have to worry about the latest version or change in values ever.<\/span><\/li>\r\n<\/ul>\r\n<span style=\"font-weight:400;\">I can talk about the Advantages of best practices continuously but you should understand it after using them. Now, let\u2019s talk about <\/span><b>\u201cHow to apply them\u201d<\/b><span style=\"font-weight:400;\">.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">F<\/span><span style=\"font-weight:400;\">irst, we will understand the complete directory structure on Ansible Role:<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\">\r\n<ul>\r\n<li style=\"font-weight:400;\"><b>Defaults: <\/b><span style=\"font-weight:400;\">The default variables for the role are stored here inside this directory. These variables have the lowest priority.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><b>Files: <\/b><span style=\"font-weight:400;\">All the static files are being stored here which are used inside the role.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><b>Handlers: <\/b><span style=\"font-weight:400;\">All the handlers are being used here but not inside the Task directory. And automatically called upon from here.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><b>Meta: <\/b><span style=\"font-weight:400;\">This directory contains the metadata about your role regarding the dependencies which are being required to run this role in any system, so it will not be run until the dependencies inside it are not resolved.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><b>Tasks: <\/b><span style=\"font-weight:400;\">This directory contains the main list of the tasks which needs to be executed by the role.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><b>Vars: <\/b><span style=\"font-weight:400;\">This directory has higher precedence than the defaults directory and can only be overwritten by passing them On the command line, In the specific task, or In a block.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><b>Templates: <\/b><span style=\"font-weight:400;\">This directory contains the Jinja templates inside it. Basically, all the variablized templates which are rendered into static files during runtime are stored here.<\/span><\/li>\r\n<\/ul>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5191\" style=\"font-size:inherit;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2020\/12\/image5.png\" alt=\"\" width=\"441\" height=\"514\" \/><\/p>\r\n<h3><b>Whitespace and Comments<\/b><\/h3>\r\n<span style=\"font-weight:400;\">Generous use of whitespace and breaking things up is really appreciated. One very important thing is the use of comments inside your roles so that someone using your role in the future can easily understand it properly.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\"><b style=\"font-size:23px;\">YAML format<\/b><br \/><\/span><span style=\"font-weight:400;\">Learn YAML format properly and use of indentation properly inside the document. Sometimes, when running the role gives the error for Invalid Syntax due to bad indentation format. And writing in proper Indentation makes your role look beautiful.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\"> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5190\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2020\/12\/image4.png\" alt=\"\" width=\"650\" height=\"421\" \/><\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Always Name Tasks<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">It is possible to leave off the \u2018name\u2019 for a given task, though it is recommended to provide a description of something being done instead. This name is shown when that particular task is being run.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\"> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5188\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2020\/12\/image1.png\" alt=\"\" width=\"650\" height=\"315\" \/><\/span><span style=\"font-weight:400;\">\u00a0<\/span><\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Version Control<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">Use version control. Keep your roles and inventory files in git and commit when you make changes to them. This way you have an audit trail describing when and why you changed the rules that are automating your infrastructure.<\/span><\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5189\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2020\/12\/image3.png\" alt=\"\" width=\"650\" height=\"413\" \/> <\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Variable and Vaults<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">Since the variable contains sensitive data, so it is often easier to find variables using grep or similar tools inside the Ansible system. Since vaults obscure these variables, it is best to work with a layer of Indirection. This allows Ansible to find the variables inside the unencrypted file and all sensitive variables come from an encrypted file.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">The best approach to perform is to start with a group_vars subdirectory containing two more subdirectories inside it naming <\/span><b>\u201cVars\u201d <\/b><span style=\"font-weight:400;\">and <\/span><b>\u201cVaults\u201d<\/b><span style=\"font-weight:400;\">. Inside the <\/span><b>\u201cVars\u201d <\/b><span style=\"font-weight:400;\">\u00a0directory, define all the variables including sensitive variables also. Now, copy those sensitive variables inside the <\/span><b>\u201cVault\u201d <\/b><span style=\"font-weight:400;\">directory while using the prefix <\/span><b>\u201cvault_*\u201d<\/b><span style=\"font-weight:400;\"> for the variables. Now you should adjust the variables in the <\/span><b>\u201cVars\u201d <\/b><span style=\"font-weight:400;\">to point the matching <\/span><b>\u201cvault_*\u201d <\/b><span style=\"font-weight:400;\">variables using jinja2 syntax and ensure that the vault file is vault encrypted.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Roles for multiple OS<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">Roles should be written in a way that they can run on multiple Operating systems. Try to make your roles as generic as you can. But if you have created a role for some specific kind of operating system or some specific application, then try to explicitly define that inside the role name.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Single role Single goal<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><span style=\"font-weight:400;\">Avoid tasks within a role that are not related to each other. Don\u2019t build a common role. It\u2019s ugly and bad for the readability of your role.<\/span><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><b>Other Tips:<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\">\r\n<ul>\r\n<li><span style=\"font-weight:400;\">Use a module if available<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Try not to use command or shell module<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Use the state parameter<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Prefer scalar variables<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Set default for every variable<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">If you have multiple roles related to each other than try to create a common variable file for all of them which will be called inside your playbook<\/span><\/li>\r\n<\/ul>\r\n<ul>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Use \u201c<\/span><b>copy<\/b><span style=\"font-weight:400;\">\u201d or \u201ctemplate\u201d module instead of \u201c<\/span><b>lineinfile<\/b><span style=\"font-weight:400;\">\u201d module<\/span><\/li>\r\n<\/ul>\r\n<ul>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Make role fully variablized<\/span><\/li>\r\n<\/ul>\r\n<ul>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Be explicit when writing tasks. Suppose, if you are creating a file or directory then instead of defining src and destination, try to define owner, group, mode, etc.<\/span><\/li>\r\n<\/ul>\r\n<b>Summary:<\/b><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\">\r\n<ul>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Create a Role that could be used further.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Create it using proper modules for better understanding.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Do proper comments inside it so that it would be understood by someone else also.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Use proper Indentation for the YAML format.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Create your Role variables and also secure them using a vault.<\/span><\/li>\r\n<li style=\"font-weight:400;\"><span style=\"font-weight:400;\">Create a Single role for a single goal.<\/span><\/li>\r\n<\/ul>\r\nOpstree is an End to End DevOps solution provider<\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>\r\n<div dir=\"ltr\" style=\"text-align:left;\"><!-- \/wp:paragraph -->\r\n\r\n<!-- wp:paragraph --> <a href=\"https:\/\/www.opstree.com\/contact-us\" target=\"_blank\" rel=\"noreferrer noopener\">CONTACT US<\/a><\/div>\r\n<div dir=\"ltr\">\u00a0<\/div>","protected":false},"excerpt":{"rendered":"<p>I have written about Ansible Roles in my career. But when I talk about the \u201cBest Practice of writing an Ansible Role\u201d, half of them were not following the best practices. When I started writing this blog, I had only limited knowledge of Ansible Roles and about the practices being followed. But reading more on &hellip; <a href=\"https:\/\/opstree.com\/blog\/2019\/02\/21\/best-practices-of-ansible-role\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Best Practices of Ansible Role&#8221;<\/span><\/a><\/p>\n","protected":false},"author":172651618,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[4011177,28070474],"tags":[768739304,23122,2185,36382],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-2t","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/153"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/172651618"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=153"}],"version-history":[{"count":24,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/153\/revisions"}],"predecessor-version":[{"id":5326,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/153\/revisions\/5326"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}