Bootstrap: auto-mount the new EFS to a new EC2 instance

5,179 views
Skip to first unread message

SudoSu

unread,
Aug 14, 2016, 11:11:35 PM8/14/16
to Terraform
Hello guys!

EFS, EC2, and AS are parts of our infrastructure that will be created by Terraform.

Now I'm struggling how to mount the new EFS to the new EC2 automatically during the deployment (single deployment or via Auto Scaling).

I thought bootstrapping was the answer. I have these lines in my user-data-client-sync.sh script:


Is it possible to get the Filesystem ID and AWS Region from Terraform, then pass it to my user-data-client-sync.sh for bootstrapping?


variable "region" {

   
default = "us-east-1"
}

variable
"azs" {

   
default = {
       
"us-east-1" = "us-east-1a, us-east-1b, us-east-1c, us-east-1e"
   
}
}


resource "aws_efs_file_system" "client-efs" {
    performance_mode
= "generalPurpose"

    tags
{
       
Name = "client-efs"
       
CostCenter = "${lookup(var.tags, "costcenter")}"
       
Environment = "${lookup(var.tags, "environment")}"
       
Manager = "${lookup(var.tags, "manager")}"
   
}
}

resource
"aws_efs_mount_target" "client-mount-target" {
    count
= "${length(split(", ", lookup(var.azs, var.region)))}"
    file_system_id
= "${aws_efs_file_system.client-efs.id}"
    subnet_id
= "${element(aws_subnet.client-private-subnets.*.id, count.index)}"
    security_groups
= ["${aws_security_group.client-efs.id}"]
}



resource "aws_instance" "client-sync" {
    ami
= "${data.aws_ami.amazon-ami.id}"
    availability_zone
= "${element(split(", ", lookup(var.azs, var.region)), 0)}"
    instance_type
= "t2.micro"
    key_name
= "${var.aws_key_name}"
    vpc_security_group_ids
= ["${aws_security_group.client-sync.id}"]
    subnet_id
= "${element(aws_subnet.client-public-subnets.*.id, 0)}"
    associate_public_ip_address
= true
    user_data
= "${file("user-data-client-sync.sh")}"

    root_block_device
{
        volume_type
= "gp2"
   
}

    tags
{
       
Name = "client-sync"
       
CostCenter = "${lookup(var.tags, "costcenter")}"
       
Environment = "${lookup(var.tags, "environment")}"
       
Manager = "${lookup(var.tags, "manager")}"
   
}
}

resource
"aws_eip" "client-sync" {
    instance
= "${aws_instance.client-sync.id}"
    vpc
= true
}

user-data-client-sync.sh

#!/bin/bash
yum
-config-manager --enable epel
yum update
-y
yum
-y install nfs-utils
mkdir
/mnt/efs
mount
-t nfs4 -o nfsvers=4.1 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).${aws_efs_file_system.client-efs.id}.efs.${var.region}.amazonaws.com:/ /mnt/efs
echo
"$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).${aws_efs_file_system.client-efs.id}.efs.${var.region}.amazonaws.com:/ /mnt/efs nfs defaults 0 0" >> /etc/fstab

Thank in advance!

Cheers,
SudoSu

Igor Cicimov

unread,
Aug 15, 2016, 4:18:14 AM8/15/16
to Terraform
I think you should read about templates https://www.terraform.io/docs/providers/template/

SudoSu

unread,
Sep 1, 2016, 3:19:15 AM9/1/16
to Terraform
Hello Igor,

Thanks! I'll check that out!

Cheers,
SudoSu

Ethan Fahy

unread,
Sep 1, 2016, 1:49:49 PM9/1/16
to Terraform
I have done what you are attempting to do using a terraform aws_instance provisioner of type=remote-exec as seen here: https://www.terraform.io/docs/provisioners/remote-exec.html

Add something like this to your ec2 resource block:
provisioner "remote-exec" {
 
inline = [
 
# mount EFS volume
 
# https://docs.aws.amazon.com/efs/latest/ug/gs-step-three-connect-to-ec2-instance.html
 
# create a directory to mount our efs volume to
 
"sudo mkdir -p /mnt/efs",
 
# mount the efs volume
 
"sudo mount -t nfs4 -o nfsvers=4.1 ${aws_efs_mount_target.efs-mount-target.dns_name}:/ /mnt/efs",
 
# create fstab entry to ensure automount on reboots
 
# https://docs.aws.amazon.com/efs/latest/ug/mount-fs-auto-mount-onreboot.html#mount-fs-auto-mount-on-creation
 
"sudo su -c \"echo '${aws_efs_mount_target.efs-mount-target.dns_name}:/ /mnt/efs nfs defaults,vers=4.1 0 0' >> /etc/fstab\"" #create fstab entry to ensure automount on reboots
 
]
 
}
You will need to ensure that you also add a "connection" block to your aws_instance block to let terraform where your local .pem key file is so that it can execute the remote-exec provisioner.  You will also need to ensure that you have properly configured the security groups for the efs mount target and the ec2 instance per instructions here: 
Good luck!

Ionut Cadariu

unread,
Sep 16, 2016, 7:15:35 AM9/16/16
to Terraform
Hello,

Did anyone found a workaround of automatically mounting EFS on machines created using AS - aws_launch_configuration?

Thanks,
Ionut

David Adams

unread,
Sep 16, 2016, 7:44:54 AM9/16/16
to terrafo...@googlegroups.com
If you want to use a launch configuration you'll need to add the EFS mounting to the AMI you launch.
--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/hashicorp/terraform/issues
IRC: #terraform-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Terraform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-too...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/terraform-tool/71e11436-1b59-4462-9bce-ab765a0d6bdb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages