Amazon Elastic File System 샘플 템플릿
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 User Guide(Amazon Elastic File System 사용 설명서)의 Mounting File Systems(EFS 파일 시스템 탑재)를 참조하세요.
네트워크 파일 시스템 활동을 측정하기 위해 템플릿에 사용자 지정 Amazon CloudWatch 지표가 포함되어 있습니다. 또한 템플릿은 VPC, 서브넷 및 보안 그룹을 생성합니다. 인스턴스가 파일 시스템과 통신하도록 허용하려면 VPC에서 DNS를 활성화하고 탑재 대상과 EC2 인스턴스가 동일한 가용 영역(AZ)에 있어야 합니다. 가용 영역은 서브넷에 의해 지정됩니다.
탑재 대상의 보안 그룹은 TCP 포트 2049에 대한 네트워크 연결을 활성화합니다. NFSv4 클라이언트가 파일 시스템을 탑재하려면 네트워크 연결이 필요합니다. EC2 인스턴스 및 탑재 대상의 보안 그룹에 대한 자세한 내용을 알아보려면 Amazon Elastic File System User Guide(Amazon Elastic File System 사용 설명서)의 Security(보안)를 참조하세요.
참고
탑재 대상을 업데이트하여 대체될 경우 연결된 파일 시스템을 사용하는 인스턴스 또는 애플리케이션이 중단될 수 있습니다. 그러면 작성한 커밋되지 않은 내용이 손실될 수 있습니다. 중단을 방지하려면 원하는 용량을 0으로 설정하여 탑재 대상을 업데이트할 때 인스턴스를 중지합니다. 그러면 탑재 대상이 삭제되기 이전에 인스턴스에서 파일 시스템의 탑재를 해제할 수 있습니다. 탑재 업데이트가 완료된 이후에 원하는 용량을 설정하여 후속 업데이트에서 인스턴스를 시작합니다.
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