github.com/hashicorp/packer@v1.14.3/website/content/docs/templates/hcl_templates/syntax-json.mdx (about)

     1  ---
     2  page_title: JSON syntax reference
     3  description: |-
     4    A JSON configuration expresses HCL Packer templates as JSON-compatible syntax. Learn about the JSON syntax for creating HCL Packer templates.  
     5  ---
     6  
     7  # JSON syntax reference
     8  
     9  This topic provides reference information about the JSON syntax you can use to express HCL Packer templates as JSON. For information about the HCL syntax, refer to [HCL syntax reference](/packer/docs/templates/hcl_templates/syntax).
    10  
    11  ## Introduction
    12  
    13  Packer supports templates written in JSON, which is useful when generating portions of a configuration programmatically. This is because you can use existing JSON libraries to prepare the generated
    14  configuration files.
    15  
    16  This syntax is not to be confused with the pre-version-1.5 "legacy" Packer
    17  templates, which were exclusively JSON and follow a different format.
    18  
    19  The JSON syntax is defined in terms of the native syntax. Everything that can
    20  be expressed in native syntax can also be expressed in JSON syntax, but some
    21  constructs are more complex to represent in JSON due to limitations of the
    22  JSON grammar.
    23  
    24  Packer expects native syntax for files named with a `.pkr.hcl` suffix, and JSON
    25  syntax for files named with a `.pkr.json` suffix. If you leave out the `.pkr`
    26  portion of suffix, Packer will try to read your json file as a legacy Packer
    27  template.
    28  
    29  The low-level JSON syntax, just as with the native syntax, is defined in terms
    30  of a specification called _HCL_. It is not necessary to know all of the details
    31  of HCL syntax or its JSON mapping in order to use Packer, and so this page
    32  summarizes the most important differences between native and JSON syntax. If
    33  you are interested, you can find a full definition of HCL's JSON syntax in [its
    34  specification](https://github.com/hashicorp/hcl/blob/hcl2/hclsyntax/spec.md).
    35  
    36  ## JSON File Structure
    37  
    38  At the root of any JSON-based Packer configuration is a JSON object. The
    39  properties of this object correspond to the top-level block types of the
    40  Packer language. For example:
    41  
    42  ```json
    43  {
    44    "variables": {
    45      "example": "value"
    46    }
    47  }
    48  ```
    49  
    50  Each top-level object property must match the name of one of the expected
    51  top-level block types. Block types that expect labels, such as `variable` shown
    52  above, are represented by one nested object value for each level of label.
    53  `source` blocks expect two labels, so two levels of nesting are required:
    54  
    55  ```json
    56  {
    57    "source": {
    58      "amazon-ebs": {
    59        "example": {
    60          "instance_type": "t2.micro",
    61          "ami_name": "ami-abc123"
    62        }
    63      }
    64    }
    65  }
    66  ```
    67  
    68  After any nested objects representing the labels, finally one more nested
    69  object represents the body of the block itself. In the above example the
    70  `instance_type` and `ami_name` arguments for `source "amazon-ebs" "example"`
    71  are specified.
    72  
    73  Taken together, the above two configuration files are equivalent to the
    74  following blocks in the native syntax:
    75  
    76  ```hcl
    77  variables {
    78    example = "value"
    79  }
    80  
    81  source "amazon-ebs" "example" {
    82    instance_type = "t2.micro"
    83    ami_name      = "ami-abc123"
    84  }
    85  ```
    86  
    87  Within each top-level block type the rules for mapping to JSON are slightly
    88  different (see [block-type-specific exceptions](#block-type-specific-exceptions) below), but the following general rules apply in most cases:
    89  
    90  - The JSON object representing the block body contains properties that
    91    correspond either to argument names or to nested block type names.
    92  
    93  - Where a property corresponds to an argument that accepts
    94    [arbitrary expressions](/packer/docs/templates/hcl_templates/expressions) in the native syntax, the
    95    property value is mapped to an expression as described under
    96    [_Expression Mapping_](#expression-mapping) below. For arguments that
    97    do _not_ accept arbitrary expressions, the interpretation of the property
    98    value depends on the argument, as described in the
    99    [block-type-specific exceptions](#block-type-specific-exceptions)
   100    given later in this page.
   101  
   102  - Where a property name corresponds to an expected nested block type name,
   103    the value is interpreted as described under
   104    [_Nested Block Mapping_](#nested-block-mapping) below, unless otherwise
   105    stated in [the block-type-specific exceptions](#block-type-specific-exceptions)
   106    given later in this page.
   107  
   108  ## Expression Mapping
   109  
   110  Since JSON grammar is not able to represent all of the Packer language
   111  [expression syntax](/packer/docs/templates/hcl_templates/expressions), JSON values interpreted as expressions
   112  are mapped as follows:
   113  
   114  | JSON    | Packer Language Interpretation                                                                                                   |
   115  | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
   116  | Boolean | A literal `bool` value.                                                                                                          |
   117  | Number  | A literal `number` value.                                                                                                        |
   118  | String  | Parsed as a [string template](/packer/docs/templates/hcl_templates/expressions#string-templates) and then evaluated as described below. |
   119  | Object  | Each property value is mapped per this table, producing an `object(...)` value with suitable attribute types.                    |
   120  | Array   | Each element is mapped per this table, producing a `tuple(...)` value with suitable element types.                               |
   121  | Null    | A literal `null`.                                                                                                                |
   122  
   123  When a JSON string is encountered in a location where arbitrary expressions are
   124  expected, its value is first parsed as a [string template](/packer/docs/templates/hcl_templates/expressions#string-templates)
   125  and then it is evaluated to produce the final result.
   126  
   127  If the given template consists _only_ of a single interpolation sequence,
   128  the result of its expression is taken directly, without first converting it
   129  to a string. This allows non-string expressions to be used within the
   130  JSON syntax.
   131  
   132  ## Nested Block Mapping
   133  
   134  When a JSON object property is named after a nested block type, the value
   135  of this property represents one or more blocks of that type. The value of
   136  the property must be either a JSON object or a JSON array.
   137  
   138  The simplest situation is representing only a single block of the given type
   139  when that type expects no labels, as with the `tags` nested block used
   140  within `source` blocks:
   141  
   142  ```json
   143  {
   144    "source": {
   145      "amazon-ebs": {
   146        "example": {
   147          "tags": {
   148            "key": "value"
   149          }
   150        }
   151      }
   152    }
   153  }
   154  ```
   155  
   156  The above is equivalent to the following native syntax configuration:
   157  
   158  ```hcl
   159  source "amazon-ebs" "example" {
   160    tags = {
   161      key = "value"
   162    }
   163  }
   164  ```
   165  
   166  When the nested block type requires one or more labels, or when multiple
   167  blocks of the same type can be given, the mapping gets a little more
   168  complicated. For example, the `provisioner` nested block type used
   169  within `build` blocks expects a label giving the provisioner to use,
   170  and the ordering of provisioner blocks is significant to decide the order
   171  of operations.
   172  
   173  The following native syntax example shows a `build` block with a number
   174  of provisioners of different types:
   175  
   176  ```hcl
   177  build {
   178    # (source configuration omitted for brevity)
   179  
   180    provisioner "shell-local" {
   181      inline = ["echo 'Hello World' >example.txt"]
   182    }
   183    provisioner "file" {
   184      source      = "example.txt"
   185      destination = "/tmp/example.txt"
   186    }
   187    provisioner "shell" {
   188      inline = [
   189        "sudo install-something -f /tmp/example.txt",
   190      ]
   191    }
   192  }
   193  ```
   194  
   195  In order to preserve the order of these blocks, you must use a JSON array
   196  as the direct value of the property representing this block type, as in
   197  this JSON equivalent of the above:
   198  
   199  ```json
   200  {
   201    "build": {
   202      "//": "(source configuration omitted for brevity)",
   203  
   204      "provisioner": [
   205        {
   206          "shell-local": {
   207            "inline": ["echo 'Hello World' >example.txt"]
   208          }
   209        },
   210        {
   211          "file": {
   212            "source": "example.txt",
   213            "destination": "/tmp/example.txt"
   214          }
   215        },
   216        {
   217          "shell": {
   218            "inline": ["sudo install-something -f /tmp/example.txt"]
   219          }
   220        }
   221      ]
   222    }
   223  }
   224  ```
   225  
   226  Each element of the `provisioner` array is an object with a single property
   227  whose name represents the label for each `provisioner` block. For block types
   228  that expect multiple labels, this pattern of alternating array and object
   229  nesting can be used for each additional level.
   230  
   231  If a nested block type requires labels but the order does _not_ matter, you
   232  may omit the array and provide just a single object whose property names
   233  correspond to unique block labels. This is allowed as a shorthand for the above
   234  for simple cases, but the alternating array and object approach is the most
   235  general. We recommend using the most general form if systematically converting
   236  from native syntax to JSON, to ensure that the meaning of the configuration is
   237  preserved exactly.
   238  
   239  ### Comment Properties
   240  
   241  Although we do not recommend hand-editing of JSON syntax configuration files
   242  -- this format is primarily intended for programmatic generation and consumption --
   243  a limited form of _comments_ are allowed inside JSON objects that represent
   244  block bodies using a special property name:
   245  
   246  ```json
   247  {
   248    "source": {
   249      "amazon-ebs": {
   250        "example": {
   251          "//": "This instance runs the scheduled tasks for backup",
   252  
   253          "instance_type": "t2.micro",
   254          "ami_name": "ami-abc123"
   255        }
   256      }
   257    }
   258  }
   259  ```
   260  
   261  In any object that represents a block body, properties named `"//"` are
   262  ignored by Packer entirely. This exception does _not_ apply to objects
   263  that are being [interpreted as expressions](#expression-mapping), where this
   264  would be interpreted as an object type attribute named `"//"`.
   265  
   266  This special property name can also be used at the root of a JSON-based
   267  configuration file. This can be useful to note which program created the file.
   268  
   269  ```json
   270  {
   271    "//": "This file is generated by generate-outputs.py. DO NOT HAND-EDIT!"
   272  }
   273  ```
   274  
   275  ## Block-type-specific Exceptions
   276  
   277  [inpage-block]: #block-type-specific-exceptions
   278  
   279  Certain arguments within specific block types are processed in a special way,
   280  and so their mapping to the JSON syntax does not follow the general rules
   281  described above. The following sub-sections describe the special mapping rules
   282  that apply to each top-level block type.
   283  
   284  ### `variable` blocks
   285  
   286  All arguments inside `variable` blocks have non-standard mappings to JSON:
   287  
   288  - `type`: a string containing a type expression, like `"string"` or `"list(string)"`.
   289  - `default`: a literal JSON value that can be converted to the given type.
   290    Strings within this value are taken literally and _not_ interpreted as
   291    string templates.
   292  - `description`: a literal JSON string, _not_ interpreted as a template.
   293  
   294  ```json
   295  {
   296    "variable": {
   297      "example": {
   298        "type": "string",
   299        "default": "hello"
   300      }
   301    }
   302  }
   303  ```