code: func loadLocalsHcl(list *ast.ObjectList) ([]*Local, error) {
  
  	result := make([]*Local, 0, len(list.Items))
  
  	for _, block := range list.Items {
  		if len(block.Keys) > 0 {
  			return nil, fmt.Errorf(
  				"locals block at %s should not have label %q",
  				block.Pos(), block.Keys[0].Token.Value(),
  			)
  		}
  
  		blockObj, ok := block.Val.(*ast.ObjectType)
  		if !ok {
  			return nil, fmt.Errorf("locals value at %s should be a block", block.Val.Pos())
  		}
  
  		// blockObj now contains directly our local decls
  		for _, item := range blockObj.List.Items {
  			if len(item.Keys) != 1 {
  				return nil, fmt.Errorf("local declaration at %s may not be a block", item.Val.Pos())
  			}
  
  			// By the time we get here there can only be one item left, but
  			// we'll decode into a map anyway because it's a convenient way
  			// to extract both the key and the value robustly.
  			kv := map[string]interface{}{}
  			hcl.DecodeObject(&kv, item)
  			for k, v := range kv {
  				rawConfig, err := NewRawConfig(map[string]interface{}{
  					"value": v,
  				})
  
  				if err != nil {
  					return nil, fmt.Errorf(
  						"error parsing local value %q at %s: %s",
  						k, item.Val.Pos(), err,
  					)
  				}
  
  				result = append(result, &Local{
  					Name:      k,
  					RawConfig: rawConfig,
  				})
  			}
  		}
  	}
  
  	return result, nil
  }
docs: // loadLocalsHcl recurses into the given HCL object turns it into
  // a list of locals.