github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/website/docs/language/syntax/json.html.md (about) 1 --- 2 layout: "language" 3 page_title: "JSON Configuration Syntax - Configuration Language" 4 sidebar_current: "docs-config-syntax-json" 5 description: |- 6 Details about the JSON-compatible Terraform language syntax, including file structure, expression mapping, and blocks. 7 --- 8 9 # JSON Configuration Syntax 10 11 Most Terraform configurations are written in 12 [the native Terraform language syntax](/docs/language/syntax/configuration.html), which is designed to be 13 relatively easy for humans to read and update. 14 15 Terraform also supports an alternative syntax that is JSON-compatible. This 16 syntax is useful when generating portions of a configuration programmatically, 17 since existing JSON libraries can be used to prepare the generated 18 configuration files. 19 20 The JSON syntax is defined in terms of the native syntax. Everything that can 21 be expressed in native syntax can also be expressed in JSON syntax, but some 22 constructs are more complex to represent in JSON due to limitations of the 23 JSON grammar. 24 25 Terraform expects native syntax for files named with a `.tf` suffix, and 26 JSON syntax for files named with a `.tf.json` suffix. 27 28 The low-level JSON syntax, just as with the native syntax, is defined in terms 29 of a specification called _HCL_. It is not necessary to know all of the details 30 of HCL syntax or its JSON mapping in order to use Terraform, and so this page 31 summarizes the most important differences between native and JSON syntax. 32 If you are interested, you can find a full definition of HCL's JSON syntax 33 in [its specification](https://github.com/hashicorp/hcl/blob/hcl2/json/spec.md). 34 35 ## JSON File Structure 36 37 At the root of any JSON-based Terraform configuration is a JSON object. The 38 properties of this object correspond to the top-level block types of the 39 Terraform language. For example: 40 41 ```json 42 { 43 "variable": { 44 "example": { 45 "default": "hello" 46 } 47 } 48 } 49 ``` 50 51 Each top-level object property must match the name of one of the expected 52 top-level block types. Block types that expect labels, such as `variable` 53 shown above, are represented by one nested object value for each level 54 of label. `resource` blocks expect two labels, so two levels of nesting 55 are required: 56 57 ```json 58 { 59 "resource": { 60 "aws_instance": { 61 "example": { 62 "instance_type": "t2.micro", 63 "ami": "ami-abc123" 64 } 65 } 66 } 67 } 68 ``` 69 70 After any nested objects representing the labels, finally one more nested 71 object represents the body of the block itself. In the above examples, the 72 `default` argument for `variable "example"` and the `instance_type` and 73 `ami` arguments for `resource "aws_instance" "example"` are specified. 74 75 Taken together, the above two configuration files are equivalent to the 76 following blocks in the native syntax: 77 78 ```hcl 79 variable "example" { 80 default = "hello" 81 } 82 83 resource "aws_instance" "example" { 84 instance_type = "t2.micro" 85 ami = "ami-abc123" 86 } 87 ``` 88 89 Within each top-level block type the rules for mapping to JSON are slightly 90 different (see the [block-type-specific exceptions](#block-type-specific-exceptions) below), but the following general rules apply in most cases: 91 92 * The JSON object representing the block body contains properties that 93 correspond either to argument names or to nested block type names. 94 95 * Where a property corresponds to an argument that accepts 96 [arbitrary expressions](/docs/language/expressions/index.html) in the native syntax, the 97 property value is mapped to an expression as described under 98 [_Expression Mapping_](#expression-mapping) below. For arguments that 99 do _not_ accept arbitrary expressions, the interpretation of the property 100 value depends on the argument, as described in the 101 [block-type-specific exceptions](#block-type-specific-exceptions) 102 given later in this page. 103 104 * Where a property name corresponds to an expected nested block type name, 105 the value is interpreted as described under 106 [_Nested Block Mapping_](#nested-block-mapping) below, unless otherwise 107 stated in [the block-type-specific exceptions](#block-type-specific-exceptions) 108 given later in this page. 109 110 ## Expression Mapping 111 112 Since JSON grammar is not able to represent all of the Terraform language 113 [expression syntax](/docs/language/expressions/index.html), JSON values interpreted as expressions 114 are mapped as follows: 115 116 | JSON | Terraform Language Interpretation | 117 | ------- | ------------------------------------------------------------------------------------------------------------- | 118 | Boolean | A literal `bool` value. | 119 | Number | A literal `number` value. | 120 | String | Parsed as a [string template][] and then evaluated as described below. | 121 | Object | Each property value is mapped per this table, producing an `object(...)` value with suitable attribute types. | 122 | Array | Each element is mapped per this table, producing a `tuple(...)` value with suitable element types. | 123 | Null | A literal `null`. | 124 125 [string template]: /docs/language/expressions/strings.html#string-templates 126 127 When a JSON string is encountered in a location where arbitrary expressions are 128 expected, its value is first parsed as a [string template][] 129 and then it is evaluated to produce the final result. 130 131 If the given template consists _only_ of a single interpolation sequence, 132 the result of its expression is taken directly, without first converting it 133 to a string. This allows non-string expressions to be used within the 134 JSON syntax: 135 136 ```json 137 { 138 "output": { 139 "example": { 140 "value": "${aws_instance.example}" 141 } 142 } 143 } 144 ``` 145 146 The `output "example"` declared above has the object value representing the 147 given `aws_instance` resource block as its value, rather than a string value. 148 This special behavior does not apply if any literal or control sequences appear 149 in the template; in these other situations, a string value is always produced. 150 151 ## Nested Block Mapping 152 153 When a JSON object property is named after a nested block type, the value 154 of this property represents one or more blocks of that type. The value of 155 the property must be either a JSON object or a JSON array. 156 157 The simplest situation is representing only a single block of the given type 158 when that type expects no labels, as with the `lifecycle` nested block used 159 within `resource` blocks: 160 161 ```json 162 { 163 "resource": { 164 "aws_instance": { 165 "example": { 166 "lifecycle": { 167 "create_before_destroy": true 168 } 169 } 170 } 171 } 172 } 173 ``` 174 175 The above is equivalent to the following native syntax configuration: 176 177 ```hcl 178 resource "aws_instance" "example" { 179 lifecycle { 180 create_before_destroy = true 181 } 182 } 183 ``` 184 185 When the nested block type requires one or more labels, or when multiple 186 blocks of the same type can be given, the mapping gets a little more 187 complicated. For example, the `provisioner` nested block type used 188 within `resource` blocks expects a label giving the provisioner to use, 189 and the ordering of provisioner blocks is significant to decide the order 190 of operations. 191 192 The following native syntax example shows a `resource` block with a number 193 of provisioners of different types: 194 195 ```hcl 196 resource "aws_instance" "example" { 197 # (resource configuration omitted for brevity) 198 199 provisioner "local-exec" { 200 command = "echo 'Hello World' >example.txt" 201 } 202 provisioner "file" { 203 source = "example.txt" 204 destination = "/tmp/example.txt" 205 } 206 provisioner "remote-exec" { 207 inline = [ 208 "sudo install-something -f /tmp/example.txt", 209 ] 210 } 211 } 212 ``` 213 214 In order to preserve the order of these blocks, you must use a JSON array 215 as the direct value of the property representing this block type, as in 216 this JSON equivalent of the above: 217 218 ```json 219 { 220 "resource": { 221 "aws_instance": { 222 "example": { 223 "provisioner": [ 224 { 225 "local-exec": { 226 "command": "echo 'Hello World' >example.txt" 227 } 228 }, 229 { 230 "file": { 231 "source": "example.txt", 232 "destination": "/tmp/example.txt" 233 } 234 }, 235 { 236 "remote-exec": { 237 "inline": ["sudo install-something -f /tmp/example.txt"] 238 } 239 } 240 ] 241 } 242 } 243 } 244 } 245 ``` 246 247 Each element of the `provisioner` array is an object with a single property 248 whose name represents the label for each `provisioner` block. For block types 249 that expect multiple labels, this pattern of alternating array and object 250 nesting can be used for each additional level. 251 252 If a nested block type requires labels but the order does _not_ matter, you 253 may omit the array and provide just a single object whose property names 254 correspond to unique block labels. This is allowed as a shorthand for the above 255 for simple cases, but the alternating array and object approach is the most 256 general. We recommend using the most general form if systematically converting 257 from native syntax to JSON, to ensure that the meaning of the configuration is 258 preserved exactly. 259 260 ### Comment Properties 261 262 Although we do not recommend hand-editing of JSON syntax configuration files 263 -- this format is primarily intended for programmatic generation and consumption -- 264 a limited form of _comments_ are allowed inside JSON objects that represent 265 block bodies using a special property name: 266 267 ```json 268 { 269 "resource": { 270 "aws_instance": { 271 "example": { 272 "//": "This instance runs the scheduled tasks for backup", 273 274 "instance_type": "t2.micro", 275 "ami": "ami-abc123" 276 } 277 } 278 } 279 } 280 ``` 281 282 In any object that represents a block body, properties named `"//"` are 283 ignored by Terraform entirely. This exception does _not_ apply to objects 284 that are being [interpreted as expressions](#expression-mapping), where this 285 would be interpreted as an object type attribute named `"//"`. 286 287 This special property name can also be used at the root of a JSON-based 288 configuration file. This can be useful to note which program created the file. 289 290 ```json 291 { 292 "//": "This file is generated by generate-outputs.py. DO NOT HAND-EDIT!", 293 294 "output": { 295 "example": { 296 "value": "${aws_instance.example}" 297 } 298 } 299 } 300 ``` 301 302 ## Block-type-specific Exceptions 303 304 [inpage-block]: #block-type-specific-exceptions 305 306 Certain arguments within specific block types are processed in a special way 307 by Terraform, and so their mapping to the JSON syntax does not follow the 308 general rules described above. The following sub-sections describe the special 309 mapping rules that apply to each top-level block type. 310 311 ### `resource` and `data` blocks 312 313 Some meta-arguments for the `resource` and `data` block types take direct 314 references to objects, or literal keywords. When represented in JSON, the 315 reference or keyword is given as a JSON string with no additional surrounding 316 spaces or symbols. 317 318 For example, the `provider` meta-argument takes a `<PROVIDER>.<ALIAS>` reference 319 to a provider configuration, which appears unquoted in the native syntax but 320 must be presented as a string in the JSON syntax: 321 322 ```json 323 { 324 "resource": { 325 "aws_instance": { 326 "example": { 327 "provider": "aws.foo" 328 } 329 } 330 } 331 } 332 ``` 333 334 This special processing applies to the following meta-arguments: 335 336 * `provider`: a single string, as shown above 337 * `depends_on`: an array of strings containing references to named entities, 338 like `["aws_instance.example"]`. 339 * `ignore_changes` within the `lifecycle` block: if set to `all`, a single 340 string `"all"` must be given. Otherwise, an array of JSON strings containing 341 property references must be used, like `["ami"]`. 342 343 Special processing also applies to the `type` argument of any `connection` 344 blocks, whether directly inside the `resource` block or nested inside 345 `provisioner` blocks: the given string is interpreted literally, and not 346 parsed and evaluated as a string template. 347 348 ### `variable` blocks 349 350 All arguments inside `variable` blocks have non-standard mappings to JSON: 351 352 * `type`: a string containing a type expression, like `"string"` or `"list(string)"`. 353 * `default`: a literal JSON value that can be converted to the given type. 354 Strings within this value are taken literally and _not_ interpreted as 355 string templates. 356 * `description`: a literal JSON string, _not_ interpreted as a template. 357 358 ```json 359 { 360 "variable": { 361 "example": { 362 "type": "string", 363 "default": "hello" 364 } 365 } 366 } 367 ``` 368 369 ### `output` blocks 370 371 The `description` and `sensitive` arguments are interpreted as literal JSON 372 values. The `description` string is not interpreted as a string template. 373 374 The `value` argument is [interpreted as an expression](#expression-mapping). 375 376 ```json 377 { 378 "output": { 379 "example": { 380 "value": "${aws_instance.example}" 381 } 382 } 383 } 384 ``` 385 386 ### `locals` blocks 387 388 The value of the JSON object property representing the locals block type 389 must be a JSON object whose property names are the local value names to 390 declare: 391 392 ```json 393 { 394 "locals": { 395 "greeting": "Hello, ${var.name}" 396 } 397 } 398 ``` 399 400 The value of each of these nested properties is 401 [interpreted as an expression](#expression-mapping). 402 403 ### `module` blocks 404 405 The `source` and `version` meta-arguments must be given as literal strings. The 406 values are not interpreted as string templates. 407 408 The `providers` meta-argument must be given as a JSON object whose properties 409 are the compact provider addresses to expose into the child module and whose 410 values are the provider addresses to use from the current module, both 411 given as literal strings: 412 413 ```json 414 { 415 "module": { 416 "example": { 417 "source": "hashicorp/consul/azurerm", 418 "version": "= 1.0.0", 419 "providers": { 420 "aws": "aws.usw1" 421 } 422 } 423 } 424 } 425 ``` 426 427 ### `provider` blocks 428 429 The `alias` and `version` meta-arguments must be given as literal strings. The 430 values are not interpreted as string templates. 431 432 ```json 433 { 434 "provider": { 435 "aws": [ 436 { 437 "region": "us-east-1" 438 }, 439 { 440 "alias": "usw1", 441 "region": "us-west-1" 442 } 443 ] 444 } 445 } 446 ``` 447 448 ### `terraform` blocks 449 450 Since no settings within `terraform` blocks accept named object references or 451 function calls, all setting values are taken literally. String values are not 452 interpreted as string templates. 453 454 Since only one `backend` block is allowed per `terraform` block, the compact 455 block mapping can be used to represent it, with a nested object containing 456 a single property whose name represents the backend type. 457 458 ```json 459 { 460 "terraform": { 461 "required_version": ">= 0.12.0", 462 "backend": { 463 "s3": { 464 "region": "us-west-2", 465 "bucket": "acme-terraform-states" 466 } 467 } 468 } 469 } 470 ```