Terraform Loop Iteration
Terraform can manage multiple similar resources by iterating through defined data structures. You reuse your Terraform code and keep similar resources managed consistently.
The Terraform for_each Meta-Argument is the mechanism for this. The example below uses it to manage multiple similar Files.com resources.
Example Use Case
The scenario is a fictional healthcare business that processes Medicare claims.
The healthcare business needs to onboard multiple client customers, such as the healthcare providers it serves.
Each client requires a home folder within the Medicare clients' folder structure. Each client home folder contains subfolders named Eligibility and Prescription Drug Event for that client.
Each client home folder is assigned 2 user access groups. One group has permission only to upload and the other has permission only to download. The customer client is placed in the upload group and the internal systems are placed in the download group. This way, only clients submit data and only internal systems collect it.
For compliance reasons, each subfolder also needs to be accessible by the relevant teams. The Eligibility subfolder is accessed (read only) by another internal system and accessed (write only) by the Customer Eligibility Support Team whenever eligibility records are updated or changed. The Eligibility subfolder gets 2 new user access groups assigned to meet these access needs.
The Prescription Drug Event subfolder has similar requirements to the Eligibility subfolder. It also gets 2 user access groups: 1 to upload (write only) and 1 to download (read only).
All new clients have these same requirements applied to their folders.
for_each Usage Example
Use the for_each Meta-Argument to iterate through a variable when managing resources:
# Variable Containing List of Clients
variable "clients" {
type = set(string)
default = [
"Client A",
"Client B",
"Client C"
]
}
# Create User Accounts for each Client by using a loop
resource "files_user" "user_account" {
for_each = var.clients
authentication_method = "password"
name = each.value
company = each.value
password = "S0meRea11yLongP@ssw0rd"
self_managed = "true"
username = replace("${lower(each.value)}", " ", "_")
}
The code above defines a variable containing a list of client names. It uses the for_each meta-argument to iterate through the list and create corresponding user accounts on your Files.com site. The value for each client in the variable becomes the name, company, and username of the user account. For the username, the value is converted to lower case and any spaces are replaced with an underscore.
Implementing the Example Use Case
The implementation uses for_each loops to perform these steps for each client:
- Create client folder
- Create upload and download groups for the client folder
- Assign access permissions to the client folder groups
- Create subfolder(s)
- Create upload and download groups for the subfolder(s)
- Assign access permissions to the subfolder groups
Create Client Folder
Client folders go inside the /Medicare/Clients/ folder of the site. A Terraform best practice is to have Terraform manage all dependencies, including the existence of parent folders in the hierarchy. This avoids issues later when Terraform modifies or removes existing resources.
Configure Terraform to manage both the /Medicare/ and the /Medicare/Clients/ folders, and make the latter depend on the former. The following code does that:
# Create top level folder for Medicare
resource "files_folder" "top_medicare_folder" {
path = "Medicare"
}
# Create Clients folder within the Medicare folder
resource "files_folder" "medicare_clients_folder" {
path = "${files_folder.top_medicare_folder.path}/Clients"
depends_on = [ files_folder.top_medicare_folder ]
}
A for_each loop then creates and manages the client folders:
# Create home folders for each client
resource "files_folder" "client_folder" {
for_each = var.clients
path = "${files_folder.medicare_clients_folder.path}/${each.value}"
depends_on = [ files_folder.medicare_clients_folder ]
}
Create Groups for the Client Home Folder
Use similar for_each loops to create and manage the groups that are assigned upload (write only) and download (read only) access permissions.
The following code creates the 2 groups:
# Create group to upload to client home folder
resource "files_group" "client_upload_group" {
for_each = var.clients
notes = "Upload Group for ${each.value}."
ftp_permission = true
sftp_permission = true
dav_permission = true
restapi_permission = true
name = "${each.value} Upload Group"
}
# Create group to retrieve (download only) from client home folder
resource "files_group" "client_download_group" {
for_each = var.clients
notes = "Download Group for ${each.value}."
ftp_permission = true
sftp_permission = true
dav_permission = true
restapi_permission = true
name = "${each.value} Download Group"
}
Assign Access Permissions to the Home Folder Groups
Assign access permissions to the 2 home folder groups with the following code:
# Assign upload access permission to upload group
resource "files_permission" "client_group_upload_permission" {
for_each = var.clients
path = "${files_folder.medicare_clients_folder.path}/${each.value}"
group_name = "${each.value} Upload Group"
permission = "writeonly"
depends_on = [files_group.client_upload_group, files_folder.client_folder]
}
# Assign download access permission to retrieve group
resource "files_permission" "client_group_download_permission" {
for_each = var.clients
path = "${files_folder.medicare_clients_folder.path}/${each.value}"
group_name = "${each.value} Download Group"
permission = "readonly"
depends_on = [files_group.client_download_group, files_folder.client_folder]
}
The code above assigns access permissions to the previously created groups. It specifies dependencies so that the permissions are only assigned after the groups and their corresponding home folders are successfully created.
Create Client Subfolders
For each subfolder within the client home folder, repeat the following code, adjusting the folder name as needed:
# Create Eligibility subfolder for each client
resource "files_folder" "client_eligibility_folder" {
for_each = var.clients
path = "${files_folder.medicare_clients_folder.path}/${each.value}/Eligibility"
depends_on = [ files_folder.client_folder ]
}
The code above creates an Eligibility subfolder within the client home folder. It specifies a dependency so that the subfolder is only created after the home folder has been created.
Duplicate this step for each required subfolder. For this use case, repeat the code but replace all mentions of "eligibility" with "prescription drug event".
Create Groups for the Client Subfolders
As before, create 2 groups that are assigned upload (write only) and download (read only) access permissions to the subfolders:
# Create group to upload to client eligibility folder
resource "files_group" "client_eligibility_upload_group" {
for_each = var.clients
notes = "Eligibility Upload Group for ${each.value}."
ftp_permission = true
sftp_permission = true
dav_permission = true
restapi_permission = true
name = "${each.value} Eligibility Upload Group"
}
# Create group to download from client eligibility folder
resource "files_group" "client_eligibility_download_group" {
for_each = var.clients
notes = "Eligibility Download Group for ${each.value}."
ftp_permission = true
sftp_permission = true
dav_permission = true
restapi_permission = true
name = "${each.value} Eligibility Download Group"
}
Duplicate this step for each required subfolder. For this use case, repeat the code but replace all mentions of "eligibility" with "prescription drug event".
Assign Access Permissions to the Subfolder Groups
Assign access permissions to the 2 subfolder groups with the following code:
# Assign upload access permission to eligibility upload group
resource "files_permission" "client_group_eligibility_upload_permission" {
for_each = var.clients
path = "${files_folder.medicare_clients_folder.path}/${each.value}/Eligibility"
group_name = "${each.value} Eligibility Upload Group"
permission = "writeonly"
depends_on = [files_group.client_eligibility_upload_group, files_folder.client_eligibility_folder]
}
# Assign download access permission to eligibility download group
resource "files_permission" "client_group_eligibility_download_permission" {
for_each = var.clients
path = "${files_folder.medicare_clients_folder.path}/${each.value}/Eligibility"
group_name = "${each.value} Eligibility Download Group"
permission = "readonly"
depends_on = [files_group.client_eligibility_download_group, files_folder.client_eligibility_folder]
}
The code above assigns access permissions to the groups and specifies dependencies so that the permissions are only assigned after the groups and their corresponding subfolders are successfully created.
Duplicate this step for each required subfolder. For this use case, repeat the code but replace all mentions of "eligibility" with "prescription drug event".
Execution
When the code above runs, Terraform creates all these resources and manages the dependencies between them.
Each time you add a client to the variable, Terraform manages 16 corresponding resources for that client: 1 user account, 3 folders, 6 groups, and 6 access permissions. A single addition to the variable drives all the changes needed to onboard the client.
In real-world scenarios, an onboarding system updates the client variable programmatically so that the entire process is automated, removing delays and human error.
Get The File Orchestration Platform Today
4,000+ organizations trust Files.com for mission-critical file operations. Start your free trial now and build your first flow in 60 seconds.
No credit card required • 7-day free trial • Setup in minutes