AWS EFS Terraform module

January 8, 2026 ยท View on GitHub

Terraform module which creates AWS EFS (elastic file system) resources.

SWUbanner

Usage

See examples directory for working examples to reference:

module "efs" {
  source = "terraform-aws-modules/efs/aws"

  # File system
  name           = "example"
  creation_token = "example-token"
  encrypted      = true
  kms_key_arn    = "arn:aws:kms:eu-west-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"

  # performance_mode                = "maxIO"
  # NB! PROVISIONED TROUGHPUT MODE WITH 256 MIBPS IS EXPENSIVE ~\$1500/month
  # throughput_mode                 = "provisioned"
  # provisioned_throughput_in_mibps = 256

  lifecycle_policy = {
    transition_to_ia = "AFTER_30_DAYS"
  }

  # File system policy
  attach_policy                      = true
  bypass_policy_lockout_safety_check = false
  policy_statements = [
    {
      sid     = "Example"
      actions = ["elasticfilesystem:ClientMount"]
      principals = [
        {
          type        = "AWS"
          identifiers = ["arn:aws:iam::111122223333:role/EfsReadOnly"]
        }
      ]
    }
  ]

  # Mount targets / security group
  mount_targets = {
    "eu-west-1a" = {
      subnet_id = "subnet-abcde012"
    }
    "eu-west-1b" = {
      subnet_id = "subnet-bcde012a"
    }
    "eu-west-1c" = {
      subnet_id = "subnet-fghi345a"
    }
  }
  security_group_description = "Example EFS security group"
  security_group_vpc_id      = "vpc-1234556abcdef"
  security_group_ingress_rules = {
    vpc_1 = {
      # relying on the defaults provided for EFS/NFS (2049/TCP + ingress)
      description = "NFS ingress from VPC private subnets"
      cidr_ipv4   = "10.99.3.0/24"
    }
    vpc_2 = {
      # relying on the defaults provided for EFS/NFS (2049/TCP + ingress)
      description = "NFS ingress from VPC private subnets"
      cidr_ipv4   = "10.99.4.0/24"
    }
    vpc_3 = {
      # relying on the defaults provided for EFS/NFS (2049/TCP + ingress)
      description = "NFS ingress from VPC private subnets"
      cidr_ipv4   = "10.99.5.0/24"
    }
  }

  # Access point(s)
  access_points = {
    posix_example = {
      name = "posix-example"
      posix_user = {
        gid            = 1001
        uid            = 1001
        secondary_gids = [1002]
      }

      tags = {
        Additionl = "yes"
      }
    }
    root_example = {
      root_directory = {
        path = "/example"
        creation_info = {
          owner_gid   = 1001
          owner_uid   = 1001
          permissions = "755"
        }
      }
    }
  }

  # Backup policy
  enable_backup_policy = true

