{"id":42352,"date":"2023-01-22T01:55:27","date_gmt":"2022-12-10T14:36:21","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/"},"modified":"2024-04-29T10:49:37","modified_gmt":"2024-04-29T02:49:37","slug":"ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/","title":{"rendered":"Ansible lint\u547d\u4ee4\u7684\u9009\u9879"},"content":{"rendered":"<p>\u672c\u6587\u662fAnsible lint Advent Calendar 2022\u7684\u7b2c\u4e8c\u7bc7\u6587\u7ae0\u3002<\/p>\n<p>\u8fd9\u6b21\u6211\u4eec\u5c06\u89e3\u91ca\u4e00\u4e0bAnsible lint\u547d\u4ee4\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>ansible-lint <span class=\"nt\">--help<\/span>\r\nusage: ansible-lint <span class=\"o\">[<\/span><span class=\"nt\">-h<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">-L<\/span> | <span class=\"nt\">-T<\/span><span class=\"o\">]<\/span>\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">-f<\/span> <span class=\"o\">{<\/span>rich,plain,md,json,codeclimate,quiet,pep8,sarif,docs<span class=\"o\">}]<\/span>\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">-q<\/span><span class=\"o\">]<\/span>\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">-P<\/span> <span class=\"o\">[{<\/span>min,basic,moderate,safety,shared,production<span class=\"o\">}<\/span> ...]]\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">-p<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">--progressive<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">--project-dir<\/span> PROJECT_DIR]\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">-r<\/span> RULESDIR] <span class=\"o\">[<\/span><span class=\"nt\">-R<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">-s<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">--write<\/span> <span class=\"o\">[<\/span>WRITE_LIST]]\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">--show-relpath<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">-t<\/span> TAGS] <span class=\"o\">[<\/span><span class=\"nt\">-v<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">-x<\/span> SKIP_LIST]\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">-w<\/span> WARN_LIST] <span class=\"o\">[<\/span><span class=\"nt\">--enable-list<\/span> ENABLE_LIST] <span class=\"o\">[<\/span><span class=\"nt\">--nocolor<\/span><span class=\"o\">]<\/span>\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">--force-color<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">--exclude<\/span> EXCLUDE_PATHS] <span class=\"o\">[<\/span><span class=\"nt\">-c<\/span> CONFIG_FILE]\r\n                    <span class=\"o\">[<\/span><span class=\"nt\">--offline<\/span><span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nt\">--version<\/span><span class=\"o\">]<\/span>\r\n                    <span class=\"o\">[<\/span>lintables ...]\r\n\r\npositional arguments:\r\n  lintables             One or more files or paths. When missing it will\r\n                        <span class=\"nb\">enable <\/span>auto-detection mode.\r\n\r\noptions:\r\n  <span class=\"nt\">-h<\/span>, <span class=\"nt\">--help<\/span>            show this <span class=\"nb\">help <\/span>message and <span class=\"nb\">exit<\/span>\r\n  <span class=\"nt\">-L<\/span>, <span class=\"nt\">--list-rules<\/span>      List all the rules. For listing rules only the\r\n                        following formats <span class=\"k\">for <\/span>argument <span class=\"nt\">-f<\/span> are supported:\r\n                        <span class=\"o\">{<\/span>plain, rich, md<span class=\"o\">}<\/span>\r\n  <span class=\"nt\">-T<\/span>, <span class=\"nt\">--list-tags<\/span>       List all the tags and the rules they cover. Increase\r\n                        the verbosity level with <span class=\"sb\">`<\/span><span class=\"nt\">-v<\/span><span class=\"sb\">`<\/span> to include <span class=\"s1\">'opt-in'<\/span> tag\r\n                        and its rules.\r\n  <span class=\"nt\">-f<\/span> <span class=\"o\">{<\/span>rich,plain,md,json,codeclimate,quiet,pep8,sarif,docs<span class=\"o\">}<\/span>, <span class=\"nt\">--format<\/span> <span class=\"o\">{<\/span>rich,plain,md,json,codeclimate,quiet,pep8,sarif,docs<span class=\"o\">}<\/span>\r\n                        stdout formatting, json being an <span class=\"nb\">alias <\/span><span class=\"k\">for\r\n                        <\/span>codeclimate. <span class=\"o\">(<\/span>default: rich<span class=\"o\">)<\/span>\r\n  <span class=\"nt\">-q<\/span>                    quieter, reduce verbosity, can be specified twice.\r\n  <span class=\"nt\">-P<\/span> <span class=\"o\">[{<\/span>min,basic,moderate,safety,shared,production<span class=\"o\">}<\/span> ...], <span class=\"nt\">--profile<\/span> <span class=\"o\">[{<\/span>min,basic,moderate,safety,shared,production<span class=\"o\">}<\/span> ...]\r\n                        Specify which rules profile to be used, or displays\r\n                        available profiles when no argument is given.\r\n  <span class=\"nt\">-p<\/span>, <span class=\"nt\">--parseable<\/span>       parseable output, same as <span class=\"s1\">'-f pep8'<\/span>\r\n  <span class=\"nt\">--progressive<\/span>         Return success <span class=\"k\">if <\/span>it detects a reduction <span class=\"k\">in <\/span>number of\r\n                        violations compared with previous git commit. This\r\n                        feature works only <span class=\"k\">in <\/span>git repositories.\r\n  <span class=\"nt\">--project-dir<\/span> PROJECT_DIR\r\n                        Location of project\/repository, autodetected based on\r\n                        location of configuration file.\r\n  <span class=\"nt\">-r<\/span> RULESDIR, <span class=\"nt\">--rules-dir<\/span> RULESDIR\r\n                        Specify custom rule directories. Add <span class=\"nt\">-R<\/span> to keep using\r\n                        embedded rules from \/home\/docs\/checkouts\/readthedocs.o\r\n                        rg\/user_builds\/ansible-\r\n                        lint\/envs\/latest\/lib\/python3.10\/site-\r\n                        packages\/ansiblelint\/rules\r\n  <span class=\"nt\">-R<\/span>                    Keep default rules when using <span class=\"nt\">-r<\/span>\r\n  <span class=\"nt\">-s<\/span>, <span class=\"nt\">--strict<\/span>          Return non-zero <span class=\"nb\">exit <\/span>code on warnings as well as\r\n                        errors\r\n  <span class=\"nt\">--write<\/span> <span class=\"o\">[<\/span>WRITE_LIST]  Allow ansible-lint to reformat YAML files and run rule\r\n                        transforms <span class=\"o\">(<\/span>Reformatting YAML files standardizes\r\n                        spacing, quotes, etc. A rule transform can fix or\r\n                        simplify fixing issues identified by that rule<span class=\"o\">)<\/span><span class=\"nb\">.<\/span> You\r\n                        can limit the effective rule transforms <span class=\"o\">(<\/span>the\r\n                        <span class=\"s1\">'write_list'<\/span><span class=\"o\">)<\/span> by passing a keywords <span class=\"s1\">'all'<\/span> or <span class=\"s1\">'none'<\/span> or\r\n                        a comma separated list of rule ids or rule tags. YAML\r\n                        reformatting happens whenever <span class=\"s1\">'--write'<\/span> or <span class=\"s1\">'--write='<\/span>\r\n                        is used. <span class=\"s1\">'--write'<\/span> and <span class=\"s1\">'--write=all'<\/span> are equivalent:\r\n                        they allow all transforms to run. The effective list\r\n                        of transforms comes from <span class=\"s1\">'write_list'<\/span> <span class=\"k\">in <\/span>the config\r\n                        file, followed whatever <span class=\"s1\">'--write'<\/span> args are provided on\r\n                        the commandline. <span class=\"s1\">'--write=none'<\/span> resets the list of\r\n                        transforms to allow reformatting YAML without running\r\n                        any of the transforms <span class=\"o\">(<\/span>ie <span class=\"s1\">'--write=none,rule-id'<\/span> will\r\n                        ignore write_list <span class=\"k\">in <\/span>the config file and only run the\r\n                        rule-id transform<span class=\"o\">)<\/span><span class=\"nb\">.<\/span>\r\n  <span class=\"nt\">--show-relpath<\/span>        Display path relative to CWD\r\n  <span class=\"nt\">-t<\/span> TAGS, <span class=\"nt\">--tags<\/span> TAGS  only check rules whose <span class=\"nb\">id<\/span>\/tags match these values\r\n  <span class=\"nt\">-v<\/span>                    Increase verbosity level <span class=\"o\">(<\/span><span class=\"nt\">-vv<\/span> <span class=\"k\">for <\/span>more<span class=\"o\">)<\/span>\r\n  <span class=\"nt\">-x<\/span> SKIP_LIST, <span class=\"nt\">--skip-list<\/span> SKIP_LIST\r\n                        only check rules whose <span class=\"nb\">id<\/span>\/tags <span class=\"k\">do <\/span>not match these\r\n                        values\r\n  <span class=\"nt\">-w<\/span> WARN_LIST, <span class=\"nt\">--warn-list<\/span> WARN_LIST\r\n                        only warn about these rules, unless overridden <span class=\"k\">in\r\n                        <\/span>config file. Current version default value is: avoid-\r\n                        implicit, experimental, fqcn[action], fqcn[redirect],\r\n                        jinja[spacing], name[casing], name[play], role-name,\r\n                        warning[empty-playbook], role-name[path]\r\n  <span class=\"nt\">--enable-list<\/span> ENABLE_LIST\r\n                        activate optional rules by their tag name\r\n  <span class=\"nt\">--nocolor<\/span>             disable colored output, same as <span class=\"nv\">NO_COLOR<\/span><span class=\"o\">=<\/span>1\r\n  <span class=\"nt\">--force-color<\/span>         Force colored output, same as <span class=\"nv\">FORCE_COLOR<\/span><span class=\"o\">=<\/span>1\r\n  <span class=\"nt\">--exclude<\/span> EXCLUDE_PATHS\r\n                        path to directories or files to skip. This option is\r\n                        repeatable.\r\n  <span class=\"nt\">-c<\/span> CONFIG_FILE, <span class=\"nt\">--config-file<\/span> CONFIG_FILE\r\n                        Specify configuration file to use. By default it will\r\n                        look <span class=\"k\">for<\/span> <span class=\"s1\">'.ansible-lint'<\/span> or <span class=\"s1\">'.config\/ansible-lint.yml'<\/span>\r\n  <span class=\"nt\">--offline<\/span>             Disable installation of requirements.yml\r\n  <span class=\"nt\">--version<\/span>\r\n<\/code><\/pre>\n<h3>\u57fa\u672c\u7684\u547d\u4ee4 de<\/h3>\n<pre class=\"post-pre\"><code>ansible-lint &lt;\u30d5\u30a1\u30a4\u30eb\u540d&gt;\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6587\u4ef6\u540d\u88ab\u7701\u7565\uff0cAnsible lint\u4f1a\u81ea\u52a8\u68c0\u6d4bplaybook\u3001role\u3001collection\u7b49\u6587\u4ef6\uff0c\u5e76\u6267\u884clint\u5904\u7406\u3002<\/p>\n<h3>\u663e\u793a\u6240\u6709\u89c4\u5219\u3010-L\uff0c&#8211;list-rules\u3011\u3002<\/h3>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">-L<\/span>\r\n<span class=\"c\">## \u3082\u3057\u304f\u306f <\/span>\r\n<span class=\"c\">## ansible-lint --list-rules<\/span>\r\n<\/code><\/pre>\n<details>\u60c5\u5831\u91cf\u304c\u591a\u3044\u3067\u3059\u3002<br \/>\navoid-implicit \u2502 Avoid implicit behaviors<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # avoid-implicit<br \/>\n\u2502<br \/>\n\u2502 This rule identifies the use of dangerous implicit behaviors, often also undocumented.<br \/>\n\u2502<br \/>\n\u2502 This rule will produce the following type of error messages:<br \/>\n\u2502<br \/>\n\u2502 \u2022 avoid-implicit[copy-content] is not a string as copy modules also accept these, but without<br \/>\n\u2502 documenting them.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Write file content<br \/>\n\u2502 ansible.builtin.copy:<br \/>\n\u2502 content: { &#8220;foo&#8221;: &#8220;bar&#8221; } # &lt;&#8211; should use explicit jinja template<br \/>\n\u2502 dest: \/tmp\/foo.txt<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Write file content<br \/>\n\u2502 vars:<br \/>\n\u2502 content: { &#8220;foo&#8221;: &#8220;bar&#8221; }<br \/>\n\u2502 ansible.builtin.copy:<br \/>\n\u2502 content: &#8220;{{ content | to_json }}&#8221; # explicit better than implicit!<br \/>\n\u2502 dest: \/tmp\/foo.txt<br \/>\nversion_added \u2502 v6.8.0<br \/>\ntags \u2502 unpredictability, experimental<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\ncommand-instead-of-module \u2502 Using command rather than module.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # command-instead-of-module<br \/>\n\u2502<br \/>\n\u2502 This rule will recommend you to use a specific ansible module instead for tasks that are better served<br \/>\n\u2502 by a module, as these are more reliable, provide better messaging and usually have additional features<br \/>\n\u2502 like the ability to retry.<br \/>\n\u2502<br \/>\n\u2502 In the unlikely case that the rule triggers false positives, you can disable it by adding a comment like<br \/>\n\u2502 # noqa: command-instead-of-module to the same line.<br \/>\n\u2502<br \/>\n\u2502 You can check the source of the rule for all the known commands that trigger the rule and their allowed<br \/>\n\u2502 list arguments of exceptions and raise a pull request to improve them.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Update apt cache<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Run apt-get update<br \/>\n\u2502 ansible.builtin.command: apt-get update # &lt;&#8211; better to use ansible.builtin.apt module<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Update apt cache<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Run apt-get update<br \/>\n\u2502 ansible.builtin.apt:<br \/>\n\u2502 update_cache: true<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 command-shell, idiom<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\ncommand-instead-of-shell \u2502 Use shell only when shell functionality is required.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # command-instead-of-shell<br \/>\n\u2502<br \/>\n\u2502 This rule identifies uses of shell modules instead of a command one when this is not really needed.<br \/>\n\u2502 Shell is considerably slower than command and should be avoided unless there is a special need for using<br \/>\n\u2502 shell features, like environment variable expansion or chaining multiple commands using pipes.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Problematic example<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Echo a message<br \/>\n\u2502 ansible.builtin.shell: echo hello # &lt;&#8211; command is better in this case<br \/>\n\u2502 changed_when: false<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Correct example<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Echo a message<br \/>\n\u2502 ansible.builtin.command: echo hello<br \/>\n\u2502 changed_when: false<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 command-shell, idiom<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\ndeprecated-bare-vars \u2502 Using bare variables is deprecated.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # deprecated-bare-vars<br \/>\n\u2502<br \/>\n\u2502 This rule identifies possible confusing expressions where it is not clear if a variable or string is to<br \/>\n\u2502 be used and asks for clarification.<br \/>\n\u2502<br \/>\n\u2502 You should either use the full variable syntax (&#8216;{{{{ {0} }}}}&#8217;) or, whenever possible, convert it to a<br \/>\n\u2502 list of strings.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;{{ item }}&#8221;<br \/>\n\u2502 with_items: foo # &lt;&#8211; deprecated-bare-vars<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 # if foo is not really a variable:<br \/>\n\u2502 &#8211; ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;{{ item }}&#8221;<br \/>\n\u2502 with_items:<br \/>\n\u2502 &#8211; foo<br \/>\n\u2502<br \/>\n\u2502 # if foo is a variable:<br \/>\n\u2502 &#8211; ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;{{ item }}&#8221;<br \/>\n\u2502 with_items: &#8220;{{ foo }}&#8221;<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 deprecations<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\ndeprecated-command-syntax \u2502 Using command rather than an argument to e.g. file.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # deprecated-command-syntax<br \/>\n\u2502<br \/>\n\u2502 This rule identifies the use of shorthand (free-form) syntax as this is highly discouraged inside<br \/>\n\u2502 playbooks, mainly because it can easily lead to bugs that are hard to identify.<br \/>\n\u2502<br \/>\n\u2502 While using the free-form from the command line is ok, it should never be used inside playbooks.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Perform chmod<br \/>\n\u2502 ansible.builtin.command: creates=B chmod 644 A # &lt;&#8211; do not use shorthand<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Perform chmod<br \/>\n\u2502 ansible.builtin.command: chmod 644 A<br \/>\n\u2502 args:<br \/>\n\u2502 creates: B<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 command-shell, deprecations<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\ndeprecated-local-action \u2502 Do not use &#8216;local_action&#8217;, use &#8216;delegate_to: localhost&#8217;.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # deprecated-local-action<br \/>\n\u2502<br \/>\n\u2502 This rule recommends using delegate_to: localhost instead of the local_action.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Task example<br \/>\n\u2502 local_action: # &lt;&#8211; this is deprecated<br \/>\n\u2502 module: boto3_facts<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Task example<br \/>\n\u2502 boto3_facts:<br \/>\n\u2502 delegate_to: localhost # &lt;&#8211; recommended way to run on localhost<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 deprecations<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\ndeprecated-module \u2502 Deprecated module.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # deprecated-module<br \/>\n\u2502<br \/>\n\u2502 This rule identifies deprecated modules in playbooks. You should avoid using deprecated modules because<br \/>\n\u2502 they are not maintained, which can pose a security risk. Additionally when a module is deprecated it is<br \/>\n\u2502 available temporarily with a plan for future removal.<br \/>\n\u2502<br \/>\n\u2502 Refer to the Ansible module index for information about replacements and removal dates for deprecated<br \/>\n\u2502 modules.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Configure VLAN ID<br \/>\n\u2502 ansible.netcommon.net_vlan: # &lt;- Uses a deprecated module.<br \/>\n\u2502 vlan_id: 20<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Configure VLAN ID<br \/>\n\u2502 dellemc.enterprise_sonic.sonic_vlans: # &lt;- Uses a platform specific module. \u2502 config: \u2502 &#8211; vlan_id: 20 \u2502 \u2502 (more) version_added \u2502 v4.0.0 tags \u2502 deprecations severity \u2502 HIGH \u2575 \u2577 empty-string-compare \u2502 Don&#8217;t compare to empty string. \u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574 description \u2502 # empty-string-compare \u2502 \u2502 This rule checks for empty string comparison in playbooks. To ensure code clarity you should avoid using \u2502 empty strings in conditional statements with the when clause. \u2502 \u2502 \u2022 Use when: var | length &gt; 0 instead of when: var != &#8220;&#8221;.<br \/>\n\u2502 \u2022 Use when: var | length == 0 instead of when: var == &#8220;&#8221;.<br \/>\n\u2502<br \/>\n\u2502 This is an opt-in rule. You must enable it in your Ansible-lint configuration as follows:<br \/>\n\u2502<br \/>\n\u2502 enable_list:<br \/>\n\u2502 &#8211; empty-string-compare<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Shut down<br \/>\n\u2502 ansible.builtin.command: \/sbin\/shutdown -t now<br \/>\n\u2502 when: ansible_os_family == &#8220;&#8221; # &lt;- Compares with an empty string.<br \/>\n\u2502 &#8211; name: Shut down<br \/>\n\u2502 ansible.builtin.command: \/sbin\/shutdown -t now<br \/>\n\u2502 when: ansible_os_family !=&#8221;&#8221; # &lt;- Compares with an empty string.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Shut down<br \/>\n\u2502 ansible.builtin.shell: |<br \/>\n\u2502 \/sbin\/shutdown -t now<br \/>\n\u2502 echo $var ==<br \/>\n\u2502 when: ansible_os_family<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 idiom, opt-in<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nfqcn \u2502 Use FQCN for builtin actions.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # fqcn<br \/>\n\u2502<br \/>\n\u2502 This rule checks for fully-qualified collection names (FQCN) in Ansible content.<br \/>\n\u2502<br \/>\n\u2502 Declaring an FQCN ensures that an action uses code from the correct namespace. This avoids ambiguity and<br \/>\n\u2502 conflicts that can cause operations to fail or produce unexpected results.<br \/>\n\u2502<br \/>\n\u2502 The fqcn rule has the following checks:<br \/>\n\u2502<br \/>\n\u2502 \u2022 fqcn[action] &#8211; Use FQCN for module actions, such &#8230;<br \/>\n\u2502 \u2022 fqcn[action-core] &#8211; Checks for FQCNs from the ansible.legacy or ansible.builtin collection.<br \/>\n\u2502 \u2022 fqcn[canonical] &#8211; You should use canonical module name &#8230; instead of &#8230;<br \/>\n\u2502<br \/>\n\u2502 In most cases you should declare the `ansible.builtin` collection for internal Ansible actions.<br \/>\n\u2502 You should declare the `ansible.legacy` collection if you use local overrides with actions, such with as<br \/>\n\u2502 the &#8220;shell&#8220; module.<br \/>\n\u2502<br \/>\n\u2502 This rule does not take [`collections`<br \/>\n\u2502 keyword](https:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/collections_using.html#simplifying-module-n\u2026<br \/>\n\u2502 into consideration.<br \/>\n\u2502 The `collections` keyword provided a temporary mechanism transitioning to Ansible 2.9.<br \/>\n\u2502 You should rewrite any content that uses the `collections:` key and avoid it where possible.<br \/>\n\u2502<br \/>\n\u2502 ## Canonical module names<br \/>\n\u2502<br \/>\n\u2502 Canonical module names are also known as resolved module names and they are to be preferred for most<br \/>\n\u2502 cases. Many Ansible modules have multiple aliases and redirects, as these were created over time while<br \/>\n\u2502 the content was refactored. Still, all of them do finally resolve to the same module name, but not<br \/>\n\u2502 without adding some performance overhead. As very old aliases are at some point removed, it makes to<br \/>\n\u2502 just refresh the content to make it point to the current canonical name.<br \/>\n\u2502<br \/>\n\u2502 The only exception for using a canonical name is if your code still needs to be compatible with a very<br \/>\n\u2502 old version of Ansible, one that does not know how to resolve that name. If you find yourself in such a<br \/>\n\u2502 situation, feel free to add this rule to the ignored list.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Create an SSH connection<br \/>\n\u2502 shell: ssh ssh_user@{{ ansible_ssh_host }} # &lt;- Does not use the FQCN for the shell module.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook (1st solution)<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Create an SSH connection<br \/>\n\u2502 # Use the FQCN for the legacy shell module and allow local overrides.<br \/>\n\u2502 ansible.legacy.shell: ssh ssh_user@{{ ansible_ssh_host }} -o IdentityFile=path\/to\/my_rsa<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook (2nd solution)<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Create an SSH connection<br \/>\n\u2502 # Use the FQCN for the builtin shell module.<br \/>\n\u2502 ansible.builtin.shell: ssh ssh_user@{{ ansible_ssh_host }}<br \/>\nversion_added \u2502 v6.8.0<br \/>\ntags \u2502 formatting<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\ngalaxy \u2502 Rule for checking collection version is greater than 1.0.0.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # galaxy<br \/>\n\u2502<br \/>\n\u2502 This rule identifies if the collection version mentioned in galaxy.yml is ideal in terms of the version<br \/>\n\u2502 number being greater than or equal to 1.0.0.<br \/>\n\u2502<br \/>\n\u2502 This rule can produce messages such:<br \/>\n\u2502<br \/>\n\u2502 \u2022 galaxy[version-missing] &#8211; galaxy.yaml should have version tag.<br \/>\n\u2502 \u2022 galaxy[version-incorrect] &#8211; collection version should be greater than or equal to 1.0.0<br \/>\n\u2502<br \/>\n\u2502 If you want to ignore some of the messages above, you can add any of them to the ignore_list.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 # galaxy.yml<br \/>\n\u2502 &#8212;<br \/>\n\u2502 name: foo<br \/>\n\u2502 namespace: bar<br \/>\n\u2502 version: 0.2.3 # &lt;&#8211; collection version should be &gt;= 1.0.0<br \/>\n\u2502 authors:<br \/>\n\u2502 &#8211; John<br \/>\n\u2502 readme: ..\/README.md<br \/>\n\u2502 description: &#8220;&#8230;&#8221;<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 # galaxy.yml<br \/>\n\u2502 &#8212;<br \/>\n\u2502 name: foo<br \/>\n\u2502 namespace: bar<br \/>\n\u2502 version: 1.0.0<br \/>\n\u2502 authors:<br \/>\n\u2502 &#8211; John<br \/>\n\u2502 readme: ..\/README.md<br \/>\n\u2502 description: &#8220;&#8230;&#8221;<br \/>\nversion_added \u2502 v6.6.0 (last update)<br \/>\ntags \u2502 metadata, opt-in, experimental<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nignore-errors \u2502 Use failed_when and specify error conditions instead of using ignore_errors.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # ignore-errors<br \/>\n\u2502<br \/>\n\u2502 This rule checks that playbooks do not use the ignore_errors directive to ignore all errors. Ignoring<br \/>\n\u2502 all errors in a playbook hides actual failures, incorrectly mark tasks as failed, and result in<br \/>\n\u2502 unexpected side effects and behavior.<br \/>\n\u2502<br \/>\n\u2502 Instead of using the ignore_errors: true directive, you should do the following:<br \/>\n\u2502<br \/>\n\u2502 \u2022 Ignore errors only when using the {{ ansible_check_mode }} variable.<br \/>\n\u2502 \u2022 Use register to register errors.<br \/>\n\u2502 \u2022 Use failed_when: and specify acceptable error conditions.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Run apt-get update<br \/>\n\u2502 ansible.builtin.command: apt-get update<br \/>\n\u2502 ignore_errors: true # &lt;- Ignores all errors, including important failures.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Run apt-get update<br \/>\n\u2502 ansible.builtin.command: apt-get update<br \/>\n\u2502 ignore_errors: &#8220;{{ ansible_check_mode }}&#8221; # &lt;- Ignores errors in check mode.<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Run apt-get update<br \/>\n\u2502 ansible.builtin.command: apt-get update<br \/>\n\u2502 ignore_errors: true<br \/>\n\u2502 register: ignore_errors_register # &lt;- Stores errors and failures for evaluation.<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Disable apport<br \/>\n\u2502 become: &#8220;yes&#8221;<br \/>\n\u2502 lineinfile:<br \/>\n\u2502 line: &#8220;enabled=0&#8221;<br \/>\n\u2502 dest: \/etc\/default\/apport<br \/>\n\u2502 mode: 0644<br \/>\n\u2502 state: present<br \/>\n\u2502 register: default_apport<br \/>\n\u2502 failed_when: default_apport.rc !=0 and not default_apport.rc == 257 # &lt;- Defines conditions that<br \/>\n\u2502 constitute a failure.<br \/>\nversion_added \u2502 v5.0.7<br \/>\ntags \u2502 unpredictability, experimental<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\ninline-env-var \u2502 Command module does not accept setting environment variables inline.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # inline-env-var<br \/>\n\u2502<br \/>\n\u2502 This rule checks that playbooks do not set environment variables in the ansible.builtin.command module.<br \/>\n\u2502<br \/>\n\u2502 You should set environment variables with the ansible.builtin.shell module or the environment keyword.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Set environment variable<br \/>\n\u2502 ansible.builtin.command: MY_ENV_VAR=my_value # &lt;- Sets an environment variable in the command<br \/>\n\u2502 module.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Set environment variable<br \/>\n\u2502 ansible.builtin.shell: echo $MY_ENV_VAR<br \/>\n\u2502 environment:<br \/>\n\u2502 MY_ENV_VAR: my_value # &lt;- Sets an environment variable with the environment keyword.<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Set environment variable<br \/>\n\u2502 ansible.builtin.shell: MY_ENV_VAR=my_value # &lt;- Sets an environment variable with the shell<br \/>\n\u2502 module.<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 command-shell, idiom<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\ninternal-error \u2502 Unexpected internal error.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # internal-error<br \/>\n\u2502<br \/>\n\u2502 This error can also be caused by internal bugs but also by custom rules. Instead of just stopping tool<br \/>\n\u2502 execution, we generate the errors and continue processing other files. This allows users to add this<br \/>\n\u2502 rule to their warn_list until the root cause is fixed.<br \/>\n\u2502<br \/>\n\u2502 Keep in mind that once an internal-error is found on a specific file, no other rules will be executed on<br \/>\n\u2502 that same file.<br \/>\n\u2502<br \/>\n\u2502 In almost all cases you will see more detailed information regarding the original error or runtime<br \/>\n\u2502 exception that triggered this rule.<br \/>\n\u2502<br \/>\n\u2502 If these files are broken on purpose, like some test fixtures, you need to add them to the<br \/>\n\u2502 exclude_paths.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Some title {{ # &lt;&#8211; Ansible will not load this invalid jinja template<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks: []<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Some title<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks: []<br \/>\n\u2502<br \/>\n\u2502 ## ERROR! No hosts matched the subscripted pattern<br \/>\n\u2502<br \/>\n\u2502 If you see this error, it means that you tried to index a host group variable that is using an index<br \/>\n\u2502 above its size.<br \/>\n\u2502<br \/>\n\u2502 Instead of doing something like hosts: all[1] which assumes that you have at least two hosts in your<br \/>\n\u2502 current inventory, you better write something like hosts: &#8220;{{ all[1] | default([]) }}, which is safe and<br \/>\n\u2502 do not produce runtime errors. Use safe fallbacks to make your code more resilient.<br \/>\nversion_added \u2502 v5.0.0<br \/>\ntags \u2502 core<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\njinja \u2502 Rule that looks inside jinja2 templates.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # jinja<br \/>\n\u2502<br \/>\n\u2502 This rule can report problems related to jinja2 string templates. The current version can report:<br \/>\n\u2502<br \/>\n\u2502 \u2022 jinja[spacing] when there are no spaces between variables and operators, including filters, like {{<br \/>\n\u2502 var_name | filter }}. This improves readability and makes it less likely to introduce typos.<br \/>\n\u2502 \u2022 jinja[invalid] when the jinja2 template is invalid, like {{ {{ &#8216;1&#8217; }} }}, which would result in a<br \/>\n\u2502 runtime error if you try to use it with Ansible, even if it does pass the Ansible syntax check.<br \/>\n\u2502<br \/>\n\u2502 As jinja2 syntax is closely following Python one we aim to follow black formatting rules. If you are<br \/>\n\u2502 curious how black would reformat a small sniped feel free to visit online black formatter site. Keep in<br \/>\n\u2502 mind to not include the entire jinja2 template, so instead of {{ 1+2==3 }}, do paste only 1+2==3.<br \/>\n\u2502<br \/>\n\u2502 In ansible, changed_when, failed_when, until, when are considered to use implicit jinja2 templating,<br \/>\n\u2502 meaning that they do not require {{ }}. Our rule will suggest the removal of the braces for these<br \/>\n\u2502 fields.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Some task<br \/>\n\u2502 vars:<br \/>\n\u2502 foo: &#8220;{{some|dict2items}}&#8221; # &lt;&#8211; jinja[spacing]<br \/>\n\u2502 bar: &#8220;{{ &amp; }}&#8221; # &lt;&#8211; jinja[invalid]<br \/>\n\u2502 when: &#8220;{{ foo | bool }}&#8221; # &lt;&#8211; jinja[spacing] &#8211; &#8216;when&#8217; has implicit templating<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Some task<br \/>\n\u2502 vars:<br \/>\n\u2502 foo: &#8220;{{ some | dict2items }}&#8221;<br \/>\n\u2502 bar: &#8220;{{ &#8216;&amp;&#8217; }}&#8221;<br \/>\n\u2502 when: foo | bool<br \/>\n\u2502<br \/>\n\u2502 ## Current limitations<br \/>\n\u2502<br \/>\n\u2502 In its current form, this rule presents the following limitations:<br \/>\n\u2502<br \/>\n\u2502 \u2022 Jinja2 blocks that have newlines in them will not be reformatted because we consider that the user<br \/>\n\u2502 deliberately wanted to format them in a particular way.<br \/>\n\u2502 \u2022 Jinja2 blocks that use tilde as a binary operation are ignored because black does not support tilde<br \/>\n\u2502 as a binary operator. Example: {{ a ~ b }}.<br \/>\n\u2502 \u2022 Jinja2 blocks that use dot notation with numbers are ignored because python and black do not allow<br \/>\n\u2502 it. Example: {{ foo.0.bar }}<br \/>\nversion_added \u2502 v6.5.0<br \/>\ntags \u2502 formatting<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nkey-order \u2502 Ensure specific order of keys in mappings.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # key-order<br \/>\n\u2502<br \/>\n\u2502 This rule recommends reordering key names in ansible content to make code easier to maintain and less<br \/>\n\u2502 prone to errors.<br \/>\n\u2502<br \/>\n\u2502 Here are some examples of common ordering checks done for tasks and handlers:<br \/>\n\u2502<br \/>\n\u2502 \u2022 name must always be the first key for plays, tasks and handlers<br \/>\n\u2502 \u2022 on tasks, the block, rescue and always keys must be the last keys, as this would avoid accidental<br \/>\n\u2502 miss-indentation errors between the last task and the parent level.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; hosts: localhost<br \/>\n\u2502 name: This is a playbook # &lt;&#8211; name key should be the first one<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: A block<br \/>\n\u2502 block:<br \/>\n\u2502 &#8211; name: Display a message<br \/>\n\u2502 debug:<br \/>\n\u2502 msg: &#8220;Hello world!&#8221;<br \/>\n\u2502 when: true # &lt;&#8211; when key should be before block<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: This is a playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: A block<br \/>\n\u2502 when: true<br \/>\n\u2502 block:<br \/>\n\u2502 &#8211; name: Display a message<br \/>\n\u2502 debug:<br \/>\n\u2502 msg: &#8220;Hello world!&#8221;<br \/>\n\u2502<br \/>\n\u2502 ## Reasoning<br \/>\n\u2502<br \/>\n\u2502 Making decisions about the optimal order of keys for ansible tasks or plays is no easy task, as we had a<br \/>\n\u2502 huge number of combinations to consider. This is also the reason why we started with a minimal sorting<br \/>\n\u2502 rule (name to be the first), and aimed to gradually add more fields later, and only when we find the<br \/>\n\u2502 proofs that one approach is likely better than the other.<br \/>\n\u2502<br \/>\n\u2502 ### Why I no longer can put when after a block?<br \/>\n\u2502<br \/>\n\u2502 Try to remember that in real life, block\/rescue\/always have the habit to grow due to the number of tasks<br \/>\n\u2502 they host inside, making them exceed what a single screen. This would move the when task further away<br \/>\n\u2502 from the rest of the task properties. A when from the last task inside the block can easily be confused<br \/>\n\u2502 as being at the block level, or the reverse. When tasks are moved from one location to another, there is<br \/>\n\u2502 a real risk of moving the block level when with it.<br \/>\n\u2502<br \/>\n\u2502 By putting the when before the block, we avoid that kind of risk. The same risk applies to any simple<br \/>\n\u2502 property at the task level, so that is why we concluded that the block keys must be the last ones.<br \/>\n\u2502<br \/>\n\u2502 Another common practice was to put tags as the last property. Still, for the same reasons, we decided<br \/>\n\u2502 that they should not be put after block keys either.<br \/>\nversion_added \u2502 v6.6.2<br \/>\ntags \u2502 formatting, experimental<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nlatest \u2502 Result of the command may vary on subsequent runs.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # latest<br \/>\n\u2502<br \/>\n\u2502 The latest rule checks that module arguments like those used for source control checkout do not have<br \/>\n\u2502 arguments that might generate different results based on context.<br \/>\n\u2502<br \/>\n\u2502 This more generic rule replaced two older rules named git-latest and hg-latest.<br \/>\n\u2502<br \/>\n\u2502 We are aware that there are genuine cases where getting the tip of the main branch is not accidental.<br \/>\n\u2502 For these cases, just add a comment such as # noqa: latest to the same line to prevent it from<br \/>\n\u2502 triggering.<br \/>\n\u2502<br \/>\n\u2502 ## Possible errors messages:<br \/>\n\u2502<br \/>\n\u2502 \u2022 latest[git]<br \/>\n\u2502 \u2022 latest[hg]<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example for `latest` rule<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Risky use of git module<br \/>\n\u2502 ansible.builtin.git:<br \/>\n\u2502 repo: &#8220;https:\/\/foosball.example.org\/path\/to\/repo.git&#8221;<br \/>\n\u2502 version: HEAD # &lt;&#8211; HEAD value is triggering the rule<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example for `latest` rule<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Safe use of git module<br \/>\n\u2502 ansible.builtin.git:<br \/>\n\u2502 repo: &#8220;https:\/\/foosball.example.org\/path\/to\/repo.git&#8221;<br \/>\n\u2502 version: abcd1234&#8230; # &lt;&#8211; that is safe<br \/>\nversion_added \u2502 v6.5.2<br \/>\ntags \u2502 idempotency<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nliteral-compare \u2502 Don&#8217;t compare to literal True\/False.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # literal-compare<br \/>\n\u2502<br \/>\n\u2502 This rule checks for literal comparison with the when clause. Literal comparison, like when: var ==<br \/>\n\u2502 True, is unnecessarily complex. Use when: var to keep your playbooks simple.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Print environment variable to stdout<br \/>\n\u2502 ansible.builtin.command: echo $MY_ENV_VAR<br \/>\n\u2502 when: ansible_os_family == True # &lt;- Adds complexity to your playbook.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Print environment variable to stdout<br \/>\n\u2502 ansible.builtin.command: echo $MY_ENV_VAR<br \/>\n\u2502 when: ansible_os_family # &lt;- Keeps your playbook simple.<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 idiom<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nload-failure \u2502 Failed to load or parse file.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # load-failure<br \/>\n\u2502<br \/>\n\u2502 Linter failed to process a YAML file, probably because it is either:<br \/>\n\u2502<br \/>\n\u2502 \u2022 contains unsupported encoding (only UTF-8 is supported)<br \/>\n\u2502 \u2022 not an Ansible file<br \/>\n\u2502 \u2022 it contains some unsupported custom YAML objects (!! prefix)<br \/>\n\u2502 \u2022 it was not able to decrypt an inline !vault block.<br \/>\n\u2502<br \/>\n\u2502 This violation is not skippable, so it cannot be added to the warn_list or the skip_list. If a vault<br \/>\n\u2502 decryption issue cannot be avoided, the offending file can be added to exclude_paths configuration.<br \/>\nversion_added \u2502 v4.3.0<br \/>\ntags \u2502 core, unskippable<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nloop-var-prefix \u2502 Role loop_var should use configured prefix.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # loop-var-prefix<br \/>\n\u2502<br \/>\n\u2502 This rule avoids conflicts with nested looping tasks by configuring a variable prefix with loop_var.<br \/>\n\u2502 Ansible sets item as the loop variable. You can use loop_var to specify a prefix for loop variables and<br \/>\n\u2502 ensure they are unique to each task.<br \/>\n\u2502<br \/>\n\u2502 This rule can produce the following messages:<br \/>\n\u2502<br \/>\n\u2502 \u2022 [loop-var-prefix[missing] &#8211; Replace any unsafe implicit item loop variable by adding loop_var:<br \/>\n\u2502 &#8230;.<br \/>\n\u2502 \u2022 [loop-var-prefix[wrong] &#8211; Ensure loop variables start with .<br \/>\n\u2502<br \/>\n\u2502 This is an opt-in rule. You must enable it in your Ansible-lint configuration as follows:<br \/>\n\u2502<br \/>\n\u2502 enable_list:<br \/>\n\u2502 &#8211; loop-var-prefix<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Does not set a prefix for loop variables.<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 var: item<br \/>\n\u2502 loop:<br \/>\n\u2502 &#8211; foo<br \/>\n\u2502 &#8211; bar # &lt;- These items do not have a unique prefix.<br \/>\n\u2502 &#8211; name: Sets a prefix that is not unique.<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 var: zz_item<br \/>\n\u2502 loop:<br \/>\n\u2502 &#8211; foo<br \/>\n\u2502 &#8211; bar<br \/>\n\u2502 loop_control:<br \/>\n\u2502 loop_var: zz_item # &lt;- This prefix is not unique.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Sets a unique prefix for loop variables.<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 var: zz_item<br \/>\n\u2502 loop:<br \/>\n\u2502 &#8211; foo<br \/>\n\u2502 &#8211; bar<br \/>\n\u2502 loop_control:<br \/>\n\u2502 loop_var: my_prefix # &lt;- Specifies a unique prefix for loop variables.<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\ntags \u2502 idiom<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nmeta-incorrect \u2502 meta\/main.yml default values should be changed.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # meta-incorrect<br \/>\n\u2502<br \/>\n\u2502 This rule checks role metadata for fields with undefined or default values. Always set appropriate<br \/>\n\u2502 values for the following metadata fields in the meta\/main.yml file:<br \/>\n\u2502<br \/>\n\u2502 \u2022 author<br \/>\n\u2502 \u2022 description<br \/>\n\u2502 \u2022 company<br \/>\n\u2502 \u2022 license<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 # Metadata fields for the role contain default values.<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 author: your name<br \/>\n\u2502 description: your role description<br \/>\n\u2502 company: your company (optional)<br \/>\n\u2502 license: license (GPL-2.0-or-later, MIT, etc)<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 author: Leroy Jenkins<br \/>\n\u2502 description: This role will set you free.<br \/>\n\u2502 company: Red Hat<br \/>\n\u2502 license: Apache<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 metadata<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nmeta-no-info \u2502 meta\/main.yml should contain relevant info.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # meta-no-info<br \/>\n\u2502<br \/>\n\u2502 This rule checks role metadata for missing information. Always set appropriate values for the following<br \/>\n\u2502 metadata fields in the meta\/main.yml file, under galaxy_info key:<br \/>\n\u2502<br \/>\n\u2502 \u2022 platforms<br \/>\n\u2502 \u2022 min_ansible_version<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 # The metadata fields for minimum Ansible version and supported platforms are not set.<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 min_ansible_version:<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 min_ansible_version: &#8220;2.8&#8221;<br \/>\n\u2502 platforms:<br \/>\n\u2502 &#8211; name: Fedora<br \/>\n\u2502 versions:<br \/>\n\u2502 &#8211; all<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 metadata<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nmeta-no-tags \u2502 Tags must contain lowercase letters and digits only.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # meta-no-tags<br \/>\n\u2502<br \/>\n\u2502 This rule checks role metadata for tags with special characters. Always use lowercase numbers and<br \/>\n\u2502 letters for tags in the meta\/main.yml file.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 # Metadata tags contain upper-case letters and special characters.<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 galaxy_tags: [MyTag#1, MyTag&amp;^-]<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 # Metadata tags contain only lowercase letters and numbers.<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 galaxy_tags: [mytag1, mytag2]<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 metadata<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nmeta-video-links \u2502 meta\/main.yml video_links should be formatted correctly.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # meta-video-links<br \/>\n\u2502<br \/>\n\u2502 This rule checks formatting for video links in metadata. Always use dictionaries for items in the<br \/>\n\u2502 meta\/main.yml file.<br \/>\n\u2502<br \/>\n\u2502 Items in the video_links section must be in a dictionary and use the following keys:<br \/>\n\u2502<br \/>\n\u2502 \u2022 url<br \/>\n\u2502 \u2022 title<br \/>\n\u2502<br \/>\n\u2502 The value of the url key must be a shared link from YouTube, Vimeo, or Google Drive.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 video_links:<br \/>\n\u2502 &#8211; https:\/\/youtu.be\/this_is_not_a_dictionary # &lt;- Does not use the url key.<br \/>\n\u2502 &#8211; my_bad_key: https:\/\/youtu.be\/aWmRepTSFKs # &lt;- Uses an unsupported key.<br \/>\n\u2502 title: Incorrect key.<br \/>\n\u2502 &#8211; url: www.acme.com\/vid # &lt;- Uses an unsupported url format.<br \/>\n\u2502 title: Incorrect url format.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 video_links:<br \/>\n\u2502 &#8211; url: https:\/\/youtu.be\/aWmRepTSFKs # &lt;- Uses a supported shared link with the url key.<br \/>\n\u2502 title: Correctly formatted video link.<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 metadata<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nname \u2502 Rule for checking task and play names.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # name<br \/>\n\u2502<br \/>\n\u2502 This rule identifies several problems related to the naming of tasks and plays. This is important<br \/>\n\u2502 because these names are the primary way to identify and document executed operations on console, logs or<br \/>\n\u2502 web interface.<br \/>\n\u2502<br \/>\n\u2502 This rule can produce messages such:<br \/>\n\u2502<br \/>\n\u2502 \u2022 name[casing] &#8211; All names should start with an uppercase letter for languages that support it.<br \/>\n\u2502 \u2022 name[missing] &#8211; All tasks should be named.<br \/>\n\u2502 \u2022 name[play] &#8211; All plays should be named.<br \/>\n\u2502 \u2022 name[template] &#8211; Jinja templates should only be at the end of &#8216;name&#8217;. This helps with the<br \/>\n\u2502 identification of tasks inside the source code when they fail. The use of templating inside name keys<br \/>\n\u2502 is discouraged as there are multiple cases where the rendering of the name template is not possible.<br \/>\n\u2502<br \/>\n\u2502 If you want to ignore some of the messages above, you can add any of them to the skip_list.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; hosts: localhost # &lt;&#8211; playbook missing a name key<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: create placefolder file # &lt;&#8211; not starting with a capital letter<br \/>\n\u2502 ansible.builtin.command: touch \/tmp\/.placeholder<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Play for creating playholder<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Create placeholder file<br \/>\n\u2502 ansible.builtin.command: touch \/tmp\/.placeholder<br \/>\nversion_added \u2502 v6.5.0 (last update)<br \/>\ntags \u2502 idiom<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-changed-when \u2502 Commands should not change things if nothing needs doing.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-changed-when<br \/>\n\u2502<br \/>\n\u2502 This rule checks that tasks return changes to results or conditions. Unless tasks only read information,<br \/>\n\u2502 you should ensure that they return changes in the following ways:<br \/>\n\u2502<br \/>\n\u2502 \u2022 Register results or conditions and use the changed_when clause.<br \/>\n\u2502 \u2022 Use the creates or removes argument.<br \/>\n\u2502<br \/>\n\u2502 You should use the when clause to run tasks only if a check returns a particular result.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Does not handle any output or return codes<br \/>\n\u2502 ansible.builtin.command: cat {{ my_file | quote }} # &lt;- Does not handle the command output.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Handle shell output with return code<br \/>\n\u2502 ansible.builtin.command: cat {{ my_file | quote }}<br \/>\n\u2502 register: my_output # &lt;- Registers the command output.<br \/>\n\u2502 changed_when: my_output.rc != 0 # &lt;- Uses the return code to define when the task has changed.<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 command-shell, idempotency<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-free-form \u2502 Rule for detecting discouraged free-form syntax for action modules.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-free-form<br \/>\n\u2502<br \/>\n\u2502 This rule identifies any use of free-form module calling syntax and asks for switching to the full<br \/>\n\u2502 syntax.<br \/>\n\u2502<br \/>\n\u2502 Free-form syntax, also known as inline or shorthand, can produce subtle bugs. It can also prevent<br \/>\n\u2502 editors and IDEs from providing feedback, autocomplete and validation for the edited line.<br \/>\n\u2502<br \/>\n\u2502 As long you just pass a YAML string that contains a `=` character inside as the<br \/>\n\u2502 parameter to the action module name, we consider this as using free-formsyntax.<br \/>\n\u2502 Be sure you pass a dictionary to the module, so the free-form parsing<br \/>\n\u2502 is never triggered.<br \/>\n\u2502<br \/>\n\u2502 As raw module only accepts free-form, we trigger no-free-form[raw] only if we detect the presence of<br \/>\n\u2502 executable= inside raw calls. We advice the explicit use of args: dictionary for configuring the<br \/>\n\u2502 executable to be run.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example with discouraged free-form syntax<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Create a placefolder file<br \/>\n\u2502 ansible.builtin.command: chdir=\/tmp touch foo # &lt;&#8211; don&#8217;t use free-form<br \/>\n\u2502 &#8211; name: Use raw to echo<br \/>\n\u2502 ansible.builtin.raw: executable=\/bin\/bash echo foo # &lt;&#8211; don&#8217;t use executable=<br \/>\n\u2502 changed_when: false<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example that avoids free-form syntax<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Create a placefolder file<br \/>\n\u2502 ansible.builtin.command:<br \/>\n\u2502 cmd: touch foo # &lt;&#8211; ansible will not touch it<br \/>\n\u2502 chdir: \/tmp<br \/>\n\u2502 &#8211; name: Use raw to echo<br \/>\n\u2502 ansible.builtin.raw: echo foo<br \/>\n\u2502 args:<br \/>\n\u2502 executable: \/bin\/bash # &lt;&#8211; explicit is better<br \/>\n\u2502 changed_when: false<br \/>\nversion_added \u2502 v6.8.0<br \/>\ntags \u2502 syntax, risk, experimental<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-handler \u2502 Tasks that run when changed should likely be handlers.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-handler<br \/>\n\u2502<br \/>\n\u2502 This rule checks for the correct handling of changes to results or conditions.<br \/>\n\u2502<br \/>\n\u2502 If a task has a when: result.changed condition, it effectively acts as a handler. The recommended<br \/>\n\u2502 approach is to use notify and move tasks to handlers. If necessary you can silence the rule by add a #<br \/>\n\u2502 noqa: no-handler comment at the end of the line.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example of no-handler rule<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Register result of a task<br \/>\n\u2502 ansible.builtin.copy:<br \/>\n\u2502 dest: &#8220;\/tmp\/placeholder&#8221;<br \/>\n\u2502 content: &#8220;Ansible made this!&#8221;<br \/>\n\u2502 mode: 0600<br \/>\n\u2502 register: result # &lt;&#8211; Registers the result of the task.<br \/>\n\u2502 &#8211; name: Second command to run<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 msg: The placeholder file was modified!<br \/>\n\u2502 when: result.changed # &lt;&#8211; Triggers the no-handler rule.<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 # Optionally silences the rule.<br \/>\n\u2502 when: result.changed # noqa: no-handler<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 The following code includes the same functionality as the problematic code without recording a result<br \/>\n\u2502 variable.<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example of no-handler rule<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Register result of a task<br \/>\n\u2502 ansible.builtin.copy:<br \/>\n\u2502 dest: &#8220;\/tmp\/placeholder&#8221;<br \/>\n\u2502 content: &#8220;Ansible made this!&#8221;<br \/>\n\u2502 mode: 0600<br \/>\n\u2502 notify:<br \/>\n\u2502 &#8211; Second command to run # &lt;&#8211; Handler runs only when the file changes.<br \/>\n\u2502 handlers:<br \/>\n\u2502 &#8211; name: Second command to run<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 msg: The placeholder file was modified!<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 idiom<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-jinja-when \u2502 No Jinja2 in when.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-jinja-when<br \/>\n\u2502<br \/>\n\u2502 This rule checks conditional statements for Jinja expressions in curly brackets {{ }}. Ansible processes<br \/>\n\u2502 conditionals statements that use the when, failed_when, and changed_when clauses as Jinja expressions.<br \/>\n\u2502<br \/>\n\u2502 An Ansible rule is to always use {{ }} except with when keys. Using {{ }} in conditionals creates a<br \/>\n\u2502 nested expression, which is an Ansible anti-pattern and does not produce expected results.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Shut down Debian systems<br \/>\n\u2502 ansible.builtin.command: \/sbin\/shutdown -t now<br \/>\n\u2502 when: &#8220;{{ ansible_facts[&#8216;os_family&#8217;] == &#8216;Debian&#8217; }}&#8221; # &lt;- Nests a Jinja expression in a<br \/>\n\u2502 conditional statement.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Shut down Debian systems<br \/>\n\u2502 ansible.builtin.command: \/sbin\/shutdown -t now<br \/>\n\u2502 when: ansible_facts[&#8216;os_family&#8217;] == &#8220;Debian&#8221; # &lt;- Uses facts in a conditional statement.<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 deprecations<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-log-password \u2502 Password should not be logged.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-log-password<br \/>\n\u2502<br \/>\n\u2502 This rule ensures playbooks do not write passwords to logs when using loops. Always set the no_log: true<br \/>\n\u2502 attribute to protect sensitive data.<br \/>\n\u2502<br \/>\n\u2502 While most Ansible modules mask sensitive data, using secrets inside a loop can result in those secrets<br \/>\n\u2502 being logged. Explicitly adding no_log: true prevents accidentally exposing secrets.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Log user passwords<br \/>\n\u2502 ansible.builtin.user:<br \/>\n\u2502 name: john_doe<br \/>\n\u2502 comment: John Doe<br \/>\n\u2502 uid: 1040<br \/>\n\u2502 group: admin<br \/>\n\u2502 password: &#8220;{{ item }}&#8221;<br \/>\n\u2502 with_items:<br \/>\n\u2502 &#8211; wow<br \/>\n\u2502 no_log: false # &lt;- Sets the no_log attribute to false.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Do not log user passwords<br \/>\n\u2502 ansible.builtin.user:<br \/>\n\u2502 name: john_doe<br \/>\n\u2502 comment: John Doe<br \/>\n\u2502 uid: 1040<br \/>\n\u2502 group: admin<br \/>\n\u2502 password: &#8220;{{ item }}&#8221;<br \/>\n\u2502 with_items:<br \/>\n\u2502 &#8211; wow<br \/>\n\u2502 no_log: true # &lt;- Sets the no_log attribute to a non-false value.<br \/>\nversion_added \u2502 v5.0.9<br \/>\ntags \u2502 opt-in, security, experimental<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-prompting \u2502 Disallow prompting.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-prompting<br \/>\n\u2502<br \/>\n\u2502 This rule checks for vars_prompt or the ansible.builtin.pause module in playbooks. You should enable<br \/>\n\u2502 this rule to ensure that playbooks can run unattended and in CI\/CD pipelines.<br \/>\n\u2502<br \/>\n\u2502 This is an opt-in rule. You must enable it in your Ansible-lint configuration as follows:<br \/>\n\u2502<br \/>\n\u2502 enable_list:<br \/>\n\u2502 &#8211; no-prompting<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 vars_prompt: # &lt;- Prompts the user to input credentials.<br \/>\n\u2502 &#8211; name: username<br \/>\n\u2502 prompt: What is your username?<br \/>\n\u2502 private: false<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: password<br \/>\n\u2502 prompt: What is your password?<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Pause for 5 minutes<br \/>\n\u2502 ansible.builtin.pause:<br \/>\n\u2502 minutes: 5 # &lt;- Pauses playbook execution for a set period of time.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 Correct code for this rule is to omit vars_prompt and the ansible.builtin.pause module from your<br \/>\n\u2502 playbook.<br \/>\nversion_added \u2502 v6.0.3<br \/>\ntags \u2502 opt-in, experimental<br \/>\nseverity \u2502 VERY_LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-relative-paths \u2502 The src argument should not use a relative path.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-relative-paths<br \/>\n\u2502<br \/>\n\u2502 This rule checks for relative paths in the ansible.builtin.copy and ansible.builtin.template modules.<br \/>\n\u2502<br \/>\n\u2502 Relative paths in a task most often direct Ansible to remote files and directories on managed nodes. In<br \/>\n\u2502 the ansible.builtin.copy and ansible.builtin.template modules, the src argument refers to local files<br \/>\n\u2502 and directories on the control node.<br \/>\n\u2502<br \/>\n\u2502 The recommended locations to store files are as follows:<br \/>\n\u2502<br \/>\n\u2502 \u2022 Use the files\/ folder in the playbook or role directory for the copy module.<br \/>\n\u2502 \u2022 Use the templates\/ folder in the playbook or role directory for the template module.<br \/>\n\u2502<br \/>\n\u2502 These folders allow you to omit the path or use a sub-folder when specifying files with the src<br \/>\n\u2502 argument.<br \/>\n\u2502<br \/>\n\u2502 If resources are outside your Ansible playbook or role directory you should use an absolute path with<br \/>\n\u2502 the `src` argument.<br \/>\n\u2502<br \/>\n\u2502 Do not store resources at the same directory level as your Ansible playbook or tasks files.<br \/>\n\u2502 Doing this can result in disorganized projects and cause user confusion when distinguishing between<br \/>\n\u2502 resources of the same type, such as YAML.<br \/>\n\u2502<br \/>\n\u2502 See task paths in the Ansible documentation for more information.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Template a file to \/etc\/file.conf<br \/>\n\u2502 ansible.builtin.template:<br \/>\n\u2502 src: ..\/my_templates\/foo.j2 # &lt;- Uses a relative path in the src argument.<br \/>\n\u2502 dest: \/etc\/file.conf<br \/>\n\u2502 owner: bin<br \/>\n\u2502 group: wheel<br \/>\n\u2502 mode: &#8220;0644&#8221;<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 vars:<br \/>\n\u2502 source_path: ..\/..\/my_templates\/foo.j2 # &lt;- Sets a variable to a relative path.<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Copy a file to \/etc\/file.conf<br \/>\n\u2502 ansible.builtin.copy:<br \/>\n\u2502 src: &#8220;{{ source_path }}&#8221; # &lt;- Uses the variable in the src argument.<br \/>\n\u2502 dest: \/etc\/foo.conf<br \/>\n\u2502 owner: foo<br \/>\n\u2502 group: foo<br \/>\n\u2502 mode: &#8220;0644&#8221;<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Template a file to \/etc\/file.conf<br \/>\n\u2502 ansible.builtin.template:<br \/>\n\u2502 src: foo.j2 # &lt;- Uses a path from inside templates\/ directory.<br \/>\n\u2502 dest: \/etc\/file.conf<br \/>\n\u2502 owner: bin<br \/>\n\u2502 group: wheel<br \/>\n\u2502 mode: &#8220;0644&#8221;<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 vars:<br \/>\n\u2502 source_path: foo.j2 # &lt;- Uses a path from inside files\/ directory.<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Copy a file to \/etc\/file.conf<br \/>\n\u2502 ansible.builtin.copy:<br \/>\n\u2502 src: &#8220;{{ source_path }}&#8221; # &lt;- Uses the variable in the src argument.<br \/>\n\u2502 dest: \/etc\/foo.conf<br \/>\n\u2502 owner: foo<br \/>\n\u2502 group: foo<br \/>\n\u2502 mode: &#8220;0644&#8221;<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 idiom<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-same-owner \u2502 Do not preserve the owner and group when transferring files across hosts.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-same-owner<br \/>\n\u2502<br \/>\n\u2502 This rule checks that the owner and group do not transfer across hosts.<br \/>\n\u2502<br \/>\n\u2502 In many cases the owner and group on remote hosts do not match the owner and group assigned to source<br \/>\n\u2502 files. Preserving the owner and group during transfer can result in errors with permissions or leaking<br \/>\n\u2502 sensitive information.<br \/>\n\u2502<br \/>\n\u2502 When you synchronize files, you should avoid transferring the owner and group by setting owner: false<br \/>\n\u2502 and group: false arguments. When you unpack archives with the ansible.builtin.unarchive module you<br \/>\n\u2502 should set the &#8211;no-same-owner option.<br \/>\n\u2502<br \/>\n\u2502 This is an opt-in rule. You must enable it in your Ansible-lint configuration as follows:<br \/>\n\u2502<br \/>\n\u2502 enable_list:<br \/>\n\u2502 &#8211; no-same-owner<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Synchronize conf file<br \/>\n\u2502 ansible.posix.synchronize:<br \/>\n\u2502 src: \/path\/conf.yaml<br \/>\n\u2502 dest: \/path\/conf.yaml # &lt;- Transfers the owner and group for the file.<br \/>\n\u2502 &#8211; name: Extract tarball to path<br \/>\n\u2502 ansible.builtin.unarchive:<br \/>\n\u2502 src: &#8220;{{ file }}.tar.gz&#8221;<br \/>\n\u2502 dest: \/my\/path\/ # &lt;- Transfers the owner and group for the file.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Synchronize conf file<br \/>\n\u2502 ansible.posix.synchronize:<br \/>\n\u2502 src: \/path\/conf.yaml<br \/>\n\u2502 dest: \/path\/conf.yaml<br \/>\n\u2502 owner: false<br \/>\n\u2502 group: false # &lt;- Does not transfer the owner and group for the file.<br \/>\n\u2502 &#8211; name: Extract tarball to path<br \/>\n\u2502 ansible.builtin.unarchive:<br \/>\n\u2502 src: &#8220;{{ file }}.tar.gz&#8221;<br \/>\n\u2502 dest: \/my\/path\/<br \/>\n\u2502 extra_opts:<br \/>\n\u2502 &#8211; &#8211;no-same-owner # &lt;- Does not transfer the owner and group for the file.<br \/>\ntags \u2502 opt-in<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nno-tabs \u2502 Most files should not contain tabs.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # no-tabs<br \/>\n\u2502<br \/>\n\u2502 This rule checks for the tab character. The \\t tab character can result in unexpected display or<br \/>\n\u2502 formatting issues. You should always use spaces instead of tabs.<br \/>\n\u2502<br \/>\n\u2502 This rule does not trigger alerts for tab characters in the &#8220;ansible.builtin.lineinfile&#8220; module.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Do not trigger the rule<br \/>\n\u2502 ansible.builtin.lineinfile:<br \/>\n\u2502 path: some.txt<br \/>\n\u2502 regexp: &#8216;^\\t$&#8217;<br \/>\n\u2502 line: &#8216;string with \\t inside&#8217;<br \/>\n\u2502 &#8211; name: Trigger the rule with a debug message<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;Using the \\t character can cause formatting issues.&#8221; # &lt;- Includes the tab character.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Do not trigger the no-tabs rule<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;Using space characters avoids formatting issues.&#8221;<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 formatting<br \/>\nseverity \u2502 LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nonly-builtins \u2502 Use only builtin actions.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # only-builtins<br \/>\n\u2502<br \/>\n\u2502 This rule checks that playbooks use actions from the ansible.builtin collection only.<br \/>\n\u2502<br \/>\n\u2502 This is an opt-in rule. You must enable it in your Ansible-lint configuration as follows:<br \/>\n\u2502<br \/>\n\u2502 enable_list:<br \/>\n\u2502 &#8211; only-builtins<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: all<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Deploy a Helm chart for Prometheus<br \/>\n\u2502 kubernetes.core.helm: # &lt;- Uses a non-builtin collection.<br \/>\n\u2502 name: test<br \/>\n\u2502 chart_ref: stable\/prometheus<br \/>\n\u2502 release_namespace: monitoring<br \/>\n\u2502 create_namespace: true<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Run a shell command<br \/>\n\u2502 ansible.builtin.shell: echo This playbook uses actions from the builtin collection only.<br \/>\ntags \u2502 opt-in, experimental<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\npackage-latest \u2502 Package installs should not use latest.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # package-latest<br \/>\n\u2502<br \/>\n\u2502 This rule checks that package managers install software in a controlled, safe manner.<br \/>\n\u2502<br \/>\n\u2502 Package manager modules, such as ansible.builtin.yum, include a state parameter that configures how<br \/>\n\u2502 Ansible installs software. In production environments, you should set state to present and specify a<br \/>\n\u2502 target version to ensure that packages are installed to a planned and tested version.<br \/>\n\u2502<br \/>\n\u2502 Setting state to latest not only installs software, it performs an update and installs additional<br \/>\n\u2502 packages. This can result in performance degradation or loss of service. If you do want to update<br \/>\n\u2502 packages to the latest version, you should also set the update_only parameter to true to avoid<br \/>\n\u2502 installing additional packages.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Install Ansible<br \/>\n\u2502 ansible.builtin.yum:<br \/>\n\u2502 name: ansible<br \/>\n\u2502 state: latest # &lt;- Installs the latest package.<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Install Ansible-lint<br \/>\n\u2502 ansible.builtin.pip:<br \/>\n\u2502 name: ansible-lint<br \/>\n\u2502 args:<br \/>\n\u2502 state: latest # &lt;- Installs the latest package.<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Install some-package<br \/>\n\u2502 ansible.builtin.package:<br \/>\n\u2502 name: some-package<br \/>\n\u2502 state: latest # &lt;- Installs the latest package.<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Install Ansible with update_only to false<br \/>\n\u2502 ansible.builtin.yum:<br \/>\n\u2502 name: sudo<br \/>\n\u2502 state: latest<br \/>\n\u2502 update_only: false # &lt;- Updates and installs packages.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Install Ansible<br \/>\n\u2502 ansible.builtin.yum:<br \/>\n\u2502 name: ansible-2.12.7.0<br \/>\n\u2502 state: present # &lt;- Pins the version to install with yum.<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Install Ansible-lint<br \/>\n\u2502 ansible.builtin.pip:<br \/>\n\u2502 name: ansible-lint<br \/>\n\u2502 args:<br \/>\n\u2502 state: present<br \/>\n\u2502 version: 5.4.0 # &lt;- Pins the version to install with pip.<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Install some-package<br \/>\n\u2502 ansible.builtin.package:<br \/>\n\u2502 name: some-package<br \/>\n\u2502 state: present # &lt;- Ensures the package is installed.<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Update Ansible with update_only to true<br \/>\n\u2502 ansible.builtin.yum:<br \/>\n\u2502 name: sudo<br \/>\n\u2502 state: latest<br \/>\n\u2502 update_only: true # &lt;- Updates but does not install additional packages.<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 idempotency<br \/>\nseverity \u2502 VERY_LOW<br \/>\n\u2575<br \/>\n\u2577<br \/>\nparser-error \u2502 AnsibleParserError.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 Ansible parser fails; this usually indicates an invalid file.<br \/>\nversion_added \u2502 v5.0.0<br \/>\ntags \u2502 core<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\npartial-become \u2502 become_user requires become to work as expected.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # partial-become<br \/>\n\u2502<br \/>\n\u2502 This rule checks that privilege escalation is activated when changing users.<br \/>\n\u2502<br \/>\n\u2502 To perform an action as a different user with the become_user directive, you must set become: true.<br \/>\n\u2502<br \/>\n\u2502 While Ansible inherits have of `become` and `become_user` from upper levels,<br \/>\n\u2502 like play level or command line, we do not look at these values. This rule<br \/>\n\u2502 requires you to be explicit and always define both in the same place, mainly<br \/>\n\u2502 in order to prevent accidents when some tasks are moved from one location to<br \/>\n\u2502 another one.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Start the httpd service as the apache user<br \/>\n\u2502 ansible.builtin.service:<br \/>\n\u2502 name: httpd<br \/>\n\u2502 state: started<br \/>\n\u2502 become_user: apache # &lt;- Does not change the user because &#8220;become: true&#8221; is not set.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Start the httpd service as the apache user<br \/>\n\u2502 ansible.builtin.service:<br \/>\n\u2502 name: httpd<br \/>\n\u2502 state: started<br \/>\n\u2502 become: true # &lt;- Activates privilege escalation.<br \/>\n\u2502 become_user: apache # &lt;- Changes the user with the desired privileges.<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 unpredictability<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nplaybook-extension \u2502 Use &#8220;.yml&#8221; or &#8220;.yaml&#8221; playbook extension.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # playbook-extension<br \/>\n\u2502<br \/>\n\u2502 This rule checks the file extension for playbooks is either .yml or .yaml. Ansible playbooks are<br \/>\n\u2502 expressed in YAML format with minimal syntax.<br \/>\n\u2502<br \/>\n\u2502 The YAML syntax reference provides additional detail.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 This rule is triggered if Ansible playbooks do not have a file extension or use an unsupported file<br \/>\n\u2502 extension such as playbook.json or playbook.xml.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 Save Ansible playbooks as valid YAML with the .yml or .yaml file extension.<br \/>\nversion_added \u2502 v4.0.0<br \/>\ntags \u2502 formatting<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nrisky-file-permissions \u2502 File permissions unset or incorrect.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # risky-file-permissions<br \/>\n\u2502<br \/>\n\u2502 This rule is triggered by various modules that could end up creating new files on disk with permissions<br \/>\n\u2502 that might be too open, or unpredictable. Please read the documentation of each module carefully to<br \/>\n\u2502 understand the implications of using different argument values, as these make the difference between<br \/>\n\u2502 using the module safely or not. The fix depends on each module and also your particular situation.<br \/>\n\u2502<br \/>\n\u2502 Some modules have a create argument that defaults to true. For those you either need to set create:<br \/>\n\u2502 false or provide some permissions like mode: 0600 to make the behavior predictable and not dependent on<br \/>\n\u2502 the current system settings.<br \/>\n\u2502<br \/>\n\u2502 Modules that are checked:<br \/>\n\u2502<br \/>\n\u2502 \u2022 ansible.builtin.assemble<br \/>\n\u2502 \u2022 ansible.builtin.copy<br \/>\n\u2502 \u2022 ansible.builtin.file<br \/>\n\u2502 \u2022 ansible.builtin.get_url<br \/>\n\u2502 \u2022 ansible.builtin.replace<br \/>\n\u2502 \u2022 ansible.builtin.template<br \/>\n\u2502 \u2022 community.general.archive<br \/>\n\u2502 \u2022 community.general.ini_file<br \/>\n\u2502<br \/>\n\u2502 This rule does not take<br \/>\n\u2502 [module_defaults](https:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/playbooks_module_defaults.html)<br \/>\n\u2502 configuration into account.<br \/>\n\u2502 There are currently no plans to implement this feature because changing task location can also change<br \/>\n\u2502 task behavior.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Unsafe example of using ini_file<br \/>\n\u2502 community.general.ini_file:<br \/>\n\u2502 path: foo<br \/>\n\u2502 create: true<br \/>\n\u2502 mode: preserve<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Safe example of using ini_file (1st solution)<br \/>\n\u2502 community.general.ini_file:<br \/>\n\u2502 path: foo<br \/>\n\u2502 create: false # prevents creating a file with potentially insecure permissions<br \/>\n\u2502 mode: preserve<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Safe example of using ini_file (2nd solution)<br \/>\n\u2502 community.general.ini_file:<br \/>\n\u2502 path: foo<br \/>\n\u2502 mode: 0600 # explicitly sets the desired permissions, to make the results predictable<br \/>\n\u2502 mode: preserve<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\nversion_added \u2502 v4.3.0<br \/>\ntags \u2502 unpredictability, experimental<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nrisky-octal \u2502 Octal file permissions must contain leading zero or be a string.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # risky-octal<br \/>\n\u2502<br \/>\n\u2502 This rule checks that octal file permissions either contain a leading zero or are a string value.<br \/>\n\u2502<br \/>\n\u2502 Modules that are checked:<br \/>\n\u2502<br \/>\n\u2502 \u2022 ansible.builtin.assemble<br \/>\n\u2502 \u2022 ansible.builtin.copy<br \/>\n\u2502 \u2022 ansible.builtin.file<br \/>\n\u2502 \u2022 ansible.builtin.replace<br \/>\n\u2502 \u2022 ansible.builtin.template<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Unsafe example of declaring Numeric file permissions<br \/>\n\u2502 ansible.builtin.file:<br \/>\n\u2502 path: \/etc\/foo.conf<br \/>\n\u2502 owner: foo<br \/>\n\u2502 group: foo<br \/>\n\u2502 mode: 644<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Safe example of declaring Numeric file permissions (1st solution)<br \/>\n\u2502 ansible.builtin.file:<br \/>\n\u2502 path: \/etc\/foo.conf<br \/>\n\u2502 owner: foo<br \/>\n\u2502 group: foo<br \/>\n\u2502 mode: 0644 # &lt;- Leading zero will prevent Numeric file permissions to behave in unexpected ways.<br \/>\n\u2502 &#8211; name: Safe example of declaring Numeric file permissions (2nd solution)<br \/>\n\u2502 ansible.builtin.file:<br \/>\n\u2502 path: \/etc\/foo.conf<br \/>\n\u2502 owner: foo<br \/>\n\u2502 group: foo<br \/>\n\u2502 mode: &#8220;644&#8221; # &lt;- Being in a string will prevent Numeric file permissions to behave in unexpected<br \/>\n\u2502 ways.<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\nversion_added \u2502 historic<br \/>\ntags \u2502 formatting<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nrisky-shell-pipe \u2502 Shells that use pipes should set the pipefail option.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # risky-shell-pipe<br \/>\n\u2502<br \/>\n\u2502 This rule checks for the bash pipefail option with the Ansible shell module.<br \/>\n\u2502<br \/>\n\u2502 You should always set pipefail when piping output from a command to another. The return status of a<br \/>\n\u2502 pipeline is the exit status of the command. The pipefail option ensures that tasks fail as expected if<br \/>\n\u2502 the first command fails.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Pipeline without pipefail<br \/>\n\u2502 shell: false | cat<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 become: no<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Pipeline with pipefail<br \/>\n\u2502 shell: set -o pipefail &amp;&amp; false | cat<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: Pipeline with pipefail, multi-line<br \/>\n\u2502 shell: |<br \/>\n\u2502 set -o pipefail # &lt;&#8211; adding this will prevent surprises<br \/>\n\u2502 false | cat<br \/>\nversion_added \u2502 v4.1.0<br \/>\ntags \u2502 command-shell<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nrole-name \u2502 Role name {0} does not match ^[a-z][a-z0-9_]*$ pattern.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # role-name<br \/>\n\u2502<br \/>\n\u2502 This rule checks role names to ensure they conform with requirements.<br \/>\n\u2502<br \/>\n\u2502 Role names must contain only lowercase alphanumeric characters and the underscore _ character. Role<br \/>\n\u2502 names must also start with an alphabetic character.<br \/>\n\u2502<br \/>\n\u2502 For more information see the roles directory topic in Ansible documentation.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 roles:<br \/>\n\u2502 &#8211; 1myrole # &lt;- Does not start with an alphabetic character.<br \/>\n\u2502 &#8211; myrole2[*^ # &lt;- Contains invalid special characters.<br \/>\n\u2502 &#8211; myRole_3 # &lt;- Contains uppercase alphabetic characters.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 roles:<br \/>\n\u2502 &#8211; myrole1 # &lt;- Starts with an alphabetic character.<br \/>\n\u2502 &#8211; myrole2 # &lt;- Contains only alphanumeric characters.<br \/>\n\u2502 &#8211; myrole_3 # &lt;- Contains only lowercase alphabetic characters.<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\nversion_added \u2502 v4.3.0<br \/>\ntags \u2502 deprecations, metadata<br \/>\nseverity \u2502 HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nrun-once \u2502 Run once should use strategy other than free.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # run-once<br \/>\n\u2502<br \/>\n\u2502 This rule warns against the use of run_once when strategy is set to free.<br \/>\n\u2502<br \/>\n\u2502 This rule can produce the following messages:<br \/>\n\u2502<br \/>\n\u2502 \u2022 run_once[play]: Play uses strategy: free.<br \/>\n\u2502 \u2022 run_once[task]: Using run_once may behave differently if strategy is set to free.<br \/>\n\u2502<br \/>\n\u2502 For more information see the following topics in Ansible documentation:<br \/>\n\u2502<br \/>\n\u2502 \u2022 free strategy<br \/>\n\u2502 \u2022 selecting a strategy<br \/>\n\u2502 \u2022 run_once(playbook keyword) more info<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: &#8220;Example with run_once&#8221;<br \/>\n\u2502 hosts: all<br \/>\n\u2502 strategy: free # &lt;&#8211; avoid use of strategy as free<br \/>\n\u2502 gather_facts: false<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Task with run_once<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;Test&#8221;<br \/>\n\u2502 run_once: true # &lt;&#8211; avoid use of strategy as free at play level when using run_once at task level<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8211; name: &#8220;Example without run_once&#8221;<br \/>\n\u2502 hosts: all<br \/>\n\u2502 gather_facts: false<br \/>\n\u2502 tasks:<br \/>\n\u2502 &#8211; name: Task without run_once<br \/>\n\u2502 ansible.builtin.debug:<br \/>\n\u2502 msg: &#8220;Test&#8221;<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\ntags \u2502 idiom, experimental<br \/>\nseverity \u2502 MEDIUM<br \/>\n\u2575<br \/>\n\u2577<br \/>\nschema \u2502 Perform JSON Schema Validation for known lintable kinds.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # schema<br \/>\n\u2502<br \/>\n\u2502 The schema rule validates Ansible metadata files against JSON schemas. These schemas ensure the<br \/>\n\u2502 compatibility of Ansible syntax content across versions.<br \/>\n\u2502<br \/>\n\u2502 This schema rule is mandatory. You cannot use inline noqa comments to ignore it.<br \/>\n\u2502<br \/>\n\u2502 Ansible-lint validates the schema rule before processing other rules. This prevents unexpected syntax<br \/>\n\u2502 from triggering multiple rule violations.<br \/>\n\u2502<br \/>\n\u2502 ## Validated schema<br \/>\n\u2502<br \/>\n\u2502 Ansible-lint currently validates several schemas that are maintained in separate projects and updated<br \/>\n\u2502 independently to ansible-lint.<br \/>\n\u2502<br \/>\n\u2502 \u258c Report bugs related to schema in their respective repository and not in the ansible-lint project.<br \/>\n\u2502<br \/>\n\u2502 Maintained in the ansible-lint project:<br \/>\n\u2502<br \/>\n\u2502 \u2022 schema[ansible-lint-config] validates ansible-lint configuration<br \/>\n\u2502<br \/>\n\u2502 Maintained in the ansible-navigator project:<br \/>\n\u2502<br \/>\n\u2502 \u2022 schema[ansible-navigator] validates ansible-navigator configuration<br \/>\n\u2502<br \/>\n\u2502 Maintained in the Ansible schemas project:<br \/>\n\u2502<br \/>\n\u2502 \u2022 schema[arg_specs] validates module argument specs<br \/>\n\u2502 \u2022 schema[execution-environment] validates execution environments<br \/>\n\u2502 \u2022 schema[galaxy] validates collection metadata.<br \/>\n\u2502 \u2022 schema[inventory] validates inventory files that match inventory\/*.yml.<br \/>\n\u2502 \u2022 schema[meta-runtime] validates runtime information that matches meta\/runtime.yml<br \/>\n\u2502 \u2022 schema[meta] validates metadata for roles that match meta\/main.yml. See role-dependencies or<br \/>\n\u2502 role\/metadata.py) for details.<br \/>\n\u2502 \u2022 schema[playbook] validates Ansible playbooks.<br \/>\n\u2502 \u2022 schema[requirements] validates Ansible requirements files that match requirements.yml.<br \/>\n\u2502 \u2022 schema[tasks] validates Ansible task files that match tasks\/**\/*.yml.<br \/>\n\u2502 \u2022 schema[vars] validates Ansible variables that match vars\/*.yml and defaults\/*.yml.<br \/>\n\u2502<br \/>\n\u2502 ## schema<br \/>\n\u2502<br \/>\n\u2502 For meta\/main.yml files, Ansible-lint requires a galaxy_info.standalone property that clarifies if a<br \/>\n\u2502 role is an old standalone one or a new one, collection based:<br \/>\n\u2502<br \/>\n\u2502 galaxy_info:<br \/>\n\u2502 standalone: true # &lt;&#8211; this is a standalone role (not part of a collection)<br \/>\n\u2502<br \/>\n\u2502 Ansible-lint requires the standalone key to avoid confusion and provide more specific error messages.<br \/>\n\u2502 For example, the meta schema will require some properties only for standalone roles or prevent the use<br \/>\n\u2502 of some properties that are not supported by collections.<br \/>\n\u2502<br \/>\n\u2502 You cannot use an empty meta\/main.yml file or use only comments in the meta\/main.yml file.<br \/>\nversion_added \u2502 v6.1.0<br \/>\ntags \u2502 core, experimental<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nsyntax-check \u2502 Ansible syntax check failed.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # syntax-check<br \/>\n\u2502<br \/>\n\u2502 Our linter runs ansible-playbook &#8211;syntax-check on all playbooks, and if any of these reports a syntax<br \/>\n\u2502 error, this stops any further processing of these files.<br \/>\n\u2502<br \/>\n\u2502 This error cannot be disabled due to being a prerequisite for other steps. You can exclude these files<br \/>\n\u2502 from linting, but it is better to make sure they can be loaded by Ansible. This is often achieved by<br \/>\n\u2502 editing the inventory file and\/or ansible.cfg so ansible can load required variables.<br \/>\n\u2502<br \/>\n\u2502 If undefined variables cause the failure, you can use the jinja default() filter to provide fallback<br \/>\n\u2502 values, like in the example below.<br \/>\n\u2502<br \/>\n\u2502 This rule is among the few unskippable rules that cannot be added to skip_list or warn_list. One<br \/>\n\u2502 possible workaround is to add the entire file to the exclude_paths. This is a valid approach for special<br \/>\n\u2502 cases, like testing fixtures that are invalid on purpose.<br \/>\n\u2502<br \/>\n\u2502 One of the most common sources of errors is failure to assert the presence of various variables at the<br \/>\n\u2502 beginning of the playbook.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Bad use of variable inside hosts block (wrong assumption of it being defined)<br \/>\n\u2502 hosts: &#8220;{{ my_hosts }}&#8221;<br \/>\n\u2502 tasks: []<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Good use of variable inside hosts, without assumptions<br \/>\n\u2502 hosts: &#8220;{{ my_hosts | default([]) }}&#8221;<br \/>\n\u2502 tasks: []<br \/>\nversion_added \u2502 v5.0.0<br \/>\ntags \u2502 core<br \/>\nseverity \u2502 VERY_HIGH<br \/>\n\u2575<br \/>\n\u2577<br \/>\nvar-naming \u2502 All variables should be named using only lowercase and underscores.<br \/>\n\u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574<br \/>\ndescription \u2502 # var-naming<br \/>\n\u2502<br \/>\n\u2502 This rule checks variable names to ensure they conform with requirements.<br \/>\n\u2502<br \/>\n\u2502 Variable names must contain only lowercase alphanumeric characters and the underscore _ character.<br \/>\n\u2502 Variable names must also start with either an alphabetic or underscore _ character.<br \/>\n\u2502<br \/>\n\u2502 For more information see the creating valid variable names topic in Ansible documentation.<br \/>\n\u2502<br \/>\n\u2502 ## Problematic Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 vars:<br \/>\n\u2502 CamelCase: true # &lt;- Contains a mix of lowercase and uppercase characters.<br \/>\n\u2502 ALL_CAPS: bar # &lt;- Contains only uppercase characters.<br \/>\n\u2502 v@r!able: baz # &lt;- Contains special characters.<br \/>\n\u2502<br \/>\n\u2502 ## Correct Code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 &#8211; name: Example playbook<br \/>\n\u2502 hosts: localhost<br \/>\n\u2502 vars:<br \/>\n\u2502 lowercase: true # &lt;- Contains only lowercase characters.<br \/>\n\u2502 no_caps: bar # &lt;- Does not contains uppercase characters.<br \/>\n\u2502 variable: baz # &lt;- Does not contain special characters. version_added \u2502 v5.0.10 tags \u2502 idiom, experimental severity \u2502 MEDIUM \u2575 \u2577 warning \u2502 Other warnings detected during run. \u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574 description \u2502 # warning \u2502 \u2502 warning is a special type of internal rule that is used to report generic runtime warnings found during \u2502 execution. As stated by its name, they are not counted as errors, so they do not influence the final \u2502 outcome. \u2502 \u2502 \u2022 warning[empty-playbook] is raised when a playbook file has no content. \u2502 \u2022 warning[raw-non-string] indicates that you are using \u2502 [raw](http:\/\/docs.ansible.com\/ansible\/latest\/collections\/ansible\/builtin\/raw_module.html#ansible-col\u2026 \u2502 module with non-string arguments, which is not supported by Ansible. version_added \u2502 v6.8.0 tags \u2502 core, experimental severity \u2502 LOW \u2575 \u2577 yaml \u2502 Violations reported by yamllint. \u2576\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2574 description \u2502 # yaml \u2502 \u2502 This rule checks YAML syntax and is an implementation of yamllint. \u2502 \u2502 You can disable YAML syntax violations by adding yaml to the skip_list in your Ansible-lint \u2502 configuration as follows: \u2502 \u2502 skip_list: \u2502 &#8211; yaml \u2502 \u2502 For more fine-grained control, disable violations for specific rules using tag identifiers in the \u2502 yaml[yamllint_rule] format as follows: \u2502 \u2502 skip_list: \u2502 &#8211; yaml[trailing-spaces] \u2502 &#8211; yaml[indentation] \u2502 \u2502 If you want Ansible-lint to report YAML syntax violations as warnings, and not fatal errors, add tag \u2502 identifiers to the warn_list in your configuration, for example: \u2502 \u2502 warn_list: \u2502 &#8211; yaml[document-start] \u2502 \u2502 See the list of yamllint rules for more information. \u2502 \u2502 Some of the detailed error codes that you might see are: \u2502 \u2502 \u2022 yaml[brackets] &#8211; too few spaces inside empty brackets, or too many spaces inside brackets \u2502 \u2022 yaml[colons] &#8211; too many spaces before colon, or too many spaces after colon \u2502 \u2022 yaml[commas] &#8211; too many spaces before comma, or too few spaces after comma \u2502 \u2022 yaml[comments-indentation] &#8211; Comment not indented like content \u2502 \u2022 yaml[comments] &#8211; Too few spaces before comment, or Missing starting space in comment \u2502 \u2022 yaml[document-start] &#8211; missing document start &#8220;&#8212;&#8221; or found forbidden document start &#8220;&#8212;&#8221; \u2502 \u2022 yaml[empty-lines] &#8211; too many blank lines (&#8230;&gt; &#8230;)<br \/>\n\u2502 \u2022 yaml[indentation] &#8211; Wrong indentation: expected &#8230; but found &#8230;<br \/>\n\u2502 \u2022 yaml[key-duplicates] &#8211; Duplication of key &#8220;&#8230;&#8221; in mapping<br \/>\n\u2502 \u2022 yaml[new-line-at-end-of-file] &#8211; No new line character at the end of file<br \/>\n\u2502 \u2022 yaml[syntax] &#8211; YAML syntax is broken<br \/>\n\u2502 \u2022 yaml[trailing-spaces] &#8211; Spaces are found at the end of lines<br \/>\n\u2502 \u2022 yaml[truthy] &#8211; Truthy value should be one of &#8230;<br \/>\n\u2502<br \/>\n\u2502 ## Problematic code<br \/>\n\u2502<br \/>\n\u2502 # Missing YAML document start.<br \/>\n\u2502 foo: &#8230;<br \/>\n\u2502 foo: &#8230; # &lt;&#8211; Duplicate key.<br \/>\n\u2502 bar: &#8230; # &lt;&#8211; Incorrect comment indentation<br \/>\n\u2502<br \/>\n\u2502 ## Correct code<br \/>\n\u2502<br \/>\n\u2502 &#8212;<br \/>\n\u2502 foo: &#8230;<br \/>\n\u2502 bar: &#8230; # Correct comment indentation.<br \/>\n\u2502<br \/>\n\u2502 (more)<br \/>\nversion_added \u2502 v5.0.0<br \/>\ntags \u2502 formatting, yaml<br \/>\nseverity \u2502 VERY_LOW<\/details>\n<p>\u8f93\u51fa\u683c\u5f0f\u53ef\u4ee5\u6307\u5b9a\u4e3a&#8221;rich\u3001plain\u3001md&#8221;\u3002\u5982\u679c\u4e0d\u6307\u5b9a\uff0c\u5219\u9ed8\u8ba4\u4e3arich\u683c\u5f0f\u7684\u8f93\u51fa\u3002<\/p>\n<h3>\u5c55\u793a\u663e\u793a\u7531\u6807\u7b7e\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u663e\u793a\u89c4\u5219\u7684\u7ec6\u5206\u7c7b\u522b\uff09\u3010-T, &#8211;\u5217\u51fa\u6807\u7b7e\u3011<\/h3>\n<p>\u5c55\u793a\u6bcf\u4e2a\u89c4\u5219\u662f\u5982\u4f55\u5206\u7c7b\u7684\u3002\u540c\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u6307\u5b9a\u6807\u7b7e\u6765\u4ec5\u5bf9\u6307\u5b9a\u6807\u7b7e\u7684\u89c4\u5219\u6267\u884cAnsible lint\u3002\u8fd9\u80fd\u8ba9\u4f60\u4e86\u89e3Ansible lint\u89c4\u5219\u7684\u57fa\u672c\u601d\u60f3\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">-T<\/span>\r\n<span class=\"c\">## \u3082\u3057\u304f\u306f<\/span>\r\nansible-lint <span class=\"nt\">--list-tags<\/span>\r\n\r\n<span class=\"c\"># List of tags and rules they cover<\/span>\r\ncommand-shell:  <span class=\"c\"># Specific to use of command and shell modules<\/span>\r\n  - command-instead-of-module\r\n  - command-instead-of-shell\r\n  - deprecated-command-syntax\r\n  - inline-env-var\r\n  - no-changed-when\r\n  - risky-shell-pipe\r\ncore:  <span class=\"c\"># Related to internal implementation of the linter<\/span>\r\n  - internal-error\r\n  - load-failure\r\n  - parser-error\r\n  - syntax-check\r\n  - warning\r\n  - schema\r\ndeprecations:  <span class=\"c\"># Indicate use of features that are removed from Ansible<\/span>\r\n  - deprecated-bare-vars\r\n  - deprecated-command-syntax\r\n  - deprecated-local-action\r\n  - deprecated-module\r\n  - no-jinja-when\r\n  - role-name\r\nexperimental:  <span class=\"c\"># Newly introduced rules, by default triggering only warnings<\/span>\r\n  - warning\r\n  - avoid-implicit\r\n  - galaxy\r\n  - ignore-errors\r\n  - key-order\r\n  - no-free-form\r\n  - no-log-password\r\n  - no-prompting\r\n  - only-builtins\r\n  - risky-file-permissions\r\n  - run-once\r\n  - schema\r\n  - var-naming\r\nformatting:  <span class=\"c\"># Related to code-style<\/span>\r\n  - yaml\r\n  - fqcn\r\n  - jinja\r\n  - key-order\r\n  - no-tabs\r\n  - playbook-extension\r\n  - risky-octal\r\nidempotency:  <span class=\"c\"># Possible indication that consequent runs would produce different results<\/span>\r\n  - latest\r\n  - no-changed-when\r\n  - package-latest\r\nidiom:  <span class=\"c\"># Anti-pattern detected, likely to cause undesired behavior<\/span>\r\n  - command-instead-of-module\r\n  - command-instead-of-shell\r\n  - empty-string-compare\r\n  - inline-env-var\r\n  - literal-compare\r\n  - loop-var-prefix\r\n  - name\r\n  - no-handler\r\n  - no-relative-paths\r\n  - run-once\r\n  - var-naming\r\nmetadata:  <span class=\"c\"># Invalid metadata, likely related to galaxy, collections or roles<\/span>\r\n  - galaxy\r\n  - meta-incorrect\r\n  - meta-no-info\r\n  - meta-no-tags\r\n  - meta-video-links\r\n  - role-name\r\nopt-in:  <span class=\"c\"># Rules that are not used unless manually added to `enable_list`<\/span>\r\n  - empty-string-compare\r\n  - galaxy\r\n  - no-log-password\r\n  - no-prompting\r\n  - no-same-owner\r\n  - only-builtins\r\nrisk:\r\n  - no-free-form\r\nsecurity:  <span class=\"c\"># Rules related o potentially security issues, like exposing credentials<\/span>\r\n  - no-log-password\r\nsyntax:\r\n  - no-free-form\r\nunpredictability:  <span class=\"c\"># Warn about code that might not work in a predictable way<\/span>\r\n  - avoid-implicit\r\n  - ignore-errors\r\n  - partial-become\r\n  - risky-file-permissions\r\nunskippable:  <span class=\"c\"># Indicate a fatal error that cannot be ignored or disabled<\/span>\r\n  - load-failure\r\nyaml:  <span class=\"c\"># External linter which will also produce its own rule codes<\/span>\r\n  - yaml\r\n<\/code><\/pre>\n<h3>\u6307\u5b9a\u8f93\u51fa\u683c\u5f0f\u3010-f\uff0c&#8211;format\u3011\u3002<\/h3>\n<p>\u201c\u6307\u5b9a\u8f93\u51fa\u547d\u4ee4\u7ed3\u679c\u7684\u683c\u5f0f\u3002\u53ef\u6307\u5b9a\u7684\u683c\u5f0f\u6709\u4ee5\u4e0b\u51e0\u79cd\u3002\u201d<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">rich<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">plain<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">md<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">json<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">codeclimate<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">quiet<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">pep8<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">sarif<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">docs<\/ul>\n<p>\u6210\u4e3a\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint\r\nWARNING  Listing 1 violation<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> that are fatal\r\nroles\/create-backup:1: role-name: Role name create-backup does not match <span class=\"sb\">``<\/span>^<span class=\"k\">*<\/span><span class=\"nv\">$`<\/span><span class=\"sb\">`<\/span> pattern. <span class=\"o\">(<\/span>warning<span class=\"o\">)<\/span>\r\n\r\n                  Rule Violation Summary                  \r\n count tag       profile rule associated tags             \r\n     1 role-name basic   deprecations, metadata <span class=\"o\">(<\/span>warning<span class=\"o\">)<\/span> \r\n\r\nPassed with min profile: 0 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 1 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 15 files.\r\nA new release of ansible-lint is available: 6.8.4 \u2192 6.8.5 Upgrade by running: pip3 <span class=\"nb\">install<\/span> <span class=\"nt\">--user<\/span> <span class=\"nt\">--upgrade<\/span> ansible-lint\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"err\">ansible-lint<\/span> <span class=\"err\">-f<\/span> <span class=\"err\">json<\/span>\r\n<span class=\"p\">[{<\/span><span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"issue\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"check_name\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"role-name\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"categories\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"s2\">\"deprecations\"<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"metadata\"<\/span><span class=\"p\">],<\/span> <span class=\"nl\">\"url\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"https:\/\/ansible-lint.readthedocs.io\/rules\/role-name\/\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"severity\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"info\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"description\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Role name create-backup does not match ``^<\/span><span class=\"se\">\\\\<\/span><span class=\"s2\">[a-z]<\/span><span class=\"se\">\\\\<\/span><span class=\"s2\">[a-z0-9_]*$`` pattern.\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"fingerprint\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"b6a7a8b84b404967d988b9ffb58662ac0ed3115f22e6bda953b27e89632dac75\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"location\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span><span class=\"nl\">\"path\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"roles\/create-backup\"<\/span><span class=\"p\">,<\/span> <span class=\"nl\">\"lines\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span><span class=\"nl\">\"begin\"<\/span><span class=\"p\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">}}}]<\/span>\r\n\r\n                  <span class=\"err\">Rule<\/span> <span class=\"err\">Violation<\/span> <span class=\"err\">Summary<\/span>                  \r\n <span class=\"err\">count<\/span> <span class=\"err\">tag<\/span>       <span class=\"err\">profile<\/span> <span class=\"err\">rule<\/span> <span class=\"err\">associated<\/span> <span class=\"err\">tags<\/span>             \r\n     <span class=\"mi\">1<\/span> <span class=\"err\">role-name<\/span> <span class=\"err\">basic<\/span>   <span class=\"err\">deprecations,<\/span> <span class=\"err\">metadata<\/span> <span class=\"err\">(warning)<\/span> \r\n\r\n<span class=\"err\">Passed<\/span> <span class=\"err\">with<\/span> <span class=\"err\">min<\/span> <span class=\"na\">profile<\/span><span class=\"p\">:<\/span> <span class=\"mi\">0<\/span> <span class=\"err\">failure(s),<\/span> <span class=\"mi\">1<\/span> <span class=\"err\">warning(s)<\/span> <span class=\"err\">on<\/span> <span class=\"mi\">15<\/span> <span class=\"err\">files.<\/span>\r\n<span class=\"err\">A<\/span> <span class=\"err\">new<\/span> <span class=\"err\">release<\/span> <span class=\"err\">of<\/span> <span class=\"err\">ansible-lint<\/span> <span class=\"err\">is<\/span> <span class=\"na\">available<\/span><span class=\"p\">:<\/span> <span class=\"mf\">6.8<\/span><span class=\"err\">.<\/span><span class=\"mi\">4<\/span> <span class=\"err\">\u2192<\/span> <span class=\"mf\">6.8<\/span><span class=\"err\">.<\/span><span class=\"mi\">5<\/span> <span class=\"err\">Upgrade<\/span> <span class=\"err\">by<\/span> <span class=\"na\">running<\/span><span class=\"p\">:<\/span> <span class=\"err\">pip<\/span><span class=\"mi\">3<\/span> <span class=\"err\">install<\/span> <span class=\"err\">--user<\/span> <span class=\"err\">--upgrade<\/span> <span class=\"err\">ansible-lint<\/span>\r\n<\/code><\/pre>\n<h3>\u51cf\u5c11\u663e\u793a\u4fe1\u606f \u3010-q\u3011<\/h3>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">-q<\/span>\r\nroles\/create-backup:1: role-name <span class=\"o\">(<\/span>warning<span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<h3>\u6307\u5b9a\u8981\u4f7f\u7528\u7684\u914d\u7f6e\u6587\u4ef6\u3010-P\uff0c&#8211;profile\u3011\u3002<\/h3>\n<p>\u8acb\u9078\u64c7\u9069\u7528\u7684\u500b\u4eba\u8cc7\u6599\u3002\u53ef\u9078\u500b\u4eba\u8cc7\u6599\u5982\u4e0b\uff1a<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">min<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">basic<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">moderate<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">safety<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">shared<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">production<\/ul>\n<p>\u662f\u7684\u3002<\/p>\n<p>\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u4efb\u4f55\u5185\u5bb9\uff0c\u5c06\u5e94\u7528&#8221;production&#8221;\u3002<\/p>\n<h4>\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u672a\u6307\u5b9a\u4efb\u4f55\u5185\u5bb9\uff0c\u4f1a\u5c06&#8221;production&#8221;\u6307\u5b9a\u4e3a\u4e2a\u4eba\u8d44\u6599\u3002<\/h4>\n<pre class=\"post-pre\"><code>ansible-lint\r\nWARNING  Listing 1 violation<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> that are fatal\r\nroles\/create-backup:1: role-name: Role name create-backup does not match <span class=\"sb\">``<\/span>^<span class=\"k\">*<\/span><span class=\"nv\">$`<\/span><span class=\"sb\">`<\/span> pattern. <span class=\"o\">(<\/span>warning<span class=\"o\">)<\/span>\r\n\r\n                  Rule Violation Summary                  \r\n count tag       profile rule associated tags             \r\n     1 role-name basic   deprecations, metadata <span class=\"o\">(<\/span>warning<span class=\"o\">)<\/span> \r\n\r\nPassed with min profile: 0 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 1 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 15 files.\r\nA new release of ansible-lint is available: 6.8.4 \u2192 6.8.5 Upgrade by running: pip3 <span class=\"nb\">install<\/span> <span class=\"nt\">--user<\/span> <span class=\"nt\">--upgrade<\/span> ansible-lint\r\n<\/code><\/pre>\n<h4>\u6267\u884c\u6700\u57fa\u672c\u7684lint\u68c0\u67e5\uff08\u5c06min\u8bbe\u4e3aprofile\uff09\u3002<\/h4>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">-p<\/span> min\r\n\r\nPassed with production profile: 0 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 0 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 1 files.\r\nA new release of ansible-lint is available: 6.8.4 \u2192 6.8.5 Upgrade by running: pip3 <span class=\"nb\">install<\/span> <span class=\"nt\">--user<\/span> <span class=\"nt\">--upgrade<\/span> ansible-lint\r\n<\/code><\/pre>\n<h3>\u5982\u679c\u76f8\u5bf9\u4e0a\u4e00\u6b21\u7684commit\u6709\u6539\u8fdb\uff0c\u8fd4\u56de&#8221;success&#8221;\u3010&#8211;progress\u3011\u3002<\/h3>\n<p>\u524d\u63d0\u662f\u4f7f\u7528Git\u8fdb\u884c\u5f00\u53d1\u3002\u5982\u679c\u4e0e\u4e0a\u4e00\u6b21\u63d0\u4ea4\u65f6\u7684\u5185\u5bb9\u76f8\u6bd4\uff0c\u5373\u4f7f\u6709\u4e00\u4e2a\u8fdd\u53cd\u89c4\u5219\u7684\u60c5\u51b5\u51cf\u5c11\uff0c\u4e5f\u4f1a\u8fd4\u56de\u6210\u529f\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">--progress<\/span>\r\n<\/code><\/pre>\n<h3>\u6307\u5b9a\u9879\u76ee\u76ee\u5f55\u3010&#8211;project-dir\u3011\u3002<\/h3>\n<p>\u8fd9\u662f\u4e00\u4e2a\u795e\u79d8\u7684\u9009\u9879\u3002\u6307\u5b9a\u5728\u9879\u76ee\u4e2d\u7684Galaxy\u89d2\u8272\u7b49\u8def\u5f84\u5c06\u4f1a\u68c0\u67e5\u8be5\u89d2\u8272\u3002\u7136\u800c\uff0c\u5bf9\u4e8e\u8be5\u89d2\u8272\uff0cAnsible lint\u4e0d\u4f1a\u88ab\u6267\u884c\u3002\uff08\u5728Ansible lint 6.8\u7248\u672c\u8fdb\u884c\u786e\u8ba4\uff09<\/p>\n<h3>\u5c06\u8b66\u544a\u89c6\u4e3a\u9519\u8bef\u3010-s, &#8211;\u4e25\u683c\u3011<\/h3>\n<p>\u4f7f\u7528\u4e25\u683c\u6a21\u5f0f\u5bf9 Ansible lint \u8fdb\u884c\u6267\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">-s<\/span>\r\n<span class=\"c\">## \u3082\u3057\u304f\u306f<\/span>\r\nansible-lint <span class=\"nt\">--strict<\/span>\r\n<\/code><\/pre>\n<h3>\u5c06YAML\u6587\u4ef6\u91cd\u5199\u4e3aAnsible lint\u63a8\u8350\u7684\u683c\u5f0f\u3010&#8211;write\u3011<\/h3>\n<p>\u5c06YAML\u6587\u4ef6\u8f6c\u6362\u4e3aAnsible lint\u63a8\u8350\u7684\u683c\u5f0f\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">--write<\/span>\r\n<\/code><\/pre>\n<p>\u6bd4\u5982\u8bf4<\/p>\n<pre class=\"post-pre\"><code> <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Create WordPress install directory<\/span>\r\n   <span class=\"na\">ansible.builtin.file<\/span><span class=\"pi\">:<\/span>\r\n<span class=\"pi\">-<\/span>    <span class=\"na\">dest<\/span><span class=\"pi\">:<\/span> <span class=\"s1\">'<\/span><span class=\"s\">{{<\/span> <span class=\"s\">wp_install_path<\/span> <span class=\"s\">}}'<\/span>\r\n<span class=\"na\">+    dest<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">wp_install_path<\/span> <span class=\"s\">}}\"<\/span>\r\n     <span class=\"na\">state<\/span><span class=\"pi\">:<\/span> <span class=\"s\">directory<\/span>\r\n     <span class=\"na\">owner<\/span><span class=\"pi\">:<\/span> <span class=\"s\">apache<\/span>\r\n     <span class=\"na\">group<\/span><span class=\"pi\">:<\/span> <span class=\"s\">apache<\/span>\r\n     <span class=\"na\">mode<\/span><span class=\"pi\">:<\/span> <span class=\"m\">0755<\/span>\r\n<span class=\"pi\">-<\/span>    <span class=\"na\">recurse<\/span><span class=\"pi\">:<\/span> <span class=\"s\">yes<\/span>\r\n<span class=\"na\">+    recurse<\/span><span class=\"pi\">:<\/span> <span class=\"kc\">true<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code> <span class=\"na\">yaml-files<\/span><span class=\"pi\">:<\/span>\r\n<span class=\"pi\">-<\/span>  <span class=\"pi\">-<\/span> <span class=\"s1\">'<\/span><span class=\"s\">*.yaml'<\/span>\r\n<span class=\"pi\">-<\/span>  <span class=\"pi\">-<\/span> <span class=\"s1\">'<\/span><span class=\"s\">*.yml'<\/span>\r\n<span class=\"pi\">-<\/span>  <span class=\"pi\">-<\/span> <span class=\"s1\">'<\/span><span class=\"s\">.yamllint'<\/span>\r\n<span class=\"s\">+  - \"*.yaml\"<\/span>\r\n<span class=\"s\">+  - \"*.yml\"<\/span>\r\n<span class=\"s\">+  - .yamllint<\/span>\r\n<\/code><\/pre>\n<p>\u4ee5\u7c7b\u4f3c\u7684\u65b9\u5f0f\u8fdb\u884c\u683c\u5f0f\u5316\u3002<\/p>\n<p>\u4e3b\u8981\u68c0\u67e5\u7f29\u8fdb\u3001\u5f15\u53f7\u3001\u7a7a\u683c\u7b49\uff0c\u4f46\u5728\u64b0\u5199\u6587\u7ae0\u65f6\u76846.8\u7248\u672c\u4e2d\uff0c\u4f3c\u4e4e\u4e0d\u4f1a\u6267\u884cAnsible\u72ec\u6709\u529f\u80fd\u5982fqdn\u4fee\u6b63\u6216yamllint\u7684key-ordering\u683c\u5f0f\u7b49\u64cd\u4f5c\u3002<\/p>\n<h3>\u4ec5\u5e94\u7528\u4e8e\u6307\u5b9a\u6807\u7b7e\u7684\u89c4\u5219\u7ec4\u3010-t TAGS, &#8211;tags TAGS\u3011\u3002<\/h3>\n<p>\u4f7f\u7528ansible-lint &#8211;list-tags\u547d\u4ee4\uff0c\u6839\u636e\u6807\u7b7e\u5206\u7c7b\uff0c\u4ec5\u5bf9\u7279\u5b9a\u89c4\u5219\u5e94\u7528Ansible lint\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">-t<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6ca1\u6709\u63cf\u8ff0Module\u7684fqdn\uff0c\u5f53\u6267\u884cAnsible lint\u901a\u5e38\u60c5\u51b5\u4e0b\u4f1a\u51fa\u73b0\u4ee5\u4e0b\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Install cowsay<\/span>\r\n  <span class=\"na\">package<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">cowsay<\/span>\r\n    <span class=\"na\">state<\/span><span class=\"pi\">:<\/span> <span class=\"s\">present<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>ansible-lint tasks\/main.yml\r\nWARNING  Listing 1 violation<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> that are fatal\r\ntasks\/main.yml:2: fqcn[action-core]: Use FQCN <span class=\"k\">for <\/span><span class=\"nb\">builtin <\/span>module actions <span class=\"o\">(<\/span>package<span class=\"o\">)<\/span><span class=\"nb\">.<\/span>\r\nYou can skip specific rules or tags by adding them to your configuration file:\r\n<span class=\"c\"># .config\/ansible-lint.yml<\/span>\r\nwarn_list:  <span class=\"c\"># or 'skip_list' to silence them completely<\/span>\r\n  - fqcn[action-core]  <span class=\"c\"># Use FQCN for builtin actions.<\/span>\r\n\r\n                 Rule Violation Summary                  \r\n count tag               profile    rule associated tags \r\n     1 <span class=\"o\">]<\/span>8<span class=\"p\">;<\/span><span class=\"nb\">id<\/span><span class=\"o\">=<\/span>404615<span class=\"p\">;<\/span>https:\/\/ansible-lint.readthedocs.io\/rules\/fqcn<span class=\"se\">\\f<\/span>qcn[action-core]]8<span class=\"p\">;;<\/span><span class=\"se\">\\ <\/span>production formatting           \r\n\r\nFailed after shared profile, 4\/5 star rating: 1 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 0 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 1 files.\r\n\r\nExited with code <span class=\"nb\">exit <\/span>status 2\r\n<\/code><\/pre>\n<p>\u53ea\u6709\u5c06\u6b64\u89c4\u5219\u5e94\u7528\u4e8e\u6807\u7b7e\u540d\u4e3acore\u7684\u89c4\u5219\u65f6\uff0c\u624d\u4e0d\u4f1a\u5e94\u7528\u4e8efqdn\u7b49\u89c4\u5219\uff0c\u56e0\u6b64\u4e0d\u4f1a\u51fa\u9519\u3002<\/p>\n<pre class=\"post-pre\"><code>nsible-lint <span class=\"nt\">-t<\/span> core tasks\/main.yml\r\n\r\nPassed with production profile: 0 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 0 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 1 files.\r\n<\/code><\/pre>\n<h3>\u901a\u8fc7\u4f7f\u7528Verbose\u6a21\u5f0f\u6765\u6267\u884c\u3010-v\uff0c-vv\u3011<\/h3>\n<p>\u65e5\u5fd7\u8f93\u51fa\u4f1a\u53d8\u5f97\u66f4\u8be6\u7ec6\u3002\u6700\u591a\u53ea\u80fd\u663e\u793a\u4e24\u4e2av\uff0c\u5373\u4f7f\u6dfb\u52a0\u4e86\u4e09\u4e2a\u6216\u66f4\u591a\u4e5f\u4e0d\u4f1a\u6709\u4efb\u4f55\u53d8\u5316\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint tasks\/main.yml <span class=\"nt\">-v<\/span>\r\n\r\nINFO     Set <span class=\"nv\">ANSIBLE_LIBRARY<\/span><span class=\"o\">=<\/span>\/home\/mamono210\/.cache\/ansible-compat\/244210\/modules:\/home\/mamono210\/.ansible\/plugins\/modules:\/usr\/share\/ansible\/plugins\/modules\r\nINFO     Set <span class=\"nv\">ANSIBLE_COLLECTIONS_PATH<\/span><span class=\"o\">=<\/span>\/home\/mamono210\/.cache\/ansible-compat\/244210\/collections:\/home\/mamono210\/.ansible\/collections:\/usr\/share\/ansible\/collections\r\nINFO     Set <span class=\"nv\">ANSIBLE_ROLES_PATH<\/span><span class=\"o\">=<\/span>\/home\/mamono210\/.cache\/ansible-compat\/244210\/roles:\/home\/mamono210\/.ansible\/roles:\/usr\/share\/ansible\/roles:\/etc\/ansible\/roles\r\nINFO     Using \/home\/mamono210\/.cache\/ansible-compat\/244210\/roles\/mamono210.cowsay symlink to current repository <span class=\"k\">in <\/span>order to <span class=\"nb\">enable <\/span>Ansible to find the role using its expected full name.\r\n\r\nPassed with production profile: 0 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 0 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 1 files.\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>ansible-lint tasks\/main.yml <span class=\"nt\">-vv<\/span>\r\n\r\nDEBUG    Logging initialized to level 10\r\nDEBUG    Options: Namespace<span class=\"o\">(<\/span><span class=\"nv\">cache_dir<\/span><span class=\"o\">=<\/span><span class=\"s1\">'\/home\/mamono210\/.cache\/ansible-compat\/244210'<\/span>, <span class=\"nv\">colored<\/span><span class=\"o\">=<\/span>True, <span class=\"nv\">configured<\/span><span class=\"o\">=<\/span>True, <span class=\"nv\">cwd<\/span><span class=\"o\">=<\/span>PosixPath<span class=\"o\">(<\/span><span class=\"s1\">'\/home\/mamono210\/project'<\/span><span class=\"o\">)<\/span>, <span class=\"nv\">display_relative_path<\/span><span class=\"o\">=<\/span>True, <span class=\"nv\">exclude_paths<\/span><span class=\"o\">=[<\/span><span class=\"s1\">'.cache'<\/span>, <span class=\"s1\">'.git'<\/span>, <span class=\"s1\">'.hg'<\/span>, <span class=\"s1\">'.svn'<\/span>, <span class=\"s1\">'.tox'<\/span><span class=\"o\">]<\/span>, <span class=\"nv\">format<\/span><span class=\"o\">=<\/span><span class=\"s1\">'rich'<\/span>, <span class=\"nv\">lintables<\/span><span class=\"o\">=[<\/span><span class=\"s1\">'tasks\/main.yml'<\/span><span class=\"o\">]<\/span>, <span class=\"nv\">listrules<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">listtags<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">write_list<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">parseable<\/span><span class=\"o\">=<\/span>True, <span class=\"nv\">quiet<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">rulesdirs<\/span><span class=\"o\">=[<\/span><span class=\"s1\">'\/home\/mamono210\/.local\/lib\/python3.11\/site-packages\/ansiblelint\/rules'<\/span><span class=\"o\">]<\/span>, <span class=\"nv\">skip_list<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">tags<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">verbosity<\/span><span class=\"o\">=<\/span>2, <span class=\"nv\">warn_list<\/span><span class=\"o\">=[<\/span><span class=\"s1\">'avoid-implicit'<\/span>, <span class=\"s1\">'experimental'<\/span>, <span class=\"s1\">'fqcn[action]'<\/span>, <span class=\"s1\">'fqcn[redirect]'<\/span>, <span class=\"s1\">'jinja[spacing]'<\/span>, <span class=\"s1\">'name[casing]'<\/span>, <span class=\"s1\">'name[play]'<\/span>, <span class=\"s1\">'role-name'<\/span>, <span class=\"s1\">'warning[empty-playbook]'<\/span>, <span class=\"s1\">'role-name[path]'<\/span><span class=\"o\">]<\/span>, <span class=\"nv\">kinds<\/span><span class=\"o\">=[{<\/span><span class=\"s1\">'jinja2'<\/span>: <span class=\"s1\">'**\/*.j2'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'jinja2'<\/span>: <span class=\"s1\">'**\/*.j2.*'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'yaml'<\/span>: <span class=\"s1\">'.github\/**\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'text'<\/span>: <span class=\"s1\">'**\/templates\/**\/*.*'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'execution-environment'<\/span>: <span class=\"s1\">'**\/execution-environment.yml'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'ansible-lint-config'<\/span>: <span class=\"s1\">'**\/.ansible-lint'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'ansible-lint-config'<\/span>: <span class=\"s1\">'**\/.config\/ansible-lint.yml'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'ansible-navigator-config'<\/span>: <span class=\"s1\">'**\/ansible-navigator.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'inventory'<\/span>: <span class=\"s1\">'**\/inventory\/**.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'requirements'<\/span>: <span class=\"s1\">'**\/meta\/requirements.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'galaxy'<\/span>: <span class=\"s1\">'**\/galaxy.yml'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'reno'<\/span>: <span class=\"s1\">'**\/releasenotes\/*\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'tasks'<\/span>: <span class=\"s1\">'**\/tasks\/**\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'playbook'<\/span>: <span class=\"s1\">'**\/playbooks\/*.{yml,yaml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'playbook'<\/span>: <span class=\"s1\">'**\/*playbook*.{yml,yaml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'role'<\/span>: <span class=\"s1\">'**\/roles\/*\/'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'handlers'<\/span>: <span class=\"s1\">'**\/handlers\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'vars'<\/span>: <span class=\"s1\">'**\/{host_vars,group_vars,vars,defaults}\/**\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'test-meta'<\/span>: <span class=\"s1\">'**\/tests\/integration\/targets\/*\/meta\/main.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'meta'<\/span>: <span class=\"s1\">'**\/meta\/main.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'meta-runtime'<\/span>: <span class=\"s1\">'**\/meta\/runtime.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'arg_specs'<\/span>: <span class=\"s1\">'**\/meta\/argument_specs.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'yaml'<\/span>: <span class=\"s1\">'.config\/molecule\/config.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'requirements'<\/span>: <span class=\"s1\">'**\/molecule\/*\/{collections,requirements}.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'yaml'<\/span>: <span class=\"s1\">'**\/molecule\/*\/{base,molecule}.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'requirements'<\/span>: <span class=\"s1\">'**\/requirements.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'playbook'<\/span>: <span class=\"s1\">'**\/molecule\/*\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'yaml'<\/span>: <span class=\"s1\">'**\/{.ansible-lint,.yamllint}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'yaml'<\/span>: <span class=\"s1\">'**\/*.{yaml,yml}'<\/span><span class=\"o\">}<\/span>, <span class=\"o\">{<\/span><span class=\"s1\">'yaml'<\/span>: <span class=\"s1\">'**\/.*.{yaml,yml}'<\/span><span class=\"o\">}]<\/span>, <span class=\"nv\">mock_filters<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">mock_modules<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">mock_roles<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">loop_var_prefix<\/span><span class=\"o\">=<\/span>None, <span class=\"nv\">var_naming_pattern<\/span><span class=\"o\">=<\/span>None, <span class=\"nv\">offline<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">project_dir<\/span><span class=\"o\">=<\/span><span class=\"s1\">'.'<\/span>, <span class=\"nv\">extra_vars<\/span><span class=\"o\">=<\/span>None, <span class=\"nv\">enable_list<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">skip_action_validation<\/span><span class=\"o\">=<\/span>True, <span class=\"nv\">strict<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">rules<\/span><span class=\"o\">={}<\/span>, <span class=\"nv\">profile<\/span><span class=\"o\">=<\/span>None, <span class=\"nv\">progressive<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">rulesdir<\/span><span class=\"o\">=[]<\/span>, <span class=\"nv\">use_default_rules<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">config_file<\/span><span class=\"o\">=<\/span><span class=\"s1\">'\/home\/mamono210\/project\/.ansible-lint'<\/span>, <span class=\"nv\">version<\/span><span class=\"o\">=<\/span>False, <span class=\"nv\">cache_dir_lock<\/span><span class=\"o\">=<\/span>&lt;filelock._unix.UnixFileLock object at 0x7f318b9f4d10&gt;<span class=\"o\">)<\/span>\r\nDEBUG    \/home\/mamono210\/project\r\nDEBUG    Loading custom .yamllint config file, this extends our internal yamllint config.\r\nDEBUG    Effective yamllint rules used: <span class=\"o\">{<\/span><span class=\"s1\">'braces'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'forbid'<\/span>: False, <span class=\"s1\">'min-spaces-inside'<\/span>: 0, <span class=\"s1\">'max-spaces-inside'<\/span>: 0, <span class=\"s1\">'min-spaces-inside-empty'<\/span>: <span class=\"nt\">-1<\/span>, <span class=\"s1\">'max-spaces-inside-empty'<\/span>: <span class=\"nt\">-1<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'brackets'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'forbid'<\/span>: False, <span class=\"s1\">'min-spaces-inside'<\/span>: 0, <span class=\"s1\">'max-spaces-inside'<\/span>: 0, <span class=\"s1\">'min-spaces-inside-empty'<\/span>: <span class=\"nt\">-1<\/span>, <span class=\"s1\">'max-spaces-inside-empty'<\/span>: <span class=\"nt\">-1<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'colons'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'max-spaces-before'<\/span>: 0, <span class=\"s1\">'max-spaces-after'<\/span>: 1<span class=\"o\">}<\/span>, <span class=\"s1\">'commas'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'max-spaces-before'<\/span>: 0, <span class=\"s1\">'min-spaces-after'<\/span>: 1, <span class=\"s1\">'max-spaces-after'<\/span>: 1<span class=\"o\">}<\/span>, <span class=\"s1\">'comments'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'require-starting-space'<\/span>: True, <span class=\"s1\">'ignore-shebangs'<\/span>: True, <span class=\"s1\">'min-spaces-from-content'<\/span>: 2<span class=\"o\">}<\/span>, <span class=\"s1\">'comments-indentation'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'document-end'<\/span>: False, <span class=\"s1\">'document-start'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'present'<\/span>: True<span class=\"o\">}<\/span>, <span class=\"s1\">'empty-lines'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'max'<\/span>: 2, <span class=\"s1\">'max-start'<\/span>: 0, <span class=\"s1\">'max-end'<\/span>: 0<span class=\"o\">}<\/span>, <span class=\"s1\">'empty-values'<\/span>: False, <span class=\"s1\">'float-values'<\/span>: False, <span class=\"s1\">'hyphens'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'max-spaces-after'<\/span>: 1<span class=\"o\">}<\/span>, <span class=\"s1\">'indentation'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'spaces'<\/span>: <span class=\"s1\">'consistent'<\/span>, <span class=\"s1\">'indent-sequences'<\/span>: True, <span class=\"s1\">'check-multi-line-strings'<\/span>: False<span class=\"o\">}<\/span>, <span class=\"s1\">'key-duplicates'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'key-ordering'<\/span>: False, <span class=\"s1\">'line-length'<\/span>: False, <span class=\"s1\">'new-line-at-end-of-file'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'new-lines'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span>, <span class=\"s1\">'type'<\/span>: <span class=\"s1\">'unix'<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'octal-values'<\/span>: False, <span class=\"s1\">'quoted-strings'<\/span>: False, <span class=\"s1\">'trailing-spaces'<\/span>: <span class=\"o\">{<\/span><span class=\"s1\">'level'<\/span>: <span class=\"s1\">'error'<\/span><span class=\"o\">}<\/span>, <span class=\"s1\">'truthy'<\/span>: False<span class=\"o\">}<\/span>\r\nINFO     Set <span class=\"nv\">ANSIBLE_LIBRARY<\/span><span class=\"o\">=<\/span>\/home\/mamono210\/.cache\/ansible-compat\/244210\/modules:\/home\/mamono210\/.ansible\/plugins\/modules:\/usr\/share\/ansible\/plugins\/modules\r\nINFO     Set <span class=\"nv\">ANSIBLE_COLLECTIONS_PATH<\/span><span class=\"o\">=<\/span>\/home\/mamono210\/.cache\/ansible-compat\/244210\/collections:\/home\/mamono210\/.ansible\/collections:\/usr\/share\/ansible\/collections\r\nINFO     Set <span class=\"nv\">ANSIBLE_ROLES_PATH<\/span><span class=\"o\">=<\/span>\/home\/mamono210\/.cache\/ansible-compat\/244210\/roles:\/home\/mamono210\/.ansible\/roles:\/usr\/share\/ansible\/roles:\/etc\/ansible\/roles\r\nINFO     Using \/home\/mamono210\/.cache\/ansible-compat\/244210\/roles\/mamono210.cowsay symlink to current repository <span class=\"k\">in <\/span>order to <span class=\"nb\">enable <\/span>Ansible to find the role using its expected full name.\r\nDEBUG    Examining tasks\/main.yml of <span class=\"nb\">type <\/span>tasks\r\nDEBUG    Attempting to release lock 139850772598032 on \/home\/mamono210\/.cache\/ansible-compat\/244210\/.lock\r\nDEBUG    Lock 139850772598032 released on \/home\/mamono210\/.cache\/ansible-compat\/244210\/.lock\r\n\r\nDEBUG    Determined rule-profile order: <span class=\"o\">{<\/span><span class=\"s1\">'internal-error'<\/span>: <span class=\"o\">(<\/span>0, <span class=\"s1\">'min'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'load-failure'<\/span>: <span class=\"o\">(<\/span>1, <span class=\"s1\">'min'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'parser-error'<\/span>: <span class=\"o\">(<\/span>2, <span class=\"s1\">'min'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'syntax-check'<\/span>: <span class=\"o\">(<\/span>3, <span class=\"s1\">'min'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'command-instead-of-module'<\/span>: <span class=\"o\">(<\/span>4, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'command-instead-of-shell'<\/span>: <span class=\"o\">(<\/span>5, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'deprecated-bare-vars'<\/span>: <span class=\"o\">(<\/span>6, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'deprecated-command-syntax'<\/span>: <span class=\"o\">(<\/span>7, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'deprecated-local-action'<\/span>: <span class=\"o\">(<\/span>8, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'deprecated-module'<\/span>: <span class=\"o\">(<\/span>9, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'inline-env-var'<\/span>: <span class=\"o\">(<\/span>10, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'key-order'<\/span>: <span class=\"o\">(<\/span>11, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'literal-compare'<\/span>: <span class=\"o\">(<\/span>12, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'jinja'<\/span>: <span class=\"o\">(<\/span>13, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-jinja-when'<\/span>: <span class=\"o\">(<\/span>14, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-tabs'<\/span>: <span class=\"o\">(<\/span>15, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'partial-become'<\/span>: <span class=\"o\">(<\/span>16, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'playbook-extension'<\/span>: <span class=\"o\">(<\/span>17, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'role-name'<\/span>: <span class=\"o\">(<\/span>18, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'schema'<\/span>: <span class=\"o\">(<\/span>19, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'name'<\/span>: <span class=\"o\">(<\/span>20, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'var-naming'<\/span>: <span class=\"o\">(<\/span>21, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'yaml'<\/span>: <span class=\"o\">(<\/span>22, <span class=\"s1\">'basic'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'name[template]'<\/span>: <span class=\"o\">(<\/span>23, <span class=\"s1\">'moderate'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'name[imperative]'<\/span>: <span class=\"o\">(<\/span>24, <span class=\"s1\">'moderate'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'name[casing]'<\/span>: <span class=\"o\">(<\/span>25, <span class=\"s1\">'moderate'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-free-form'<\/span>: <span class=\"o\">(<\/span>26, <span class=\"s1\">'moderate'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'spell-var-name'<\/span>: <span class=\"o\">(<\/span>27, <span class=\"s1\">'moderate'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'avoid-implicit'<\/span>: <span class=\"o\">(<\/span>28, <span class=\"s1\">'safety'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'latest'<\/span>: <span class=\"o\">(<\/span>29, <span class=\"s1\">'safety'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'package-latest'<\/span>: <span class=\"o\">(<\/span>30, <span class=\"s1\">'safety'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'risky-file-permissions'<\/span>: <span class=\"o\">(<\/span>31, <span class=\"s1\">'safety'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'risky-octal'<\/span>: <span class=\"o\">(<\/span>32, <span class=\"s1\">'safety'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'risky-shell-pipe'<\/span>: <span class=\"o\">(<\/span>33, <span class=\"s1\">'safety'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'galaxy'<\/span>: <span class=\"o\">(<\/span>34, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'ignore-errors'<\/span>: <span class=\"o\">(<\/span>35, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'layout'<\/span>: <span class=\"o\">(<\/span>36, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-incorrect'<\/span>: <span class=\"o\">(<\/span>37, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-no-info'<\/span>: <span class=\"o\">(<\/span>38, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-no-tags'<\/span>: <span class=\"o\">(<\/span>39, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-video-links'<\/span>: <span class=\"o\">(<\/span>40, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-version'<\/span>: <span class=\"o\">(<\/span>41, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-unsupported-ansible'<\/span>: <span class=\"o\">(<\/span>42, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-changed-when'<\/span>: <span class=\"o\">(<\/span>43, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-changelog'<\/span>: <span class=\"o\">(<\/span>44, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-handler'<\/span>: <span class=\"o\">(<\/span>45, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'no-relative-paths'<\/span>: <span class=\"o\">(<\/span>46, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'max-block-depth'<\/span>: <span class=\"o\">(<\/span>47, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'max-tasks'<\/span>: <span class=\"o\">(<\/span>48, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'unsafe-loop'<\/span>: <span class=\"o\">(<\/span>49, <span class=\"s1\">'shared'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'avoid-dot-notation'<\/span>: <span class=\"o\">(<\/span>50, <span class=\"s1\">'production'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'disallowed-ignore'<\/span>: <span class=\"o\">(<\/span>51, <span class=\"s1\">'production'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'fqcn'<\/span>: <span class=\"o\">(<\/span>52, <span class=\"s1\">'production'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'import-task-no-when'<\/span>: <span class=\"o\">(<\/span>53, <span class=\"s1\">'production'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'meta-no-dependencies'<\/span>: <span class=\"o\">(<\/span>54, <span class=\"s1\">'production'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'single-entry-point'<\/span>: <span class=\"o\">(<\/span>55, <span class=\"s1\">'production'<\/span><span class=\"o\">)<\/span>, <span class=\"s1\">'use-loop'<\/span>: <span class=\"o\">(<\/span>56, <span class=\"s1\">'production'<\/span><span class=\"o\">)}<\/span>\r\nPassed with production profile: 0 failure<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>, 0 warning<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span> on 1 files.\r\n<\/code><\/pre>\n<h3>\u66f4\u6539\u914d\u7f6e\u6587\u4ef6\u7684\u8def\u5f84 \u3010-c, &#8211;config-file\u3011<\/h3>\n<p>Ansible lint\u7684\u914d\u7f6e\u6587\u4ef6\u53ef\u4ee5\u901a\u8fc7\u653e\u7f6e\u5728\u9879\u76ee\u4e2d\u7684 .ansible-lint \u6216 .config\/ansible-lint.yml \u4e2d\u7684\u4efb\u610f\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5728\u8fd0\u884c\u65f6\u53cd\u6620\u5176\u5185\u5bb9\u3002<\/p>\n<p>\u5982\u679c\u6839\u636e\u60c5\u51b5\u9700\u8981\u66f4\u6539\u8bbe\u7f6e\u6587\u4ef6\u7684\u8def\u5f84\uff08\u4f8b\u5982\u5728\u5f00\u53d1\u548c\u751f\u4ea7\u73af\u5883\u4e2d\u9700\u8981\u66f4\u6539Ansible lint\u7684\u8bbe\u7f6e\uff09\uff0c\u53ef\u4ee5\u901a\u8fc7\u6307\u5b9a\u8def\u5f84\u6765\u8fdb\u884c\u66f4\u6539\u3002<\/p>\n<h3>\u4e0d\u9700\u8981\u4ecerequirements.yml\u5b89\u88c5 \u3010&#8211;offline\u3011<\/h3>\n<p>\u53ef\u80fd\u662f\u70ba\u4e86\u8207 Ansible lint \u4ee5\u5916\u7684\u5de5\u5177\u9032\u884c\u5354\u4f5c\u800c\u6e96\u5099\u7684\u795e\u79d8\u9078\u9805\u3002<\/p>\n<h3>\u663e\u793aAnsible lint\u7684\u7248\u672c\u3010&#8211;version\u3011\u3002<\/h3>\n<p>\u663e\u793aAnsible lint\u7684\u7248\u672c\u4fe1\u606f\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible-lint <span class=\"nt\">--version<\/span>\r\n\r\nansible-lint 6.8.6 using ansible 2.13.6\r\n<\/code><\/pre>\n<p>\u5982\u679c\u9700\u8981Ansible\u7684\u7248\u672c\u4fe1\u606f\u7b49\uff0c\u8bf7\u540c\u65f6\u6267\u884cansible &#8211;version\u548cansible-community &#8211;version\u3002<\/p>\n<pre class=\"post-pre\"><code>ansible <span class=\"nt\">--version<\/span>\r\nansible <span class=\"o\">[<\/span>core 2.13.5]\r\n  config file <span class=\"o\">=<\/span> None\r\n  configured module search path <span class=\"o\">=<\/span> <span class=\"o\">[<\/span><span class=\"s1\">'\/home\/mamono210\/.ansible\/plugins\/modules'<\/span>, <span class=\"s1\">'\/usr\/share\/ansible\/plugins\/modules'<\/span><span class=\"o\">]<\/span>\r\n  ansible python module location <span class=\"o\">=<\/span> \/home\/mamono210\/.local\/lib\/python3.11\/site-packages\/ansible\r\n  ansible collection location <span class=\"o\">=<\/span> \/home\/mamono210\/.ansible\/collections:\/usr\/share\/ansible\/collections\r\n  executable location <span class=\"o\">=<\/span> \/home\/mamono210\/.local\/bin\/ansible\r\n  python version <span class=\"o\">=<\/span> 3.11.0 <span class=\"o\">(<\/span>main, Oct 25 2022, 05:00:36<span class=\"o\">)<\/span> <span class=\"o\">[<\/span>GCC 10.2.1 20210110]\r\n  jinja version <span class=\"o\">=<\/span> 3.1.2\r\n  libyaml <span class=\"o\">=<\/span> True\r\n\r\nansible-community <span class=\"nt\">--version<\/span>\r\nAnsible community version 6.5.0\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u662fAnsible lint Advent Calendar 2022\u7684\u7b2c\u4e8c\u7bc7\u6587\u7ae0\u3002 \u8fd9\u6b21\u6211\u4eec\u5c06\u89e3\u91ca\u4e00\u4e0bAn [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-42352","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Ansible lint\u547d\u4ee4\u7684\u9009\u9879 - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint\u547d\u4ee4\u7684\u9009\u9879\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ansible lint\u547d\u4ee4\u7684\u9009\u9879\" \/>\n<meta property=\"og:description\" content=\"\u672c\u6587\u662fAnsible lint Advent Calendar 2022\u7684\u7b2c\u4e8c\u7bc7\u6587\u7ae0\u3002 \u8fd9\u6b21\u6211\u4eec\u5c06\u89e3\u91ca\u4e00\u4e0bAn [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint\u547d\u4ee4\u7684\u9009\u9879\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-10T14:36:21+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-29T02:49:37+00:00\" \/>\n<meta name=\"author\" content=\"\u9038, \u79d1\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u9038, \u79d1\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"55 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/\",\"name\":\"Ansible lint\u547d\u4ee4\u7684\u9009\u9879 - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2022-12-10T14:36:21+00:00\",\"dateModified\":\"2024-04-29T02:49:37+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ansible lint\u547d\u4ee4\u7684\u9009\u9879\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487\",\"name\":\"\u9038, \u79d1\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g\",\"caption\":\"\u9038, \u79d1\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keyi\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ansible lint\u547d\u4ee4\u7684\u9009\u9879 - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint\u547d\u4ee4\u7684\u9009\u9879\/","og_locale":"zh_CN","og_type":"article","og_title":"Ansible lint\u547d\u4ee4\u7684\u9009\u9879","og_description":"\u672c\u6587\u662fAnsible lint Advent Calendar 2022\u7684\u7b2c\u4e8c\u7bc7\u6587\u7ae0\u3002 \u8fd9\u6b21\u6211\u4eec\u5c06\u89e3\u91ca\u4e00\u4e0bAn [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint\u547d\u4ee4\u7684\u9009\u9879\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2022-12-10T14:36:21+00:00","article_modified_time":"2024-04-29T02:49:37+00:00","author":"\u9038, \u79d1","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u9038, \u79d1","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"55 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/","name":"Ansible lint\u547d\u4ee4\u7684\u9009\u9879 - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2022-12-10T14:36:21+00:00","dateModified":"2024-04-29T02:49:37+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"Ansible lint\u547d\u4ee4\u7684\u9009\u9879"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487","name":"\u9038, \u79d1","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g","caption":"\u9038, \u79d1"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keyi\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/ansible-lint%e5%91%bd%e4%bb%a4%e7%9a%84%e9%80%89%e9%a1%b9\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/42352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=42352"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/42352\/revisions"}],"predecessor-version":[{"id":84824,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/42352\/revisions\/84824"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=42352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=42352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=42352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}