├── .gitignore ├── LICENSE ├── README.md ├── Vagrantfile ├── ansible.cfg ├── hiera-lookup-example.yml ├── hiera_sample ├── data │ ├── global.yaml │ ├── nodes │ │ ├── puppet01.localdomain.yaml │ │ └── puppet01.yaml │ └── production.yaml └── hiera.yaml ├── inventories └── puppetmaster_example_inv ├── library └── hiera.py ├── plugins └── lookup │ └── hiera.py ├── puppetmaster-example.yml ├── samples ├── Hiera-Lookup.md ├── Puppetmaster.md └── Stand-Alone.md ├── stand-alone-example.yml ├── utils ├── bootstrap.sh └── hiera_prepare.sh └── vagrant_env └── environment.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | 64 | 65 | # Other Stuff 66 | .vagrant/ 67 | .virtualenv 68 | *.retry 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | Hiera-Ansible Module 294 | Copyright (C) 2016 Juan Manuel Parrilla Madrid 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hiera-Ansible retriever 2 | 3 | ## Why? 4 | I need a way to centralize all variables that I will use into Puppet and Ansible, 5 | this is a great and simple way to do it. 6 | 7 | ### Requirements 8 | - Must be executed into Puppet Master: 9 | - Because of how Hiera/Puppet/Ansible works, it's necessary to copy 10 | Hiera Data and Hiera config to destination node to be parsed (instead of 11 | you already got it into a DB Backend) (This module will works perfectly 12 | with an remote backend only you will need the Hiera Config). 13 | - Hiera as a requirement installed into destination nodes. 14 | - Hiera config File into destination nodes (With the same hierarchi as you need). 15 | - Hiera Lookup is also a must to be executed on the Puppetmaster/Hiera node to works propertly, because of how Lookups works in ansible _all lookup plugins only are executed on the ansible host, agains for example a module, that could be executed remotely_ 16 | 17 | #### Capabilities: 18 | - Use Hiera Data into your Ansible Playbooks/Roles allowing centralization of 19 | Key/Value Data in a Git repository. 20 | - Could be executed agains almost all hierarchi (Just add more context) 21 | - You could use every hiera data type, and will be ready to use into Ansible as 22 | a Fact 23 | 24 | #### How Can I use it into my Ansible Playbooks/Roles 25 | Just copy the 'library' folder into your project and use the Hiera-Ansible module 26 | as we show into the examples. 27 | 28 | ### Examples 29 | - [Stand-Alone node (no Puppetmaster)](samples/Stand-Alone.md) 30 | - [Hiera Lookup (on a Puppetmaster)](samples/Hiera-Lookup.md) 31 | - [With Puppetmaster against remote/s node/s](samples/Puppetmaster.md) 32 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | require 'yaml' 4 | 5 | ENVIRONMENT_FILE = 'vagrant_env/environment.yaml' 6 | 7 | unless Vagrant.has_plugin?("vagrant-hostmanager") 8 | raise 'vagrant-hostmanager is not installed!' 9 | end 10 | 11 | unless defined? ENVIRONMENT 12 | environment_file = File.join(File.dirname(__FILE__), ENVIRONMENT_FILE) 13 | ENVIRONMENT = YAML.load(File.open(environment_file, File::RDONLY).read) 14 | end 15 | 16 | Vagrant.configure(2) do |config| 17 | config.hostmanager.enabled = true 18 | config.hostmanager.manage_host = true 19 | config.hostmanager.ignore_private_ip = false 20 | config.hostmanager.include_offline = true 21 | ENVIRONMENT.each do |name, details| 22 | config.vm.define name do |node| 23 | node.vm.box = details['box'] 24 | node.vm.hostname = name 25 | #node.vm.network :private_network, ip: details['address'] 26 | #node.vm.network "public_network", bridge: "en2: Wi-Fi (AirPort)" 27 | node.vm.network "public_network", bridge: "en1: Ethernet 2" 28 | node.vm.provider 'virtualbox' do |vb| 29 | vb.customize ['modifyvm', :id, '--memory', details['memory']] 30 | vb.customize ['modifyvm', :id, '--cpus', details['cpus']] 31 | end 32 | if details.has_key?('storage') 33 | node.vm.provider 'virtualbox' do |vb| 34 | unless File.exist?("#{name}.vdi") 35 | vb.customize ['createhd', '--filename', "#{name}.vdi", '--size', details['storage'] * 1024] 36 | vb.customize ["storagectl", :id, "--name", "SCSI Controller", "--add", "scsi"] 37 | end 38 | vb.customize ['storageattach', :id, '--storagectl', 'SCSI Controller', '--port', details['storage_port'], '--device', 0, '--type', 'hdd', '--medium', "#{name}.vdi"] 39 | end 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | lookup_plugins = ./plugins/lookup 3 | nocows = 1 4 | retry_files_enabled = False 5 | [privilege_escalation] 6 | [paramiko_connection] 7 | [ssh_connection] 8 | control_path = %(directory)s/ansible-ssh-%%C 9 | [accelerate] 10 | [selinux] 11 | [colors] 12 | -------------------------------------------------------------------------------- /hiera-lookup-example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Get Facts from Hiera Data 3 | hosts: nodes 4 | become: yes 5 | connection: local 6 | tasks: 7 | - name: 'Get Hiera Variables' 8 | set_fact: 9 | hiera_get_test: "{{ lookup('hiera', 'line environment=production') }}" 10 | hiera_get_test1: "{{ lookup('hiera', 'test1') }}" 11 | 12 | - debug: var=item 13 | with_items: 14 | - "{{ hiera_get_test }}" 15 | - "{{ hiera_get_test1 }}" 16 | -------------------------------------------------------------------------------- /hiera_sample/data/global.yaml: -------------------------------------------------------------------------------- 1 | proxy::test: '00' 2 | test1: '01' 3 | test2: '02' 4 | test3: '03' 5 | test4: '04' 6 | test5: '05' 7 | -------------------------------------------------------------------------------- /hiera_sample/data/nodes/puppet01.localdomain.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | proxy::array_multi: 3 | - 'Test' 4 | - 'Into' 5 | - 'FQDN' 6 | proxy::array_line: [ 'PRO002', 'PRO012', 'PRO022', 'PRO032' ] 7 | line: 'PRO05' 8 | test4: '04' 9 | test5: '05' 10 | -------------------------------------------------------------------------------- /hiera_sample/data/nodes/puppet01.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | proxy::array_multi: 3 | - 'Test' 4 | - 'Into' 5 | - 'Hostname' 6 | proxy::array_line: [ 'PRO005', 'PRO015', 'PRO025', 'PRO035' ] 7 | line: 'PRO07' 8 | test4: '01111111' 9 | test5: '05222222' 10 | -------------------------------------------------------------------------------- /hiera_sample/data/production.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | proxy::array_multi: 3 | - 'Test' 4 | - 'In' 5 | - 'Production' 6 | - 'Environment' 7 | proxy::array_line: [ 'PRO00', 'PRO01', 'PRO02', 'PRO03' ] 8 | line: 'PRO05' 9 | test4: '04' 10 | test5: '05' 11 | -------------------------------------------------------------------------------- /hiera_sample/hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | :backends: 3 | - yaml 4 | :hierarchy: 5 | - "nodes/%{fqdn}" 6 | - "%{environment}" 7 | - global 8 | 9 | :yaml: 10 | :datadir: 11 | -------------------------------------------------------------------------------- /inventories/puppetmaster_example_inv: -------------------------------------------------------------------------------- 1 | [nodes] 2 | vagrantServer ansible_ssh_host=puppet01.localdomain ansible_ssh_port=22 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant 3 | -------------------------------------------------------------------------------- /library/hiera.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Hiera-Ansible Parser. 5 | 6 | # This module is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software. If not, see . 18 | 19 | """ 20 | 21 | DOCUMENTATION = ''' 22 | --- 23 | module: hiera 24 | version_added: "2.1" 25 | short_description: Use Hiera key/values into Ansible as fact. 26 | author: "Juan Manuel Parrilla @kerbeross jparrill@redhat.com" 27 | description: 28 | - Once copied all Hiera Data from PuppetMaster and Hiera.yaml into destination node, this module will parse all key-value that you need and create node facts in execution time 29 | options: 30 | path: 31 | description: 32 | - Hiera executable path in destination node. This bin will be executed to follow all hierarchi and get data from hiera 33 | required: false 34 | default: hiera 35 | fact: 36 | description: 37 | - This is a fact name where you want to save your variable from Hiera. 38 | required: false 39 | key: 40 | description: 41 | - This is the Hiera variable name that you want to get. 42 | required: true 43 | aliases: ['name'] 44 | context: 45 | description: 46 | - This key value will set the scope of hiera key/value. Also will follow the hiera's hierarchi, then if you dont have any variable in the first scope will go down to the next one. 47 | required: false 48 | source: 49 | description: 50 | - The hiera config file path, if you want to custom every query with multiple hierarchies 51 | required: false 52 | ''' 53 | 54 | EXAMPLES = ''' 55 | # Without Puppetmaster example, stand-alone node 56 | --- 57 | - name: Test 58 | hosts: 127.0.0.1 59 | tasks: 60 | - name: Retrieving Hiera Data 61 | hiera: path=/bin/hiera key="{{ item.value }}" fact="{{ item.key }}" source=/etc/hiera.yaml 62 | args: 63 | context: 64 | environment: 'production' 65 | fqdn: 'puppet01.localdomain' 66 | with_dict: 67 | var_array_multi: "proxy::array_multi" 68 | var_array_line: "proxy::array_line" 69 | line: "line" 70 | 71 | - debug: msg="{{ item }}" 72 | with_items: var_array_multi 73 | - debug: msg="{{ item }}" 74 | with_items: var_array_line 75 | - debug: msg="{{ line }}" 76 | 77 | # Puppetmaster example 78 | --- 79 | - name: Create Facts with Hiera Data 80 | hosts: nodes 81 | sudo: yes 82 | tasks: 83 | - name: Copy Hiera Data into Destination node 84 | copy: src=/var/lib/hiera/ dest=/var/lib/ 85 | 86 | - name: Copy Hiera Config into Destination node 87 | copy: src=/etc/hiera.yaml dest=/etc/hiera.yaml 88 | 89 | - name: Retrieving Hiera Data 90 | hiera: path=/bin/hiera key="{{ item.value }}" fact="{{ item.key }}" source=/etc/hiera.yaml 91 | args: 92 | context: 93 | environment: 'production' 94 | fqdn: 'puppet01.localdomain' 95 | with_dict: 96 | var_array_multi: "proxy::array_multi" 97 | var_array_line: "proxy::array_line" 98 | line: "line" 99 | 100 | - debug: msg="{{ item }}" 101 | with_items: var_array_multi 102 | - debug: msg="{{ item }}" 103 | with_items: var_array_line 104 | - debug: msg="{{ line }}" 105 | ''' 106 | 107 | RETURN = ''' 108 | path: 109 | description: bin for hiera execution 110 | returned: success 111 | type: string 112 | sample: "/path/to/file" 113 | environment: 114 | description: scope to be interpreted by hiera 115 | returned: success even the scope does not exists 116 | type: string 117 | sample: "production" 118 | fqdn: 119 | description: other scope for hiera parse 120 | returned: success even the scope does not exists 121 | type: string 122 | sample: "" 123 | key: 124 | description: hiera's value name 125 | returned: success 126 | type: string 127 | sample: "proxy::array_multi" 128 | fact: 129 | description: variable where store the Hiera's value 130 | returned: success 131 | type: string 132 | sample: "var_array_multi" 133 | source: 134 | description: hiera config file 135 | returned: success 136 | type: string 137 | sample: "/path/to/hiera.yaml" 138 | ''' 139 | 140 | 141 | def main(): 142 | """ 143 | Main function. 144 | This module will parse your hiera hierarchi and will return the required 145 | values 146 | - key: Is the key name of the hiera variable 147 | - fact: Is the key name that must store the hiera output 148 | - args: context: must contain all the values that identify the node against hiera 149 | - path: hiera executable 150 | - source: hiera config file 151 | WARNING: This module try to solve a disparity between arch of 152 | Puppet/Hiera and Ansible, because of how they works (Puppet compile 153 | the values into puppet master node) (Ansible are executed into 154 | destination node and have not access to Hiera backend directly) 155 | 156 | """ 157 | module = AnsibleModule( 158 | argument_spec=dict( 159 | name=dict(required=True, aliases=['key']), 160 | fact=dict(required=False), 161 | path=dict(required=False, default="hiera"), 162 | context=dict(required=False, default={}, type='dict'), 163 | source=dict(required=False, default=None) 164 | ) 165 | ) 166 | 167 | params = module.params 168 | out = {} 169 | 170 | if not params['fact']: 171 | params['fact'] = params['name'] 172 | 173 | try: 174 | pargs = [params['path']] 175 | 176 | if params['source']: 177 | pargs.extend(['-c', params['source']]) 178 | 179 | pargs.append(params['name']) 180 | pargs.extend( 181 | [r'%s=%s' % (k, v) for k, v in params['context'].iteritems()] 182 | ) 183 | 184 | rc, output, tmp = module.run_command(pargs) 185 | 186 | # Debug 187 | # module.exit_json(changed=True, something_else=pargs) 188 | # module.exit_json(changed=True, something_else=output.strip('\n')) 189 | # 190 | out['ansible_facts'] = {} 191 | out['ansible_facts'][params['fact']] = output.strip('\n') 192 | 193 | module.exit_json(**out) 194 | 195 | except Exception, e: 196 | module.fail_json(msg=str(e)) 197 | 198 | # import module snippets 199 | from ansible.module_utils.basic import * 200 | main() 201 | -------------------------------------------------------------------------------- /plugins/lookup/hiera.py: -------------------------------------------------------------------------------- 1 | # (c) 2017, Juan Manuel Parrilla 2 | # 3 | # This file is part of Ansible 4 | # 5 | # Ansible is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Ansible is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Ansible. If not, see . 17 | ''' 18 | DOCUMENTATION: 19 | author: 20 | - Juan Manuel Parrilla (@jparrill) 21 | lookup: hiera 22 | version_added: "2.4" 23 | short_description: get info from hiera data 24 | description: 25 | - Retrieves data from an Puppetmaster node Using 26 | Hiera as ENC 27 | options: 28 | _hiera_key: 29 | description: 30 | - the list of keys to lookup on the Puppetmaster 31 | type: list 32 | element_type: string 33 | required: True 34 | _bin_file: 35 | description: 36 | - Binary file to execute Hiera 37 | default: '/usr/bin/hiera' 38 | env_vars: 39 | - name: ANSIBLE_HIERA_BIN 40 | _hierarchy_file: 41 | description: 42 | - File that describes the hierarchy of Hiera 43 | default: '/etc/hiera.yaml' 44 | env_vars: 45 | - name: ANSIBLE_HIERA_CFG 46 | EXAMPLES: 47 | All this examples depends on hiera.yml that describes the 48 | hierarchy 49 | 50 | - name: "a value from Hiera 'DB'" 51 | debug: msg={{ lookup('hiera', 'foo') }} 52 | 53 | - name: "a value from a Hiera 'DB' on other environment" 54 | debug: msg={{ lookup('hiera', 'foo environment=production') }} 55 | 56 | - name: "a value from a Hiera 'DB' for a concrete node" 57 | debug: msg={{ lookup('hiera', 'foo fqdn=puppet01.localdomain') }} 58 | RETURN: 59 | _list: 60 | description: 61 | - a value associated with input key 62 | type: strings 63 | ''' 64 | from __future__ import (absolute_import, division, print_function) 65 | __metaclass__ = type 66 | 67 | import os 68 | from ansible.plugins.lookup import LookupBase 69 | from ansible.utils.cmd_functions import run_cmd 70 | 71 | if os.getenv('ANSIBLE_HIERA_CFG') is not None: 72 | ANSIBLE_HIERA_CFG = os.environ['ANSIBLE_HIERA_CFG'] 73 | else: 74 | ANSIBLE_HIERA_CFG = '/etc/hiera.yaml' 75 | 76 | if os.getenv('ANSIBLE_HIERA_BIN') is not None: 77 | ANSIBLE_HIERA_BIN = os.environ['ANSIBLE_HIERA_BIN'] 78 | else: 79 | ANSIBLE_HIERA_BIN = '/usr/bin/hiera' 80 | 81 | class Hiera(object): 82 | def get(self, hiera_key): 83 | ## Bin and Cfg file 84 | pargs = [ANSIBLE_HIERA_BIN] 85 | pargs.extend(['-c', ANSIBLE_HIERA_CFG]) 86 | 87 | ## Get Var 88 | pargs.extend(hiera_key) 89 | 90 | ## Run Command 91 | rc, output, err = run_cmd("{} -c {} {}".format( 92 | ANSIBLE_HIERA_BIN, ANSIBLE_HIERA_CFG, hiera_key[0])) 93 | 94 | return output.strip() 95 | 96 | class LookupModule(LookupBase): 97 | def run(self, terms, variables=''): 98 | hiera = Hiera() 99 | ret = [] 100 | 101 | ret.append(hiera.get(terms)) 102 | return ret 103 | 104 | -------------------------------------------------------------------------------- /puppetmaster-example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create Facts with Hiera Data 3 | hosts: nodes 4 | become: yes 5 | tasks: 6 | - name: Copy Hiera Data into Destination node 7 | copy: src=/var/lib/hiera/ dest=/var/lib/ 8 | 9 | - name: Copy Hiera Config into Destination node 10 | copy: src=/etc/hiera.yaml dest=/etc/hiera.yaml 11 | 12 | - name: Retrieving Hiera Data 13 | hiera: 14 | path: /bin/hiera 15 | key: "{{ item.value }}" 16 | fact: "{{ item.key }}" 17 | source: /etc/hiera.yaml 18 | args: 19 | context: 20 | environment: 'production' 21 | fqdn: 'puppet01.localdomain' 22 | with_dict: 23 | var_array_multi: "proxy::array_multi" 24 | var_array_line: "proxy::array_line" 25 | line: "line" 26 | 27 | - debug: msg="{{ item }}" 28 | with_items: var_array_multi 29 | - debug: msg="{{ item }}" 30 | with_items: var_array_line 31 | - debug: msg="{{ line }}" 32 | -------------------------------------------------------------------------------- /samples/Hiera-Lookup.md: -------------------------------------------------------------------------------- 1 | # Hiera Lookup Execution 2 | This example will try to consume variables in an existant Hiera/Puppetmaster environment. 3 | 4 | ## Test with Vagrant 5 | 6 | - Clone the repository and go to the folder to see the __Vagrantfile__, then execute the next: 7 | 8 | ``` 9 | ➜ vagrant up 10 | Bringing machine 'puppet01.localdomain' up with 'virtualbox' provider... 11 | ==> puppet01.localdomain: Importing base box 'centos/7'... 12 | ==> puppet01.localdomain: Matching MAC address for NAT networking... 13 | ==> puppet01.localdomain: Checking if box 'centos/7' is up to date... 14 | .... 15 | .... 16 | ==> puppet01.localdomain: Configuring and enabling network interfaces... 17 | puppet01.localdomain: SSH address: 127.0.0.1:2222 18 | puppet01.localdomain: SSH username: vagrant 19 | puppet01.localdomain: SSH auth method: private key 20 | ==> puppet01.localdomain: Rsyncing folder: /home/jparrill/projects/ansible-hiera/ => /vagrant 21 | ==> puppet01.localdomain: [vagrant-hostmanager:guests] Updating hosts file on active guest virtual machines... 22 | ==> puppet01.localdomain: [vagrant-hostmanager:host] Updating hosts file on your workstation (password may be required)... 23 | 24 | ➜ vagrant ssh 25 | [vagrant@puppet01 ~]$ sudo su 26 | [root@puppet01 vagrant]# cd /vagrant/utils 27 | [root@puppet01 utils]# bash hiera_prepare.sh 28 | ... 29 | ... 30 | ... 31 | ``` 32 | 33 | ## Test the Lookup plugin 34 | 35 | - hiera-lookup-example.yml: 36 | 37 | ``` 38 | --- 39 | - name: Create Facts with Hiera Data 40 | hosts: nodes 41 | become: yes 42 | connection: local 43 | tasks: 44 | - name: 'Get Hiera Variables' 45 | set_fact: 46 | hiera_get_test: "{{ lookup('hiera', 'line environment=production') }}" 47 | hiera_get_test1: "{{ lookup('hiera', 'test1') }}" 48 | 49 | - debug: var=item 50 | with_items: 51 | - "{{ hiera_get_test }}" 52 | - "{{ hiera_get_test1 }}" 53 | ``` 54 | 55 | - Inventory: 56 | 57 | ``` 58 | [nodes] 59 | vagrantServer ansible_ssh_host=192.168.1.138 ansible_ssh_port=22 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant 60 | ``` 61 | 62 | - Command Execution: 63 | 64 | ``` 65 | ansible-playbook -i inventories/puppetmaster_example_inv -l nodes hiera_lookup.yml 66 | ``` 67 | 68 | - Output: 69 | 70 | ``` 71 | PLAY [Create Facts with Hiera Data] ********************************************************************************************************************************************************************************************************** 72 | 73 | TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************** 74 | fatal: [vagrantServer]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: percent_expand: unknown key %C\r\n", "unreachable": true} 75 | 76 | PLAY RECAP *********************************************************************************************************************************************************************************************************************************** 77 | vagrantServer : ok=0 changed=0 unreachable=1 failed=0 78 | 79 | [root@puppet01 vagrant]# vi hiera_lookup.yml 80 | [root@puppet01 vagrant]# ansible-playbook -i inventories/puppetmaster_example_inv -l nodes hiera_lookup.yml 81 | 82 | PLAY [Create Facts with Hiera Data] ********************************************************************************************************************************************************************************************************** 83 | 84 | TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************** 85 | ok: [vagrantServer] 86 | 87 | TASK [Get Hiera Variables] ******************************************************************************************************************************************************************************************************************* 88 | ok: [vagrantServer] 89 | 90 | TASK [debug] ********************************************************************************************************************************************************************************************************************************* 91 | ok: [vagrantServer] => (item=01) => { 92 | "item": "01" 93 | } 94 | ok: [vagrantServer] => (item=PRO05) => { 95 | "item": "PRO05" 96 | } 97 | 98 | PLAY RECAP *********************************************************************************************************************************************************************************************************************************** 99 | vagrantServer : ok=3 changed=0 unreachable=0 failed=0 100 | 101 | ``` 102 | -------------------------------------------------------------------------------- /samples/Puppetmaster.md: -------------------------------------------------------------------------------- 1 | # Puppetmaster Execution 2 | This example will copy your HieraData folder (/var/lib/hiera) to the destination 3 | nodes, also will copy the hiera.yaml config file and will show from Ansible Debug 4 | sentence, all the key/value that you require into your task. This example are executed from our **Puppetmaster**. 5 | 6 | - puppetmaster-example Playbook: 7 | 8 | ``` 9 | --- 10 | - name: Create Facts with Hiera Data 11 | hosts: nodes 12 | sudo: yes 13 | tasks: 14 | - name: Copy Hiera Data into Destination node 15 | copy: src=/var/lib/hiera/ dest=/var/lib/ 16 | 17 | - name: Copy Hiera Config into Destination node 18 | copy: src=/etc/hiera.yaml dest=/etc/hiera.yaml 19 | 20 | - name: Retrieving Hiera Data 21 | hiera: path=/bin/hiera key="{{ item.value }}" fact="{{ item.key }}" source=/etc/hiera.yaml 22 | args: 23 | context: 24 | environment: 'production' 25 | fqdn: 'puppet01.localdomain' 26 | with_dict: 27 | var_array_multi: "proxy::array_multi" 28 | var_array_line: "proxy::array_line" 29 | line: "line" 30 | 31 | - debug: msg="{{ item }}" 32 | with_items: var_array_multi 33 | - debug: msg="{{ item }}" 34 | with_items: var_array_line 35 | - debug: msg="{{ line }}" 36 | ``` 37 | 38 | - Inventory: 39 | 40 | ``` 41 | [nodes] 42 | vagrantServer ansible_ssh_host=192.168.1.138 ansible_ssh_port=22 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant 43 | ``` 44 | 45 | - Command Execution: 46 | 47 | ``` 48 | ansible-playbook -i inventories/puppetmaster_example_inv puppetmaster-example.yml 49 | ``` 50 | 51 | - Example Output: 52 | 53 | ``` 54 | [root@sat61 ansible]# ansible-playbook -i inventories/puppetmaster_example_inv puppetmaster-example.yml 55 | 56 | PLAY [Create Facts with Hiera Data] ******************************************* 57 | 58 | GATHERING FACTS *************************************************************** 59 | ok: [vagrantServer] 60 | 61 | TASK: [Copy Hiera Data into Destination node] ********************************* 62 | ok: [vagrantServer] 63 | 64 | TASK: [Copy Hiera Config into Destination node] ******************************* 65 | ok: [vagrantServer] 66 | 67 | TASK: [Retrieving Hiera Data] ************************************************* 68 | ok: [vagrantServer] => (item={'key': 'var_array_line', 'value': 'proxy::array_line'}) 69 | ok: [vagrantServer] => (item={'key': 'line', 'value': 'line'}) 70 | ok: [vagrantServer] => (item={'key': 'var_array_multi', 'value': 'proxy::array_multi'}) 71 | 72 | TASK: [debug msg="{{ item }}"] ************************************************ 73 | ok: [vagrantServer] => (item=HIERA2) => { 74 | "item": "HIERA2", 75 | "msg": "HIERA2" 76 | } 77 | ok: [vagrantServer] => (item=GIGANTE2) => { 78 | "item": "GIGANTE2", 79 | "msg": "GIGANTE2" 80 | } 81 | ok: [vagrantServer] => (item=PARA2) => { 82 | "item": "PARA2", 83 | "msg": "PARA2" 84 | } 85 | ok: [vagrantServer] => (item=TI2) => { 86 | "item": "TI2", 87 | "msg": "TI2" 88 | } 89 | 90 | TASK: [debug msg="{{ item }}"] ************************************************ 91 | ok: [vagrantServer] => (item=PRO002) => { 92 | "item": "PRO002", 93 | "msg": "PRO002" 94 | } 95 | ok: [vagrantServer] => (item=PRO012) => { 96 | "item": "PRO012", 97 | "msg": "PRO012" 98 | } 99 | ok: [vagrantServer] => (item=PRO022) => { 100 | "item": "PRO022", 101 | "msg": "PRO022" 102 | } 103 | ok: [vagrantServer] => (item=PRO032) => { 104 | "item": "PRO032", 105 | "msg": "PRO032" 106 | } 107 | 108 | TASK: [debug msg="{{ line }}"] ************************************************ 109 | ok: [vagrantServer] => { 110 | "msg": "PRO05" 111 | } 112 | 113 | PLAY RECAP ******************************************************************** 114 | vagrantServer : ok=7 changed=0 unreachable=0 failed=0 115 | ``` 116 | -------------------------------------------------------------------------------- /samples/Stand-Alone.md: -------------------------------------------------------------------------------- 1 | # Stand-Alone node (no Puppetmaster) 2 | This Example is just to test the Hiera-Ansible module, no puppetmaster nor remote connections. You already have in the node all necessary to work well with Hiera and Ansible 3 | 4 | - You already have a hiera.yaml and HieraData in this remote node 5 | 6 | ``` 7 | [root@puppet01 vagrant]# tree /var/lib/hiera/ 8 | /var/lib/hiera/ 9 | ├── global.yaml 10 | ├── nodes 11 | │   ├── puppet01.localdomain.yaml 12 | │   └── puppet01.yaml 13 | └── production.yaml 14 | ``` 15 | 16 | - /etc/hiera.yaml 17 | 18 | ``` 19 | --- 20 | :backends: 21 | - yaml 22 | :hierarchy: 23 | - "nodes/%{fqdn}" 24 | - "%{environment}" 25 | - global 26 | 27 | :yaml: 28 | :datadir: 29 | ``` 30 | 31 | - stand-alone-example.yml: 32 | 33 | ``` 34 | - name: Test 35 | hosts: 127.0.0.1 36 | tasks: 37 | - name: Retrieving Hiera Data 38 | hiera: path=/bin/hiera key="{{ item.value }}" fact="{{ item.key }}" source=/etc/hiera.yaml 39 | args: 40 | context: 41 | environment: 'production' 42 | fqdn: 'puppet01.localdomain' 43 | with_dict: 44 | var_array_multi: "proxy::array_multi" 45 | var_array_line: "proxy::array_line" 46 | line: "line" 47 | 48 | - debug: msg="{{ item }}" 49 | with_items: var_array_multi 50 | - debug: msg="{{ item }}" 51 | with_items: var_array_line 52 | - debug: msg="{{ line }}" 53 | ``` 54 | 55 | - Execution from Destination node: 56 | 57 | ``` 58 | [root@puppet01 vagrant]# ansible-playbook example.yml 59 | 60 | PLAY [Test] ******************************************************************* 61 | 62 | GATHERING FACTS *************************************************************** 63 | ok: [127.0.0.1] 64 | 65 | TASK: [Retrieving Hiera Data] ************************************************* 66 | ok: [127.0.0.1] => (item={'key': 'var_array_line', 'value': 'proxy::array_line'}) 67 | ok: [127.0.0.1] => (item={'key': 'line', 'value': 'line'}) 68 | ok: [127.0.0.1] => (item={'key': 'var_array_multi', 'value': 'proxy::array_multi'}) 69 | ... 70 | ... 71 | TASK: [debug msg="{{ item }}"] ************************************************ 72 | ok: [127.0.0.1] => (item=PRO002) => { 73 | "item": "PRO002", 74 | "msg": "PRO002" 75 | } 76 | ok: [127.0.0.1] => (item=PRO012) => { 77 | "item": "PRO012", 78 | "msg": "PRO012" 79 | } 80 | ok: [127.0.0.1] => (item=PRO022) => { 81 | "item": "PRO022", 82 | "msg": "PRO022" 83 | } 84 | ok: [127.0.0.1] => (item=PRO032) => { 85 | "item": "PRO032", 86 | "msg": "PRO032" 87 | } 88 | ... 89 | ... 90 | ``` 91 | -------------------------------------------------------------------------------- /stand-alone-example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Test 3 | hosts: 127.0.0.1 4 | tasks: 5 | - name: Retrieving Hiera Data 6 | hiera: path=/bin/hiera key="{{ item.value }}" fact="{{ item.key }}" source=/etc/hiera.yaml 7 | args: 8 | context: 9 | environment: 'production' 10 | fqdn: 'puppet01.localdomain' 11 | with_dict: 12 | var_array_multi: "proxy::array_multi" 13 | var_array_line: "proxy::array_line" 14 | line: "line" 15 | hierar: 'hierar' 16 | 17 | - debug: msg="{{ item }}" 18 | with_items: var_array_multi 19 | - debug: msg="{{ item }}" 20 | with_items: var_array_line 21 | - debug: msg="{{ line }}" 22 | - debug: msg="{{ hierar }}" 23 | -------------------------------------------------------------------------------- /utils/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function clean_repos() { 4 | for repo in `ls /etc/yum.repos.d/*.repo | grep -v epel.repo | grep -v redhat.repo` 5 | do 6 | rm -f $repo 7 | done 8 | } 9 | 10 | function register() { 11 | clean_repos 12 | rpm -Uvh http://sat61.localdomain/pub/katello-ca-consumer-latest.noarch.rpm 13 | subscription-manager register --org="Default_Organization" --activationkey="RHEL7" 14 | yum repolist 15 | yum install puppet -y 16 | cat > /etc/puppet/puppet.conf <