Terraform: Amazon Elastic File System mounted to a Subnet
By: Garrett Sweeney
Tags: Aws Efs, Elastic File System, AWS, Cloud, Terraform

EFS & EFS IA

Welcome to the Cloud Tidbits publication! This article will demonstrate how to use Terraform v0.12+ to create EFS and mount it to your subnet. A follow-up article will demonstrate how to access the file system from lambda.

Start by ensuring the client machine (i.e., MacBook) is prepared to create AWS resources with Terraform. Review the following article and continue below.

Next, create a new repository and scaffold out the files needed. My repository looks like this. Don’t worry about the terraform.tfstate right now, but create the rest of the files with the simple one-liner below the tree.

Here’s the simple one-liner that can set this up:

mkdir vars && touch main.tf outputs.tf variables.tf README.md vars/sample.tfvar

Before creating AWS resources, set up the terraform and provider blocks to specify the required version of terraform and the AWS region to create the resources.

I’m using a variable for the region to make it configurable. Add the following lines to the main.tf and variables.tf respectively.

More information can be found about the Terraform Block and the provider configuration, but this setup is all we need to create AWS resources in the US East 1 region.

aws_efs_file_system

Now we can create our Amazon Elastic File System. Explore all of the different configurations on the HashiCorp documentation for the resource. For the sake of the demo, I’m going to build out variables for each of the argument references to make it as configurable as possible!

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_file_system#argument-reference as of 12/13/2020

Below is the aws_efs_file_system resource I’ve defined as file_system . Note that all the block attributes are defined as variables and defined in the variables.tf file. I’m using almost all of the default values.

Note, however, that some of the attributes have conditional operators. For example, kms_key_id can only be defined when encrypted is true and a value has been provided for kms_key_id . Also, the provisioned_throughput_in_mibps attribute can only be defined when throughput_mode is provisioned, so I perform a check that it set to provisioned before assigned the provisioned_throughput_in_mibps variable value.

Amazon EFS Mount Target

Now the File System has to be mounted using an EFS Mount Target. You can explore all of the different configurations on the Hashicorp documentation for the resource. I wouldn’t say there’s anything notable below, as all that is required is the subnet in which to mount and the reference to the newly created File System.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_mount_target#argument-reference as of 12/13/2020

In a production environment, I would recommend some Security Groups. But I’m going to tear this down 15 minutes after I create it.

A security group acts as a firewall, and the rules that you add define the traffic flow.

sample.tfvars

As is, you can plan and apply resources and provide values via the command line, but I recommend creating a .tfvars file in your repository.

I’ve put mine in the vars directory, and it looks like this. Note that you’ll need to update the subnet with an actual subnet:

Create your Amazon EFS!

All that is left is a few commands to create your Amazon EFS!

Initialize the repository with terraform init

Then use your tfvars file to plan and preview the resources being created with terraform plan -var-file="vars/sample.tfvars" .

Once satisfied with the plan, run the apply with terraform apply -var-file="vars/sample.tfvars" .

If the creation was successful, 2 resources should be created:

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Check out the resources in the console

In the AWS Console, go to the EFS Service, and you should see your newly created file system!

Amazon EFS Console

Any questions, comments, or suggestions? Let’s discuss in the comments!

Code in Github