github.com/hashicorp/packer@v1.14.3/website/content/docs/templates/json_to_hcl.mdx (about) 1 --- 2 description: | 3 Learn about the differences between JSON and HCL2 templates and how converting templates to HCL affects plugins. 4 page_title: Differences between HCL2 and JSON templates 5 --- 6 7 # Differences between HCL2 and JSON templates 8 9 This document explains the differences between JSON to HCL2 templates, including how converting JSON templates to HCL2 affects builder, provisioner, and post-processor behavior. 10 11 ## Introduction 12 13 Packer uses JSON or HCL2 templates to orchestrate builds for one or more artifacts. 14 15 In [legacy JSON templates](/packer/docs/templates/legacy_json_templates), declare a series of builders, provisioners, and post-processors to build images. 16 17 In [HCL2 templates](/packer/docs/templates/hcl_templates), you can specify builders through sources and collect them into build blocks. 18 19 You can use the `packer hcl2_upgrade` command when converting your existing JSON templates to HCL2. Refer to the [hcl2_upgrade](/packer/docs/commands/hcl2_upgrade) page for more information on its usage. 20 21 22 ## Builders 23 24 Builders are components that are specialized for a platform. 25 Their role is to set the stage for the steps that will let you build the final image from your configuration template. 26 27 ### JSON 28 29 In JSON, the `builders` attribute declares how a builder will be invoked to build an image. 30 31 ```json 32 { 33 "builders": [ 34 { 35 "type": "null", 36 "name": "test", 37 "communicator": "none" 38 } 39 ] 40 } 41 ``` 42 43 ### HCL2 44 45 In HCL2, builders are declared through a `source` block. Sources on their own are not enough, and must be invoked in a `build` block. 46 The `build` block serves as a container for all the steps (i.e. `source`, `provisioners` and `post-processors`) to go from a blank image to a finished one. 47 48 ```hcl 49 source "null" "test" { 50 communicator = "none" 51 } 52 53 build { 54 sources = ["null.test"] 55 } 56 ``` 57 58 ## Provisioners 59 60 Provisioners are components that modify the state of the machine image you are building. 61 They can be used for installing packages, writing data to the remote file system, or executing remote commands. 62 They can be defined in both JSON or HCL templates. 63 64 ### JSON 65 66 In a JSON template, provisioners are declared at the top-level of the template as an array of sequentially 67 invoked components to provision the image you are building. They apply to all the builders defined in the template. 68 69 ```json 70 { 71 "builders": [ 72 { 73 "type": "null", 74 "name": "test", 75 "communicator": "none" 76 } 77 ], 78 "provisioners": [ 79 { 80 "type": "shell-local", 81 "inline": ["echo test"] 82 } 83 ] 84 } 85 ``` 86 87 ### HCL2 88 89 In HCL2, provisioners are declared in the `build` block, and apply only to the sources invoked as 90 part of this build block. 91 This lets you declare multiple build blocks, each with its own set of provisioners, which will 92 result in multiple different builds executed in parallel. 93 94 ```hcl 95 source "null" "test" { 96 communicator = "none" 97 } 98 99 build { 100 sources = ["null.test"] 101 102 provisioner "shell-local" { 103 inline = ["echo test"] 104 } 105 } 106 ``` 107 108 ## Post-processors 109 110 Post-processors are components that are invoked after the image was produced. Their 111 role is to consume an artifact produced by a builder, or another post-processor, and 112 build a new artifact from that. 113 114 ### JSON 115 116 As with provisioners, in JSON templates, post-processors are sequentially invoked after a 117 build finished provisioning, and are declared in the template under "post-processors". 118 119 ```json 120 { 121 "builders": [ 122 { 123 "type": "null", 124 "name": "test", 125 "communicator": "none" 126 } 127 ], 128 "provisioners": [ 129 { 130 "type": "shell-local", 131 "inline": ["echo test"] 132 } 133 ], 134 "post-processors": [ 135 { 136 "type": "manifest" 137 } 138 ] 139 } 140 ``` 141 142 ### HCL2 143 144 In HCL2, much like provisioners, they are also part of the `build` block, and similar rules 145 apply as with provisioners. 146 147 ```hcl 148 source "null" "test" { 149 communicator = "none" 150 } 151 152 build { 153 sources = ["null.test"] 154 155 provisioner "shell-local" { 156 inline = ["echo test"] 157 } 158 159 post-processor "manifest" {} 160 } 161 ```