Search code examples
jsonterraformpython-3.8terraform-enterprise

How to pass array and maps using terraform cloud API calls


I need to pass an array and a map values to terraform workspace using terraform api

tried calling

{
    "data": {
      "id":"",
      "attributes": {
        "key":"PREFIXES",
        "value":'{a="b"}',
        "description":"some description",
        "category":"terraform",
        "hcl": false,
        "sensitive": false
      },
      "type":"vars"
    }
  }

and curl call is

curl \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/vnd.api+json" \
  --request PATCH \
  --data @payload.json \
  https://app.terraform.io/api/v2/workspaces/$WORKSPACE_ID/vars/$PREFIXES_ID

end up with error

{"errors":[{"status":"400","title":"JSON body is invalid","detail":"784: unexpected token at '{    \"data\": {      \"id\":\"\",      \"attributes\": {        \"key\":\"PREFIXES\",        \"value\":'{a=\"b\"}',        \"description\":\"some description\",        \"category\":\"terraform\",        \"hcl\": false,        \"sensitive\": false      },      \"type\":\"vars\"    }  }'"}]}

I tried implementing the same using python. how ever my terraform is giving errors:

Error: Invalid for_each argument

on main.tf line 18, in resource "aws_s3_bucket_object" "obj": 18: for_each = var.prefixes

python3
def update_workspace_vars(workspace_vars, var_values, params):
    headers = {"Authorization": "Bearer " + params["TOKEN"],
               "Content-Type": "application/vnd.api+json"}
    for k in var_values:
        payload = {
            "data": {
                "id": workspace_vars[k],
                "attributes": {
                    "key": k,
                    "value": var_values[k],
                    "category": "terraform"
                },
                "type": "vars"
            }
        }
        patch_params = dict((k, params[k]) for k in ("workspace_id", "tfe_host"))
        patch_params.update({"var_id": workspace_vars[k]})
        url = "https://{tfe_host}/api/v2/workspaces/{workspace_id}/vars/{var_id}".format(**patch_params)
        response = http.request("PATCH", url, headers=headers, body=json.dumps(payload)).data


var_variables = {"prefixes": {"a": ["a1", "a2", "a3"], "b": ["b1", "b2", "b3"]}}

and my terraform code :


resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket-pinnaka"
  acl    = "private"
}

resource "aws_s3_bucket_object" "obj" {
  for_each = var.prefixes
  bucket = aws_s3_bucket.b.id
  key = each.key
  content = each.value
}```

Solution

  • You JSON seems to be invalid.

    {
        "data": {
          "id":"",
          "attributes": {
            "key":"PREFIXES",
            "value":'{a="b"}',
            "description":"some description",
            "category":"terraform",
            "hcl": false,
            "sensitive": false
          },
          "type":"vars"
        }
      }
    

    "value":'{a="b"}' is invalid JSON syntax.

    Either use "value": { "a" : "b"} as JSON or otherwise "value":\"{a=\'b\'}\" escape the single quotes to keep {"a"="b"} from getting parsed as JSON.