In my last post I already praised Packer. But there is one thing I really do not like about it: the main configuration file is JSON. Now JSON is a great format for many purposes, but I like to be able to simply comment stuff out while testing and I like to add real comments to such configuration files, whether they have to be maintained by someone else or by myself. And finally Packer templates contain a lot of duplication if you use multiple “builders” (for VMWare, VirtualBox etc.): configuration items like the iso file and the checksum are the same whether you build for VMWare or VirtualBox.
You might even have quite some duplication across multiple Packer templates. But Mitchell Hashimoto (the (main) author of Packer) has a point when he says:
“This is one of the primary reasons we chose JSON as the configuration format: it is highly convenient to write a script to generate the configuration.” (See the comment in this issue)
Now the original author of that issue wanted an ‘include’ mechanism and pasted some Python code to achieve that. I additionally wanted to avoid duplication in a single file and came up with a script, that allows me to use YAML “merge keys”:
--- _macros: - &basic_builder iso_url: 'CentOS-6.5-x86_64-bin-DVD1.iso' iso_checksum: '0d9dc37b5dd4befa1c440d2174e88a87' iso_checksum_type: md5 ... builders: - <<: *basic_builder type: virtualbox-iso ... - <<: *basic_builder type: vmware-iso ...
&basic_builder gets copied wherever a
<<: *basic_builder occurs. You can add and even override items. This is plain YAML. The only problem: the original entry
&basic_builder will be in the result document. Therefore the script removes any top level (!)
To get me started I converted the existing JSON to YAML with the same script. Depending on the extension of the input file either JSON or YAML is created:
usage: yaml-to-json.py [-h] [--force] SOURCEFILE Convert YAML to JSON (and vice versa) positional arguments: SOURCEFILE the file name to be converted. If it ends with '.json' a YAML file will be created. All other file extensions are assumed to by YAML and a JSON file will be created optional arguments: -h, --help show this help message and exit --force overwrite target file, even if it is newer than the source file