  # Replication configuration
  create_replication_configuration = true
  replication_configuration_destination = {
    region = "eu-west-2"
  }

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

Examples

Examples codified under the examples are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module. If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you!

Requirements

NameVersion
terraform>= 1.5.7
aws>= 6.28

Providers

NameVersion
aws>= 6.28

Modules

No modules.

Resources

NameType
aws_efs_access_point.thisresource
aws_efs_backup_policy.thisresource
aws_efs_file_system.thisresource
aws_efs_file_system_policy.thisresource
aws_efs_mount_target.thisresource
aws_efs_replication_configuration.thisresource
aws_security_group.thisresource
aws_vpc_security_group_egress_rule.thisresource
aws_vpc_security_group_ingress_rule.thisresource
aws_iam_policy_document.policydata source

Inputs

NameDescriptionTypeDefaultRequired
access_pointsA map of access point definitions to create
map(object({
name = optional(string)
tags = optional(map(string), {})
posix_user = optional(object({
gid = number
uid = number
secondary_gids = optional(list(number))
}))
root_directory = optional(object({
path = optional(string)
creation_info = optional(object({
owner_gid = number
owner_uid = number
permissions = string
}))
}))
}))
{}no
attach_policyDetermines whether a policy is attached to the file systembooltrueno
availability_zone_nameThe AWS Availability Zone in which to create the file system. Used to create a file system that uses One Zone storage classesstringnullno
bypass_policy_lockout_safety_checkA flag to indicate whether to bypass the aws_efs_file_system_policy lockout safety check. Defaults to falseboolnullno
createDetermines whether resources will be created (affects all resources)booltrueno
create_backup_policyDetermines whether a backup policy is createdbooltrueno
create_replication_configurationDetermines whether a replication configuration is createdboolfalseno
create_security_groupDetermines whether a security group is createdbooltrueno
creation_tokenA unique name (a maximum of 64 characters are allowed) used as reference when creating the Elastic File System to ensure idempotent file system creation. By default generated by Terraformstringnullno
deny_nonsecure_transportDetermines whether aws:SecureTransport is required when connecting to elastic file systembooltrueno
deny_nonsecure_transport_via_mount_targetDetermines whether to use the common policy option for denying nonsecure transport which allows all AWS principals when accessed via EFS mounted targetbooltrueno
enable_backup_policyDetermines whether a backup policy is ENABLED or DISABLEDbooltrueno
encryptedIf true, the disk will be encryptedbooltrueno
kms_key_arnThe ARN for the KMS encryption key. When specifying kms_key_arn, encrypted needs to be set to truestringnullno
lifecycle_policyA file system lifecycle policy object
object({
transition_to_ia = optional(string)
transition_to_archive = optional(string)
transition_to_primary_storage_class = optional(string)
})
{}no
mount_targetsA map of mount target definitions to create
map(object({
ip_address = optional(string)
ip_address_type = optional(string)
ipv6_address = optional(string)
region = optional(string)
security_groups = optional(list(string), [])
subnet_id = string
}))
{}no
nameThe name of the file systemstring""no
override_policy_documentsList of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank sids will override statements with the same sidlist(string)[]no
performance_modeThe file system performance mode. Can be either generalPurpose or maxIO. Default is generalPurposestringnullno
policy_statementsA list of IAM policy statements for custom permission usage
map(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
conditions = optional(list(object({
test = string
values = list(string)
variable = string
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
nullno
protectionA map of file protection configurations
object({
replication_overwrite = optional(string)
})
nullno
provisioned_throughput_in_mibpsThe throughput, measured in MiB/s, that you want to provision for the file system. Only applicable with throughput_mode set to provisionednumbernullno
regionRegion where this resource will be managed. Defaults to the Region set in the provider configurationstringnullno
replication_configuration_destinationA destination configuration block
object({
availability_zone_name = optional(string)
file_system_id = optional(string)
kms_key_id = optional(string)
region = optional(string)
})
nullno
security_group_descriptionSecurity group description. Defaults to Managed by Terraformstringnullno
security_group_egress_rulesMap of security group egress rules to add to the security group created
map(object({
name = optional(string)

cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number, 2049)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
region = optional(string)
tags = optional(map(string), {})
to_port = optional(number, 2049)
}))
{}no
security_group_ingress_rulesMap of security group ingress rules to add to the security group created
map(object({
name = optional(string)

cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number, 2049)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
region = optional(string)
tags = optional(map(string), {})
to_port = optional(number, 2049)
}))
{}no
security_group_nameName to assign to the security group. If omitted, Terraform will assign a random, unique namestringnullno
security_group_use_name_prefixDetermines whether to use a name prefix for the security group. If true, the security_group_name value will be used as a prefixboolfalseno
security_group_vpc_idThe VPC ID where the security group will be createdstringnullno
source_policy_documentsList of IAM policy documents that are merged together into the exported document. Statements must have unique sidslist(string)[]no
tagsA map of tags to add to all resourcesmap(string){}no
throughput_modeThroughput mode for the file system. Defaults to bursting. Valid values: bursting, elastic, and provisioned. When using provisioned, also set provisioned_throughput_in_mibpsstringnullno

Outputs

NameDescription
access_pointsMap of access points created and their attributes
arnAmazon Resource Name of the file system
dns_nameThe DNS name for the filesystem per documented convention
idThe ID that identifies the file system (e.g., fs-ccfc0d65)
mount_targetsMap of mount targets created and their attributes
replication_configuration_destination_file_system_idThe file system ID of the replica
security_group_arnARN of the security group
security_group_idID of the security group
size_in_bytesThe latest known metered size (in bytes) of data stored in the file system, the value is not the exact size that the file system was at any point in time

License

Apache-2.0 Licensed. See LICENSE.