efs_volume.yaml
---

EFS CloudFormation Deployment

This CloudFormation template will build an EFS volume and associated security groups and mount points.

AWSTemplateFormatVersion: '2010-09-09' Description: EFS Volume Stack

Metadata

Metadata is mostly for organizing and presenting Parameters in a better way when using CloudFormation in the AWS Web UI.

Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Application Information Parameters: - EnvAppName - AppSlug - Label: default: Network Settings Parameters: - VPCID - PrivSubnetA - PrivSubnetB - HostedZoneName - EncryptedVolume - Label: default: Tags Parameters: - TagService - TagName - TagEnvironment - TagCreatedBy - TagContactNetId - TagAccountNumber - TagSubAccount - TagTicketNumber - TagResourceFunction ParameterLabels: EnvAppName: default: 'Service Name:' AppSlug: default: 'Service Slug:' HostedZoneName: default: 'Route53 DNS Zone:' PrivSubnetA: default: 'Private Subnet A:' PrivSubnetB: default: 'Private Subnet B:' AppS3ResourceBucket: default: 'S3 Resource Bucket'

Parameters

These are the input parameters for this template. All of these parameters must be supplied for this template to be deployed.

Parameters: EnvAppName: MinLength: '3' Type: String Default: My App Description: Full Application name, ie 'UAccess Student' AppSlug: MinLength: '3' Type: String Default: app-nonprod Description: Short application slug, ie 'myapp-efs' or 'myapp-nonprod'. Lowercase letters, numbers and dashes only AllowedPattern: "[a-z0-9-]*" EncryptedVolume: Type: String Default: True Description: Enable at rest encryption on this EFS volume. AllowedValues: - True - False VPCID: Description: Target VPC Type: AWS::EC2::VPC::Id PrivSubnetA: Description: Private Subnet for Zone A Type: AWS::EC2::Subnet::Id PrivSubnetB: Description: Private Subnet for Zone B Type: AWS::EC2::Subnet::Id TagService: Description: Service name (from the service catalog) that is utilizing this resource Type: String TagName: Description: Descriptive identifier of resource. Type: String TagEnvironment: Description: Type of environment that is using this resource, such as 'dev', 'tst', 'prd'. Type: String TagCreatedBy: Description: NetID of the user that created this resource Type: String TagContactNetId: Description: NetID of the person to contact for information about this resource Type: String TagAccountNumber: Description: Financial system account number for the service utilizing this resource Type: String TagSubAccount: Description: Financial system subaccount number for the service utilizing this resource Type: String TagTicketNumber: Description: Ticket number that this resource is for Type: String TagResourceFunction: Description: Human-readable description of what function this resource is providing Type: String

Resources

These are all of the actual AWS resources created for this application.

Resources:

EFS Shared File System

Create an EFS entity to be used as a shared filesystem for the application instances.

FileSystem: Type: AWS::EFS::FileSystem Properties: Encrypted: !Ref EncryptedVolume FileSystemTags: - Key: Name Value: !Sub "${AppSlug}-efs" - Key: service Value: !Ref TagService - Key: environment Value: !Ref TagEnvironment - Key: createdby Value: !Ref TagCreatedBy - Key: contactnetid Value: !Ref TagContactNetId - Key: accountnumber Value: !Ref TagAccountNumber - Key: subaccount Value: !Ref TagSubAccount - Key: ticketnumber Value: !Ref TagTicketNumber - Key: resourcefunction Value: !Ref TagResourceFunction - Key: pillar Value: !Sub "${AppSlug}-efs"

EFS Mount Points

EFS Mountpoints must be created for each Availability Zone in the VPC. This is also where you define access controls, as access to EFS is controlled by these security groups.

A pair of mount points must be created for each EFS volume.

EFSMountTargetZoneA: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref FileSystem SubnetId: !Ref PrivSubnetA SecurityGroups: - Ref: EFSSecurityGroup EFSMountTargetZoneB: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref FileSystem SubnetId: !Ref PrivSubnetB SecurityGroups: - Ref: EFSSecurityGroup

EFS Security Group

This security group defines what resources are able to access the EFS shared filesystem.

EFSSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow EFS Ports to EFS Volume VpcId: !Ref VPCID SecurityGroupIngress: - IpProtocol: tcp FromPort: '2049' ToPort: '2049' SourceSecurityGroupId: Ref: EFSTargetSecurityGroup Tags: - Key: Name Value: !Sub "${AppSlug}-efs-sg" - Key: service Value: !Ref TagService - Key: environment Value: !Ref TagEnvironment - Key: createdby Value: !Ref TagCreatedBy - Key: contactnetid Value: !Ref TagContactNetId - Key: accountnumber Value: !Ref TagAccountNumber - Key: subaccount Value: !Ref TagSubAccount - Key: ticketnumber Value: !Ref TagTicketNumber - Key: resourcefunction Value: !Ref TagResourceFunction

EFS Target Security Group

Create a security group which will be allowed in to the EFS Volume. This security group can be referenced by environments as they're deployed so that additional environments can be allowed access to the EFS Volumes.

EFSTargetSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Instances in this group will be allowed into the EFS Volume VpcId: Ref: VPCID

These SGs don't actually specify any rules, they exist only to allow access to the EFS security group

SecurityGroupIngress: [] Tags: - Key: Name Value: !Sub "${AppSlug}-target-efs-sg" - Key: service Value: !Ref TagService - Key: environment Value: !Ref TagEnvironment - Key: createdby Value: !Ref TagCreatedBy - Key: contactnetid Value: !Ref TagContactNetId - Key: accountnumber Value: !Ref TagAccountNumber - Key: subaccount Value: !Ref TagSubAccount - Key: ticketnumber Value: !Ref TagTicketNumber - Key: resourcefunction Value: !Ref TagResourceFunction

Outputs

Output values that can be viewed from the AWS CloudFormation console.

Outputs: FileSystem: Value: !Ref FileSystem Export: Name: !Sub "${AWS::StackName}-fs-id" EFSSecurityGroup: Value: !Ref EFSSecurityGroup Export: Name: !Sub "${AWS::StackName}-sg" EFSTargetSecurityGroup: Value: !Ref EFSTargetSecurityGroup Export: Name: !Sub "${AWS::StackName}-target-sg"