Repeatable Provisioning
An administrator maintaining several team work areas can express their Files.com folder and access arrangement in the team's existing Terraform or OpenTofu configuration. Accounts, Group memberships, and folder permissions have separate purposes, so a useful provisioning pattern needs to connect all three.
In this example, each team has a folder and a Group with Full permission on it, while each person has an individual regular user account belonging to the appropriate Group. The team roster determines the work areas; the person roster determines who belongs to each one. Changes to those inputs can update access or remove resources already in use.
Account and Configuration Ownership
Use this pattern when configuration owns the regular accounts and Groups. If your identity provider owns their lifecycle through SCIM, keep that ownership there and manage only the other resources through code. Partners provide a different model for external organizations: Partner Users share Partner permissions and cannot join Groups. Choose that model before adapting a regular-user example for external access.
Configure the Files.com provider first. The sample uses the Default Workspace and creates new objects. For existing objects, import them into their intended resource addresses before applying the configuration.
Inputs and Stable Identifiers
Teams and people have separate lifecycles: several people can share one team's work area, and a person can move to another team without recreating its folder. Separate input collections keep account changes distinct from changes to the shared folders and Groups.
The map keys are stable identifiers, while names, email addresses, and folder names are separate values. A person's display name can then change without changing their resource address.
variable "teams" {
type = map(object({
name = string
folder = string
}))
}
variable "people" {
type = map(object({
username = string
name = string
email = string
team = string
}))
}
Supply the values in a variable file such as teams.tfvars:
teams = {
"team-1001" = { name = "Finance", folder = "Finance" }
"team-1002" = { name = "Operations", folder = "Operations" }
}
people = {
"person-2001" = {
username = "alex_finance"
name = "Alex Morgan"
email = "alex@example.com"
team = "team-1001"
}
"person-2002" = {
username = "blair_operations"
name = "Blair Chen"
email = "blair@example.com"
team = "team-1002"
}
}
Every person's team must match a key in teams. Use real usernames that meet the Site's username requirements, real recipient addresses, and unused folder and Group names. The sample creates regular human accounts with Email Signup, so recipients receive invitations to establish their own passwords. Select your organization's authentication arrangement before applying it.
Supply inputs through your existing variable and secret-management conventions. Keep credentials out of ordinary variable files and shell history, and protect state and plans even when values are marked sensitive.
Folders, Groups, Accounts, and Permissions
Each resource uses the same team key to refer to the appropriate instance of another resource. The folder path depends on the shared root, each person's membership depends on their team Group, and each permission depends on its folder and Group. These references establish the creation order.
resource "files_folder" "teams_root" {
path = "Teams"
}
resource "files_folder" "team" {
for_each = var.teams
path = "${files_folder.teams_root.path}/${each.value.folder}"
}
resource "files_group" "team" {
for_each = var.teams
name = each.value.name
}
resource "files_user" "person" {
for_each = var.people
username = each.value.username
name = each.value.name
email = each.value.email
authentication_method = "email_signup"
self_managed = true
site_admin = false
group_ids = tostring(files_group.team[each.value.team].id)
}
resource "files_permission" "team" {
for_each = var.teams
path = files_folder.team[each.key].path
group_id = files_group.team[each.key].id
permission = "full"
}
This configuration owns each person's Group membership through the user's group_ids. Do not also manage the same membership through a Group's member list or an individual membership resource. When a person needs several Groups, include all intended Group IDs in the comma-separated value rather than letting separate definitions compete for the relationship.
Full permission lets team members change and delete files in their work area. Choose the permission level that fits the work. A restricted delivery folder may need Write or Read access instead. Folder permissions and the users' allowed protocols are separate controls.
Plans and Effective Access
Include teams.tfvars in your usual plan command: terraform plan -var-file=teams.tfvars or tofu plan -var-file=teams.tfvars. Review the accounts, memberships, paths, and permissions before applying with the same inputs. A saved plan must be the artifact reviewed for that environment; applying without one creates a new plan.
After applying, Check Access for the intended users and verify their actual file operations through the apps or protocols they will use. Other direct or inherited permissions can also grant access. Creating this arrangement does not remove those grants or establish isolation from other work areas by itself.
Changes to the Roster
Adding a team creates its Group, folder, and permission. Adding a person creates their account and membership. Moving a person to another team updates the membership declared here; check the resulting access and any additional grants.
Removing a person from the input plans deletion of their managed account. Removing a team plans deletion of its managed resources, including its folder. Arrange file retention and dependencies before removing a work area. The deletion safeguards apply to resources created through a loop just as they do to individually declared resources.
Changing a map key changes the resource address. Preserve existing associations through supported resource moves when changing key structure. A stable key protects that association when a display name changes, but changing a username or folder path can still produce consequential updates or replacements; inspect the plan rather than assuming the change is cosmetic.