Terraform aws_efs_file_system for Amazon Elastic File System

Amazon Elastic File System provides scalable file storage for use with Amazon EC2 instances. Setting up AWS EFS with Terraform is a detailed guide to deploying Amazon Elastic File System using Terraform Infrastructure as Code. The guide shows how to set up EFS using Terraform.

Prerequisites and Project Structure

Before provisioning an EFS file system with Terraform, the following prerequisites are required.

  • AWS CLI configured
  • Terraform installed
  • VPC and subnets already configured
  • Basic understanding of network file systems

A typical project structure used for this workflow is:

aws-efs-terraform/
├── main.tf
├── variables.tf
├── outputs.tf
└── terraform.tfvars

Core Resource awsefsfile_system

Manages an Efs File System resource.

A minimal configuration to get started is:

hcl resource "aws_efs_file_system" "example" { # Required arguments name = "my-efs-file-system" }

Refer to the Terraform Registry docs for all available arguments.

In production configurations the file system resource is defined with additional arguments for idempotency, encryption and lifecycle management.

```hcl
provider "aws" {
region = var.aws_region
}

resource "awsefsfilesystem" "main" {
creation
token = "${var.projectname}-efs"
encrypted = true
lifecycle
policy {
transitiontoia = "AFTER30DAYS"
}
tags = {
Name = "${var.project_name}-efs"
}
}
```

The core of the storage layer is the awsefsfilesystem resource named appefs. It is initialized with a creation_token set to "appEFS" to ensure idempotency during the provisioning process. The system is tagged with the environment name e.g., staging-efs for resource tracking.

The file system ID is exported as a Terraform output, allowing other modules or external systems to reference the specific storage resource.

Mount Targets and Network Placement

To make the EFS volume accessible within the VPC, mount targets are created in every private subnet where application instances reside.

The example configuration uses a count based mount target:

hcl resource "aws_efs_mount_target" "main" { count = length(var.subnet_ids) file_system_id = aws_efs_file_system.main.id subnet_id = var.subnet_ids[count.index] security_groups = [aws_security_group.efs.id] }

In an Auto Scaling Group architecture, awsefsmounttarget resource uses a foreach meta-argument to iterate over the awssubnet.private collection. filesystemid is set to the specific subnetid and efs_sg security group.

This enables EC2 instances within the Auto Scaling Group to share data across multiple Availability Zones, ensuring that files stored by one instance are accessible to all others in the cluster.

Security Group and Least Privilege Access

Security for the file system is enforced through the efs_sg security group. It follows the principle of least privilege by restricting access to only the compute tier.

hcl resource "aws_security_group" "efs" { name = "${var.project_name}-efs-sg" description = "Allow EFS inbound traffic" vpc_id = var.vpc_id ingress { description = "NFS from VPC" from_port = 2049 to_port = 2049 protocol = "tcp" security_groups = var.allowed_security_group_ids } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.project_name}-efs-sg" } }

Rule Type Port Protocol Source/Destination Purpose
Ingress 2049 TCP awssecuritygroup.ec2_sg.id Allows NFS traffic only from application instances
Egress All -1 0.0.0.0/0 Open egress

The diagram illustrates how the Terraform resources bridge the networking layer to the storage layer.

Backup Policy and Access Points

A production EFS setup involves more than just the file system resource.

Backup Policy optional:

hcl resource "aws_efs_backup_policy" "policy" { file_system_id = aws_efs_file_system.main.id backup_policy { status = "ENABLED" } }

Access Point optional:

hcl resource "aws_efs_access_point" "test" { file_system_id =

Outputs should be exported for downstream modules.

```hcl
output "efsid" {
value = aws
efsfilesystem.main.id
description = "EFS file system ID"
}

output "efsdnsname" {
value = awsefsfilesystem.main.dnsname
description = "EFS DNS name for mounting"
}

output "accesspointids" {
value = {
api = awsefsaccesspoint.api.id
worker = aws
efsaccesspoint.worker.id
}
description = "Access point IDs by service"
}
```

Don't forget to export the values other modules will need.

Terraform AWS Modules for EFS

A Terraform module which creates AWS EFS elastic file system resources is available. See examples directory for working examples to reference.

Example usage:

hcl 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" }

Module requirements:

Name Version
terraform >= 1.5.7
aws >= 6.28
Name Version
aws >= 6.28

Resources created by the module:

Name Type
awsefsaccess_point.this resource
awsefsbackup_policy.this resource
awsefsfile_system.this resource
awsefsfilesystempolicy.this resource
awsefsmount_target.this resource
awsefsreplication_configuration.this resource
awssecuritygroup.this resource
awsvpcsecuritygroupegress_rule.this resource
awsvpcsecuritygroupingress_rule.this resource

Data sources:

Name Type
awsiampolicy_document.policy data source

Module input variables include:

Name Description Type Default Required
access_points A map of access point definitions to create map(object({ {} no
attach_policy Determines whether a policy is attached to the file system bool true no
availabilityzonename The AWS Availability Zone in which to create the file system. Used to create a file system that uses One Zone storage classes string null no
bypasspolicylockoutsafetycheck A flag to indicate whether to bypass the awsefsfilesystempolicy lockout safety check

Configuration Patterns and Idempotency

Creation token is used to ensure idempotent provisioning. The example sets creationtoken to "appEFS" and also to "${var.projectname}-efs". Tags such as Name = "${var.project_name}-efs" support resource tracking.

Encryption is enabled with encrypted = true. KMS key ARN can be provided via kmskeyarn for customer managed encryption.

Lifecycle policy transitiontoia = "AFTER30DAYS" enables Infrequent Access transition.

Performance mode can be set, with maxIO as a commented option.

Outputs and Cross Module Integration

The file system ID export enables other modules or external systems to reference the specific storage resource.

Key outputs to publish:

  • efs_id
  • efsdnsname
  • accesspointids

These outputs allow mounting commands and application configuration to reference the EFS DNS name and access points by service.

Summary of Resource Relationships

Resource Purpose
awsefsfile_system Core scalable file storage
awsefsmount_target Network attachment per subnet
awssecuritygroup NFS 2049 ingress control
awsefsbackup_policy Automated backup enablement
awsefsaccess_point POSIX user and permission isolation

The Terraform resources in efs.tf bridge the networking layer to the storage layer.

Conclusion

A production EFS setup involves more than just the file system resource. The awsefsfilesystem resource forms the storage core, but effective deployment requires coordinated mount targets, security groups enforcing least privilege, optional backup policy, and access points for service isolation. Terraform enables repeatable creation of these components through variables, outputs, and modules. Creation token ensures idempotency, encryption and lifecycle policies provide operational guardrails, and security groups restrict NFS traffic to the compute tier only. Using module outputs for efsid, efsdnsname and accesspointids allows clean cross module composition in full stack AWS architectures.

Sources

  1. thecloudpanda.com
  2. awsfundamentals.com
  3. oneuptime.com
  4. github.com
  5. deepwiki.com

Related Posts