Amazon Elastic File System (Amazon EFS) は、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのファイルストレージサービスです。Amazon EFS を使用すると、ファイルの追加および削除に合わせてストレージ容量が自動的に拡大/縮小するため、アプリケーションには必要なときにストレージが提供されます。
以下のサンプルテンプレートは、Amazon EFS ファイルシステムに関連付けられる EC2 インスタンス (Auto Scaling グループ内) をデプロイします。ファイルシステムにインスタンスを関連付けるために、インスタンスは cfn-init ヘルパースクリプトを実行します。これにより、nfs-utils
yum パッケージがダウンロードおよびインストールされて、新しいディレクトリが作成され、ファイルシステムの DNS 名を使用してそのディレクトリにファイルシステムがマウントされます。ファイルシステムの DNS 名は、Amazon EC2 インスタンスのアベイラビリティーゾーンでマウントターゲットの IP アドレスに解決されます。DNS 名構造については、「Amazon Elastic File System ユーザーガイド」の「Mounting File Systems」(ファイルシステムのマウント) を参照してください。
Network File System (NFS) のアクティビティを測定するために、テンプレートにはカスタムの Amazon CloudWatch メトリクスが含まれています。このテンプレートでは、VPC、サブネット、およびセキュリティグループも作成します。インスタンスとファイルシステムとの通信を許可するには、VPC で DNS が有効になっていて、マウントターゲットと EC2 インスタンスはサブネットに指定された同じアベイラビリティーゾーン (AZ) にある必要があります。
マウントターゲットのセキュリティグループは TCP ポート 2049 へのネットワーク接続を有効にします。これは、NFSv4 クライアントがファイルシステムをマウントするために必要です。EC2 インスタンスとマウントターゲット向けのセキュリティグループの詳細については、「Amazon Elastic File System User Guide」(Amazon Elastic File System ユーザーガイド) の「Security」(セキュリティ) を参照してください。
注記
置き換えの原因となる更新をマウントターゲットに対して行った場合は、関連するファイルシステムを使用するインスタンスまたはアプリケーションが中断される可能性があります。このため、コミットされていない書き込みが失われることがあります。中断を回避するには、希望する容量をゼロに設定することで、マウントターゲットの更新時にインスタンスを停止します。これにより、マウントターゲットを削除する前に、インスタンスがファイルシステムをアンマウントできるようになります。マウントの更新が完了したら、希望する容量を設定して後続の更新のインスタンスを開始します。
JSON
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "This template creates an Amazon EFS file system and mount target and associates it with Amazon EC2 instances in an Auto Scaling group. **WARNING** This template creates Amazon EC2 instances and related resources. You will be billed for the AWS resources used if you create a stack from this template.",
"Parameters": {
"InstanceType" : {
"Description" : "WebServer EC2 instance type",
"Type" : "String",
"Default" : "t2.small",
"AllowedValues" : [
"t1.micro",
"t2.nano",
"t2.micro",
"t2.small",
"t2.medium",
"t2.large",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge",
"m2.xlarge",
"m2.2xlarge",
"m2.4xlarge",
"m3.medium",
"m3.large",
"m3.xlarge",
"m3.2xlarge",
"m4.large",
"m4.xlarge",
"m4.2xlarge",
"m4.4xlarge",
"m4.10xlarge",
"c1.medium",
"c1.xlarge",
"c3.large",
"c3.xlarge",
"c3.2xlarge",
"c3.4xlarge",
"c3.8xlarge",
"c4.large",
"c4.xlarge",
"c4.2xlarge",
"c4.4xlarge",
"c4.8xlarge",
"g2.2xlarge",
"g2.8xlarge",
"r3.large",
"r3.xlarge",
"r3.2xlarge",
"r3.4xlarge",
"r3.8xlarge",
"i2.xlarge",
"i2.2xlarge",
"i2.4xlarge",
"i2.8xlarge",
"d2.xlarge",
"d2.2xlarge",
"d2.4xlarge",
"d2.8xlarge",
"hi1.4xlarge",
"hs1.8xlarge",
"cr1.8xlarge",
"cc2.8xlarge",
"cg1.4xlarge"
],
"ConstraintDescription" : "must be a valid EC2 instance type."
},
"KeyName": {
"Type": "AWS::EC2::KeyPair::KeyName",
"Description": "Name of an existing EC2 key pair to enable SSH access to the EC2 instances"
},
"AsgMaxSize": {
"Type": "Number",
"Description": "Maximum size and initial desired capacity of Auto Scaling Group",
"Default": "2"
},
"SSHLocation" : {
"Description" : "The IP address range that can be used to connect to the EC2 instances by using SSH",
"Type": "String",
"MinLength": "9",
"MaxLength": "18",
"Default": "0.0.0.0/0",
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
},
"VolumeName" : {
"Description" : "The name to be used for the EFS volume",
"Type": "String",
"MinLength": "1",
"Default": "myEFSvolume"
},
"MountPoint" : {
"Description" : "The Linux mount point for the EFS volume",
"Type": "String",
"MinLength": "1",
"Default": "myEFSvolume"
}
},
"Mappings" : {
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "HVM64" },
"t2.nano" : { "Arch" : "HVM64" },
"t2.micro" : { "Arch" : "HVM64" },
"t2.small" : { "Arch" : "HVM64" },
"t2.medium" : { "Arch" : "HVM64" },
"t2.large" : { "Arch" : "HVM64" },
"m1.small" : { "Arch" : "HVM64" },
"m1.medium" : { "Arch" : "HVM64" },
"m1.large" : { "Arch" : "HVM64" },
"m1.xlarge" : { "Arch" : "HVM64" },
"m2.xlarge" : { "Arch" : "HVM64" },
"m2.2xlarge" : { "Arch" : "HVM64" },
"m2.4xlarge" : { "Arch" : "HVM64" },
"m3.medium" : { "Arch" : "HVM64" },
"m3.large" : { "Arch" : "HVM64" },
"m3.xlarge" : { "Arch" : "HVM64" },
"m3.2xlarge" : { "Arch" : "HVM64" },
"m4.large" : { "Arch" : "HVM64" },
"m4.xlarge" : { "Arch" : "HVM64" },
"m4.2xlarge" : { "Arch" : "HVM64" },
"m4.4xlarge" : { "Arch" : "HVM64" },
"m4.10xlarge" : { "Arch" : "HVM64" },
"c1.medium" : { "Arch" : "HVM64" },
"c1.xlarge" : { "Arch" : "HVM64" },
"c3.large" : { "Arch" : "HVM64" },
"c3.xlarge" : { "Arch" : "HVM64" },
"c3.2xlarge" : { "Arch" : "HVM64" },
"c3.4xlarge" : { "Arch" : "HVM64" },
"c3.8xlarge" : { "Arch" : "HVM64" },
"c4.large" : { "Arch" : "HVM64" },
"c4.xlarge" : { "Arch" : "HVM64" },
"c4.2xlarge" : { "Arch" : "HVM64" },
"c4.4xlarge" : { "Arch" : "HVM64" },
"c4.8xlarge" : { "Arch" : "HVM64" },
"g2.2xlarge" : { "Arch" : "HVMG2" },
"g2.8xlarge" : { "Arch" : "HVMG2" },
"r3.large" : { "Arch" : "HVM64" },
"r3.xlarge" : { "Arch" : "HVM64" },
"r3.2xlarge" : { "Arch" : "HVM64" },
"r3.4xlarge" : { "Arch" : "HVM64" },
"r3.8xlarge" : { "Arch" : "HVM64" },
"i2.xlarge" : { "Arch" : "HVM64" },
"i2.2xlarge" : { "Arch" : "HVM64" },
"i2.4xlarge" : { "Arch" : "HVM64" },
"i2.8xlarge" : { "Arch" : "HVM64" },
"d2.xlarge" : { "Arch" : "HVM64" },
"d2.2xlarge" : { "Arch" : "HVM64" },
"d2.4xlarge" : { "Arch" : "HVM64" },
"d2.8xlarge" : { "Arch" : "HVM64" },
"hi1.4xlarge" : { "Arch" : "HVM64" },
"hs1.8xlarge" : { "Arch" : "HVM64" },
"cr1.8xlarge" : { "Arch" : "HVM64" },
"cc2.8xlarge" : { "Arch" : "HVM64" }
},
"AWSRegionArch2AMI" : {
"us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},
"us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"},
"us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},
"eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},
"eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"},
"eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"},
"eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"},
"ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},
"ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"},
"ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"},
"ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"},
"ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"},
"ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"},
"us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"},
"ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"},
"sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"},
"cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"},
"cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"}
}
},
"Resources": {
"CloudWatchPutMetricsRole" : {
"Type" : "AWS::IAM::Role",
"Properties" : {
"AssumeRolePolicyDocument" : {
"Statement" : [ {
"Effect" : "Allow",
"Principal" : {
"Service" : [ "ec2.amazonaws.com" ]
},
"Action" : [ "sts:AssumeRole" ]
} ]
},
"Path" : "/"
}
},
"CloudWatchPutMetricsRolePolicy" : {
"Type" : "AWS::IAM::Policy",
"Properties" : {
"PolicyName" : "CloudWatch_PutMetricData",
"PolicyDocument" : {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchPutMetricData",
"Effect": "Allow",
"Action": ["cloudwatch:PutMetricData"],
"Resource": ["*"]
}
]
},
"Roles" : [ { "Ref" : "CloudWatchPutMetricsRole" } ]
}
},
"CloudWatchPutMetricsInstanceProfile" : {
"Type" : "AWS::IAM::InstanceProfile",
"Properties" : {
"Path" : "/",
"Roles" : [ { "Ref" : "CloudWatchPutMetricsRole" } ]
}
},
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"CidrBlock": "10.0.0.0/16",
"Tags": [ {"Key": "Application", "Value": { "Ref": "AWS::StackId"} } ]
}
},
"InternetGateway" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [
{ "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } },
{ "Key" : "Network", "Value" : "Public" }
]
}
},
"GatewayToInternet" : {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"InternetGatewayId" : { "Ref" : "InternetGateway" }
}
},
"RouteTable":{
"Type":"AWS::EC2::RouteTable",
"Properties":{
"VpcId": {"Ref":"VPC"}
}
},
"SubnetRouteTableAssoc": {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"RouteTableId" : {"Ref":"RouteTable"},
"SubnetId" : {"Ref":"Subnet"}
}
},
"InternetGatewayRoute": {
"Type":"AWS::EC2::Route",
"Properties":{
"DestinationCidrBlock":"0.0.0.0/0",
"RouteTableId":{"Ref":"RouteTable"},
"GatewayId":{"Ref":"InternetGateway"}
}
},
"Subnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": { "Ref": "VPC" },
"CidrBlock": "10.0.0.0/24",
"Tags": [ { "Key": "Application", "Value": { "Ref": "AWS::StackId" } } ]
}
},
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"VpcId": { "Ref": "VPC" },
"GroupDescription": "Enable SSH access via port 22",
"SecurityGroupIngress": [
{ "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": { "Ref": "SSHLocation" } },
{ "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" }
]
}
},
"MountTargetSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"VpcId": { "Ref": "VPC" },
"GroupDescription": "Security group for mount target",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 2049,
"ToPort": 2049,
"CidrIp": "0.0.0.0/0"
}
]
}
},
"FileSystem": {
"Type": "AWS::EFS::FileSystem",
"Properties": {
"PerformanceMode": "generalPurpose",
"FileSystemTags": [
{
"Key": "Name",
"Value": { "Ref" : "VolumeName" }
}
]
}
},
"MountTarget": {
"Type": "AWS::EFS::MountTarget",
"Properties": {
"FileSystemId": { "Ref": "FileSystem" },
"SubnetId": { "Ref": "Subnet" },
"SecurityGroups": [ { "Ref": "MountTargetSecurityGroup" } ]
}
},
"LaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"configSets" : {
"MountConfig" : [ "setup", "mount" ]
},
"setup" : {
"packages" : {
"yum" : {
"nfs-utils" : []
}
},
"files" : {
"/home/ec2-user/post_nfsstat" : {
"content" : { "Fn::Join" : [ "", [
"#!/bin/bash\n",
"\n",
"INPUT=\"$(cat)\"\n",
"CW_JSON_OPEN='{ \"Namespace\": \"EFS\", \"MetricData\": [ '\n",
"CW_JSON_CLOSE=' ] }'\n",
"CW_JSON_METRIC=''\n",
"METRIC_COUNTER=0\n",
"\n",
"for COL in 1 2 3 4 5 6; do\n",
"\n",
" COUNTER=0\n",
" METRIC_FIELD=$COL\n",
" DATA_FIELD=$(($COL+($COL-1)))\n",
"\n",
" while read line; do\n",
" if [[ COUNTER -gt 0 ]]; then\n",
"\n",
" LINE=`echo $line | tr -s ' ' `\n",
" AWS_COMMAND=\"aws cloudwatch put-metric-data --region ", { "Ref": "AWS::Region" }, "\"\n",
" MOD=$(( $COUNTER % 2))\n",
"\n",
" if [ $MOD -eq 1 ]; then\n",
" METRIC_NAME=`echo $LINE | cut -d ' ' -f $METRIC_FIELD`\n",
" else\n",
" METRIC_VALUE=`echo $LINE | cut -d ' ' -f $DATA_FIELD`\n",
" fi\n",
"\n",
" if [[ -n \"$METRIC_NAME\" && -n \"$METRIC_VALUE\" ]]; then\n",
" INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)\n",
" CW_JSON_METRIC=\"$CW_JSON_METRIC { \\\"MetricName\\\": \\\"$METRIC_NAME\\\", \\\"Dimensions\\\": [{\\\"Name\\\": \\\"InstanceId\\\", \\\"Value\\\": \\\"$INSTANCE_ID\\\"} ], \\\"Value\\\": $METRIC_VALUE },\"\n",
" unset METRIC_NAME\n",
" unset METRIC_VALUE\n",
"\n",
" METRIC_COUNTER=$((METRIC_COUNTER+1))\n",
" if [ $METRIC_COUNTER -eq 20 ]; then\n",
" # 20 is max metric collection size, so we have to submit here\n",
" aws cloudwatch put-metric-data --region ", { "Ref": "AWS::Region" }, " --cli-input-json \"`echo $CW_JSON_OPEN ${CW_JSON_METRIC%?} $CW_JSON_CLOSE`\"\n",
"\n",
" # reset\n",
" METRIC_COUNTER=0\n",
" CW_JSON_METRIC=''\n",
" fi\n",
" fi \n",
"\n",
"\n",
"\n",
" COUNTER=$((COUNTER+1))\n",
" fi\n",
"\n",
" if [[ \"$line\" == \"Client nfs v4:\" ]]; then\n",
" # the next line is the good stuff \n",
" COUNTER=$((COUNTER+1))\n",
" fi\n",
" done <<< \"$INPUT\"\n",
"done\n",
"\n",
"# submit whatever is left\n",
"aws cloudwatch put-metric-data --region ", { "Ref": "AWS::Region" }, " --cli-input-json \"`echo $CW_JSON_OPEN ${CW_JSON_METRIC%?} $CW_JSON_CLOSE`\""
] ] },
"mode": "000755",
"owner": "ec2-user",
"group": "ec2-user"
},
"/home/ec2-user/crontab" : {
"content" : { "Fn::Join" : [ "", [
"* * * * * /usr/sbin/nfsstat | /home/ec2-user/post_nfsstat\n"
] ] },
"owner": "ec2-user",
"group": "ec2-user"
}
},
"commands" : {
"01_createdir" : {
"command" : {"Fn::Join" : [ "", [ "mkdir /", { "Ref" : "MountPoint" }]]}
}
}
},
"mount" : {
"commands" : {
"01_mount" : {
"command" : { "Fn::Sub": "sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${FileSystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint}"}
},
"02_permissions" : {
"command" : {"Fn::Join" : [ "", [ "chown ec2-user:ec2-user /", { "Ref" : "MountPoint" }]]}
}
}
}
}
},
"Properties": {
"AssociatePublicIpAddress" : true,
"ImageId": {
"Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, {
"Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "InstanceType" }, "Arch" ]
} ]
},
"InstanceType": { "Ref": "InstanceType" },
"KeyName": { "Ref": "KeyName" },
"SecurityGroups": [ { "Ref": "InstanceSecurityGroup" } ],
"IamInstanceProfile" : { "Ref" : "CloudWatchPutMetricsInstanceProfile" },
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -xe\n",
"yum install -y aws-cfn-bootstrap\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource LaunchConfiguration ",
" --configsets MountConfig ",
" --region ", { "Ref" : "AWS::Region" }, "\n",
"crontab /home/ec2-user/crontab\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource AutoScalingGroup ",
" --region ", { "Ref" : "AWS::Region" }, "\n"
]]}}
}
},
"AutoScalingGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"DependsOn": ["MountTarget", "GatewayToInternet"],
"CreationPolicy" : {
"ResourceSignal" : {
"Timeout" : "PT15M",
"Count" : { "Ref": "AsgMaxSize" }
}
},
"Properties": {
"VPCZoneIdentifier": [ { "Ref": "Subnet" } ],
"LaunchConfigurationName": { "Ref": "LaunchConfiguration" },
"MinSize": "1",
"MaxSize": { "Ref": "AsgMaxSize" },
"DesiredCapacity": { "Ref": "AsgMaxSize" },
"Tags": [ {
"Key": "Name",
"Value": "EFS FileSystem Mounted Instance",
"PropagateAtLaunch": "true"
} ]
}
}
},
"Outputs" : {
"MountTargetID" : {
"Description" : "Mount target ID",
"Value" : { "Ref" : "MountTarget" }
},
"FileSystemID" : {
"Description" : "File system ID",
"Value" : { "Ref" : "FileSystem" }
}
}
}
YAML
AWSTemplateFormatVersion: '2010-09-09'
Description: This template creates an Amazon EFS file system and mount target and
associates it with Amazon EC2 instances in an Auto Scaling group. **WARNING** This
template creates Amazon EC2 instances and related resources. You will be billed
for the AWS resources used if you create a stack from this template.
Parameters:
InstanceType:
Description: WebServer EC2 instance type
Type: String
Default: t2.small
AllowedValues:
- t1.micro
- t2.nano
- t2.micro
- t2.small
- t2.medium
- t2.large
- m1.small
- m1.medium
- m1.large
- m1.xlarge
- m2.xlarge
- m2.2xlarge
- m2.4xlarge
- m3.medium
- m3.large
- m3.xlarge
- m3.2xlarge
- m4.large
- m4.xlarge
- m4.2xlarge
- m4.4xlarge
- m4.10xlarge
- c1.medium
- c1.xlarge
- c3.large
- c3.xlarge
- c3.2xlarge
- c3.4xlarge
- c3.8xlarge
- c4.large
- c4.xlarge
- c4.2xlarge
- c4.4xlarge
- c4.8xlarge
- g2.2xlarge
- g2.8xlarge
- r3.large
- r3.xlarge
- r3.2xlarge
- r3.4xlarge
- r3.8xlarge
- i2.xlarge
- i2.2xlarge
- i2.4xlarge
- i2.8xlarge
- d2.xlarge
- d2.2xlarge
- d2.4xlarge
- d2.8xlarge
- hi1.4xlarge
- hs1.8xlarge
- cr1.8xlarge
- cc2.8xlarge
- cg1.4xlarge
ConstraintDescription: must be a valid EC2 instance type.
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 key pair to enable SSH access to the ECS
instances
AsgMaxSize:
Type: Number
Description: Maximum size and initial desired capacity of Auto Scaling Group
Default: '2'
SSHLocation:
Description: The IP address range that can be used to connect to the EC2 instances
by using SSH
Type: String
MinLength: '9'
MaxLength: '18'
Default: 0.0.0.0/0
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
VolumeName:
Description: The name to be used for the EFS volume
Type: String
MinLength: '1'
Default: myEFSvolume
MountPoint:
Description: The Linux mount point for the EFS volume
Type: String
MinLength: '1'
Default: myEFSvolume
Mappings:
AWSInstanceType2Arch:
t1.micro:
Arch: HVM64
t2.nano:
Arch: HVM64
t2.micro:
Arch: HVM64
t2.small:
Arch: HVM64
t2.medium:
Arch: HVM64
t2.large:
Arch: HVM64
m1.small:
Arch: HVM64
m1.medium:
Arch: HVM64
m1.large:
Arch: HVM64
m1.xlarge:
Arch: HVM64
m2.xlarge:
Arch: HVM64
m2.2xlarge:
Arch: HVM64
m2.4xlarge:
Arch: HVM64
m3.medium:
Arch: HVM64
m3.large:
Arch: HVM64
m3.xlarge:
Arch: HVM64
m3.2xlarge:
Arch: HVM64
m4.large:
Arch: HVM64
m4.xlarge:
Arch: HVM64
m4.2xlarge:
Arch: HVM64
m4.4xlarge:
Arch: HVM64
m4.10xlarge:
Arch: HVM64
c1.medium:
Arch: HVM64
c1.xlarge:
Arch: HVM64
c3.large:
Arch: HVM64
c3.xlarge:
Arch: HVM64
c3.2xlarge:
Arch: HVM64
c3.4xlarge:
Arch: HVM64
c3.8xlarge:
Arch: HVM64
c4.large:
Arch: HVM64
c4.xlarge:
Arch: HVM64
c4.2xlarge:
Arch: HVM64
c4.4xlarge:
Arch: HVM64
c4.8xlarge:
Arch: HVM64
g2.2xlarge:
Arch: HVMG2
g2.8xlarge:
Arch: HVMG2
r3.large:
Arch: HVM64
r3.xlarge:
Arch: HVM64
r3.2xlarge:
Arch: HVM64
r3.4xlarge:
Arch: HVM64
r3.8xlarge:
Arch: HVM64
i2.xlarge:
Arch: HVM64
i2.2xlarge:
Arch: HVM64
i2.4xlarge:
Arch: HVM64
i2.8xlarge:
Arch: HVM64
d2.xlarge:
Arch: HVM64
d2.2xlarge:
Arch: HVM64
d2.4xlarge:
Arch: HVM64
d2.8xlarge:
Arch: HVM64
hi1.4xlarge:
Arch: HVM64
hs1.8xlarge:
Arch: HVM64
cr1.8xlarge:
Arch: HVM64
cc2.8xlarge:
Arch: HVM64
AWSRegionArch2AMI:
us-east-1:
HVM64: ami-0ff8a91507f77f867
HVMG2: ami-0a584ac55a7631c0c
us-west-2:
HVM64: ami-a0cfeed8
HVMG2: ami-0e09505bc235aa82d
us-west-1:
HVM64: ami-0bdb828fd58c52235
HVMG2: ami-066ee5fd4a9ef77f1
eu-west-1:
HVM64: ami-047bb4163c506cd98
HVMG2: ami-0a7c483d527806435
eu-west-2:
HVM64: ami-f976839e
HVMG2: NOT_SUPPORTED
eu-west-3:
HVM64: ami-0ebc281c20e89ba4b
HVMG2: NOT_SUPPORTED
eu-central-1:
HVM64: ami-0233214e13e500f77
HVMG2: ami-06223d46a6d0661c7
ap-northeast-1:
HVM64: ami-06cd52961ce9f0d85
HVMG2: ami-053cdd503598e4a9d
ap-northeast-2:
HVM64: ami-0a10b2721688ce9d2
HVMG2: NOT_SUPPORTED
ap-northeast-3:
HVM64: ami-0d98120a9fb693f07
HVMG2: NOT_SUPPORTED
ap-southeast-1:
HVM64: ami-08569b978cc4dfa10
HVMG2: ami-0be9df32ae9f92309
ap-southeast-2:
HVM64: ami-09b42976632b27e9b
HVMG2: ami-0a9ce9fecc3d1daf8
ap-south-1:
HVM64: ami-0912f71e06545ad88
HVMG2: ami-097b15e89dbdcfcf4
us-east-2:
HVM64: ami-0b59bfac6be064b78
HVMG2: NOT_SUPPORTED
ca-central-1:
HVM64: ami-0b18956f
HVMG2: NOT_SUPPORTED
sa-east-1:
HVM64: ami-07b14488da8ea02a0
HVMG2: NOT_SUPPORTED
cn-north-1:
HVM64: ami-0a4eaf6c4454eda75
HVMG2: NOT_SUPPORTED
cn-northwest-1:
HVM64: ami-6b6a7d09
HVMG2: NOT_SUPPORTED
Resources:
CloudWatchPutMetricsRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
CloudWatchPutMetricsRolePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: CloudWatch_PutMetricData
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: CloudWatchPutMetricData
Effect: Allow
Action:
- cloudwatch:PutMetricData
Resource:
- "*"
Roles:
- Ref: CloudWatchPutMetricsRole
CloudWatchPutMetricsInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- Ref: CloudWatchPutMetricsRole
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
CidrBlock: 10.0.0.0/16
Tags:
- Key: Application
Value:
Ref: AWS::StackId
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Application
Value:
Ref: AWS::StackName
- Key: Network
Value: Public
GatewayToInternet:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: VPC
InternetGatewayId:
Ref: InternetGateway
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: VPC
SubnetRouteTableAssoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTable
SubnetId:
Ref: Subnet
InternetGatewayRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 0.0.0.0/0
RouteTableId:
Ref: RouteTable
GatewayId:
Ref: InternetGateway
Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.0.0/24
Tags:
- Key: Application
Value:
Ref: AWS::StackId
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId:
Ref: VPC
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp:
Ref: SSHLocation
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
MountTargetSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId:
Ref: VPC
GroupDescription: Security group for mount target
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 2049
ToPort: 2049
CidrIp: 0.0.0.0/0
FileSystem:
Type: AWS::EFS::FileSystem
Properties:
PerformanceMode: generalPurpose
FileSystemTags:
- Key: Name
Value:
Ref: VolumeName
MountTarget:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId:
Ref: FileSystem
SubnetId:
Ref: Subnet
SecurityGroups:
- Ref: MountTargetSecurityGroup
LaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Metadata:
AWS::CloudFormation::Init:
configSets:
MountConfig:
- setup
- mount
setup:
packages:
yum:
nfs-utils: []
files:
"/home/ec2-user/post_nfsstat":
content: !Sub |
#!/bin/bash
INPUT="$(cat)"
CW_JSON_OPEN='{ "Namespace": "EFS", "MetricData": [ '
CW_JSON_CLOSE=' ] }'
CW_JSON_METRIC=''
METRIC_COUNTER=0
for COL in 1 2 3 4 5 6; do
COUNTER=0
METRIC_FIELD=$COL
DATA_FIELD=$(($COL+($COL-1)))
while read line; do
if [[ COUNTER -gt 0 ]]; then
LINE=`echo $line | tr -s ' ' `
AWS_COMMAND="aws cloudwatch put-metric-data --region ${AWS::Region}"
MOD=$(( $COUNTER % 2))
if [ $MOD -eq 1 ]; then
METRIC_NAME=`echo $LINE | cut -d ' ' -f $METRIC_FIELD`
else
METRIC_VALUE=`echo $LINE | cut -d ' ' -f $DATA_FIELD`
fi
if [[ -n "$METRIC_NAME" && -n "$METRIC_VALUE" ]]; then
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
CW_JSON_METRIC="$CW_JSON_METRIC { \"MetricName\": \"$METRIC_NAME\", \"Dimensions\": [{\"Name\": \"InstanceId\", \"Value\": \"$INSTANCE_ID\"} ], \"Value\": $METRIC_VALUE },"
unset METRIC_NAME
unset METRIC_VALUE
METRIC_COUNTER=$((METRIC_COUNTER+1))
if [ $METRIC_COUNTER -eq 20 ]; then
# 20 is max metric collection size, so we have to submit here
aws cloudwatch put-metric-data --region ${AWS::Region} --cli-input-json "`echo $CW_JSON_OPEN ${!CW_JSON_METRIC%?} $CW_JSON_CLOSE`"
# reset
METRIC_COUNTER=0
CW_JSON_METRIC=''
fi
fi
COUNTER=$((COUNTER+1))
fi
if [[ "$line" == "Client nfs v4:" ]]; then
# the next line is the good stuff
COUNTER=$((COUNTER+1))
fi
done <<< "$INPUT"
done
# submit whatever is left
aws cloudwatch put-metric-data --region ${AWS::Region} --cli-input-json "`echo $CW_JSON_OPEN ${!CW_JSON_METRIC%?} $CW_JSON_CLOSE`"
mode: '000755'
owner: ec2-user
group: ec2-user
"/home/ec2-user/crontab":
content: "* * * * * /usr/sbin/nfsstat | /home/ec2-user/post_nfsstat\n"
owner: ec2-user
group: ec2-user
commands:
01_createdir:
command: !Sub "mkdir /${MountPoint}"
mount:
commands:
01_mount:
command: !Sub >
mount -t nfs4 -o nfsvers=4.1 ${FileSystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint}
02_permissions:
command: !Sub "chown ec2-user:ec2-user /${MountPoint}"
Properties:
AssociatePublicIpAddress: true
ImageId:
Fn::FindInMap:
- AWSRegionArch2AMI
- Ref: AWS::Region
- Fn::FindInMap:
- AWSInstanceType2Arch
- Ref: InstanceType
- Arch
InstanceType:
Ref: InstanceType
KeyName:
Ref: KeyName
SecurityGroups:
- Ref: InstanceSecurityGroup
IamInstanceProfile:
Ref: CloudWatchPutMetricsInstanceProfile
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum install -y aws-cfn-bootstrap
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfiguration --configsets MountConfig --region ${AWS::Region}
crontab /home/ec2-user/crontab
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region}
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
DependsOn:
- MountTarget
- GatewayToInternet
CreationPolicy:
ResourceSignal:
Timeout: PT15M
Count:
Ref: AsgMaxSize
Properties:
VPCZoneIdentifier:
- Ref: Subnet
LaunchConfigurationName:
Ref: LaunchConfiguration
MinSize: '1'
MaxSize:
Ref: AsgMaxSize
DesiredCapacity:
Ref: AsgMaxSize
Tags:
- Key: Name
Value: EFS FileSystem Mounted Instance
PropagateAtLaunch: 'true'
Outputs:
MountTargetID:
Description: Mount target ID
Value:
Ref: MountTarget
FileSystemID:
Description: File system ID
Value:
Ref: FileSystem