Introduction
My earlier post, How to Work With Lists in OCI Resource Manager, described how to list dynamic groups and add policies to groups selected by the user during configuration. In this post we’ll focus on using JSON, the most common data format for the internet.
Terraform, and by extension OCI Resource Manager, makes it easy to consume JSON and to work with the data itself with features like for loops, sets, and maps.
Let’s start with a couple use cases:
- Reading multiple JSON files in the local directory
- Reading JSON via input variables
Both of these use cases are valid depending on your project needs. Let’s examine some of the differences:
-
In the first example, your project is self-contained and can run without anyone knowing the contents of the JSON files, making it an implementation detail of the configuration.
-
In the second example the JSON values can differ between runs so that you can have multiple
.tfvars.jsonfiles and choose a different one each time you runterraform apply. These settings are part of the interface of the configuration, and must be set by anyone applying that configuration.
Below is the example JSON we’ll use throughout the post.
{
"groups": [
{
"name": "dyngrp_1",
"description": "Description for dynamic group 1",
"rule": "example dynamic group rule"
},
{
"name": "dyngrp_2",
"description": "Description for dynamic group 2",
"rule": "example dynamic group rule"
},
{
"name": "dyngrp_3",
"description": "Description for dynamic group 3",
"rule": "example dynamic group rule"
},
{
"name": "dyngrp_4",
"description": "Description for dynamic group 4",
"rule": "example dynamic group rule"
}
]
}
Let’s get started.
Reading multiple files in the local directory
To read and work with a JSON file in Terraform, use both the file and jsonencode functions. First the file function reads the contents of a file at the given path and returns them as a string and the jsonencode function interprets a given string as JSON.
The example below reads all JSON files from a given path then extracts and flattens all the name attributes.
locals {
groups_path = "${path.module}/groups"
# List all group json files in path
json_files = fileset(local.groups_path, "*.json")
json_data = [for f in local.json_files : jsondecode(file("${local.groups_path}/${f}"))]
# Read list of group names from included groups json files
group_names = flatten(local.json_data[*].groups[*].name)
}
output "groups" {
value = local.group_names
}
Reading JSON via input variables
Terraform lets you define input variable files called *.tfvars so you have reusable files for all the variables in your project. These files can include name/value pairs as well as JSON data, such as the example JSON listed above saved as terraform.tfvars.json.
In this case the JSON data is automatically available but make sure to create a variable with the same name to hold the data.
See the following block for how to do it.
locals {# List all group rulesrules = distinct( [for group in var.groups.groups : group.rule] )}
# Input variable for terraform.tfvars.json
variable "groups" {
type = map(any)
description = "A map of dynamic group definitions"
}
output "rules" {
value = local.rules
}
Summary
Don’t forget to review my earlier post, Why Infrastructure as Code Matters, to learn more about the value of Terraform and Oracle Cloud Infrastructure (OCI) Resource Manager for managing your OCI infrastructure. Happy hunting!
~sn
