toolshed-base.yaml
---

Toolshed Base CloudFormation Deployment

This CloudFormation template will deploy the AWS resources needed by the toolshed service:

  • EFS Volume
  • Application Load Balancer
AWSTemplateFormatVersion: "2010-09-09" Description: "Toolshed Base"

Parameters

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

Parameters:

The name of this caching service.

VPCID is the ID of the VPC where this template will be deployed.

VPCID: Description: Target VPC Type: AWS::EC2::VPC::Id PrivSubnetA: Type: AWS::EC2::Subnet::Id Description: The first private subnets for the application PrivSubnetB: Type: AWS::EC2::Subnet::Id Description: The second private subnets for the application Route53StackName: Type: String Description: CloudFormation Stack name of the route53 deployment in this account Default: "uits-nonprod-aws-route53"

Tags

The following tags are applied to all resources created by this template.

ServiceTag: Type: String Description: Exact name of the Service as defined in the service catalog. EnvironmentTag: Type: String Description: Used to distinguish between development, test, production,etc. environment types. AllowedValues: [dev, tst, prd, trn, stg, cfg, sup, rpt] Default: dev ContactNetidTag: Type: String Description: Used to identify the netid of the person most familiar with the usage of the resource. AccountNumberTag: Type: String Description: Identifies the financial system account number. TicketNumberTag: Type: String Description: Used to identify the Jira, Cherwell, or other ticketing system ticket number to link to more information about the need for the resource.

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: Network Settings Parameters: - VPCID - PrivSubnetA - PrivSubnetB - Route53StackName - Label: default: Tags Parameters: - ServiceTag - EnvironmentTag - ContactNetidTag - AccountNumberTag - TicketNumberTag ParameterLabels: ServiceTag: default: "Service Name:" EnvironmentTag: default: 'Environment Type:' ContactNetidTag: default: 'Contact NetID:' AccountNumberTag: default: 'Financial Account Number:' TicketNumberTag: default: 'Ticket Number:'

Resources

This is the EC2 instance deployed by the template.

Resources:

Instance Security Group

Security group for the EC2 instance. (Deployed in hosts stack)

InstanceSecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: GroupDescription: "Allow ssh to client host" VpcId: !Ref VPCID SecurityGroupIngress: - IpProtocol: "tcp" FromPort: "22" ToPort: "22" CidrIp: "150.135.112.0/22" Description: "Infradev VPN" - IpProtocol: "tcp" FromPort: "22" ToPort: "22" CidrIp: "10.138.0.0/17" Description: "Mosaic VPN" - IpProtocol: "tcp" FromPort: "22" ToPort: "22" CidrIp: "128.196.130.211/32" Description: "ben.uits bastion host" - IpProtocol: "tcp" FromPort: "22" ToPort: "22" CidrIp: "128.196.135.64/26" Description: "337 wired" - IpProtocol: "tcp" FromPort: "80" ToPort: "80" SourceSecurityGroupId: !Ref AlbSecurityGroup Description: "Incoming Traffic from Load Balancer" Tags: - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

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: FileSystemTags: - Key: Name Value: toolshed-efs - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

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: - Description: "Incoming NFS Traffic from Target Security Group" IpProtocol: tcp FromPort: '2049' ToPort: '2049' SourceSecurityGroupId: Ref: EFSTargetSecurityGroup Tags: - Key: Name Value: toolshed-efs-securitygroup - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

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: toolshed-efs-target-sg - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

ALB Security Group

Create the Security Group for the ALB here in the base template so it can be referenced here. Exported for use in the host template.

AlbSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: 'Allow external traffic to load balancer' VpcId: !Ref VPCID SecurityGroupIngress: - CidrIp: 0.0.0.0/0 IpProtocol: "tcp" FromPort: "80" ToPort: "80" - CidrIp: 0.0.0.0/0 IpProtocol: "tcp" FromPort: "443" ToPort: "443" Tags: - Key: "Name" Value: !Sub "${AWS::StackName}-alb-sg" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

CloudWatch Logs Group

Create a CloudWatch Log Group for the Toolshed. This allows us to set the retention timeframe.

LogGroup: Type: "AWS::Logs::LogGroup" Properties: LogGroupName: "toolshed" RetentionInDays: 14

Outputs

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

Outputs: VPCID: Description: Target VPC Value: !Ref VPCID Export: Name: !Sub "${AWS::StackName}-vpcid" PrivSubnetA: Description: The first private subnet for the application Value: !Ref PrivSubnetA Export: Name: !Sub "${AWS::StackName}-privsubnet-a" PrivSubnetB: Description: The second private subnet for the application Value: !Ref PrivSubnetB Export: Name: !Sub "${AWS::StackName}-privsubnet-b" InstanceSecurityGroup: Description: EC2 Instance Security Group Value: !Ref InstanceSecurityGroup Export: Name: !Sub "${AWS::StackName}-ec2-sg" FileSystem: Value: !Ref FileSystem Export: Name: !Sub "${AWS::StackName}-efs-id" EFSSecurityGroup: Value: !Ref EFSSecurityGroup Export: Name: !Sub "${AWS::StackName}-efs-sg" EFSTargetSecurityGroup: Value: !Ref EFSTargetSecurityGroup Export: Name: !Sub "${AWS::StackName}-efs-target-sg" AlbSecurityGroup: Description: The ALB Security Group Value: !Ref AlbSecurityGroup Export: Name: !Sub "${AWS::StackName}-alb-sg" Route53DNS: Description: The DNS base name for this AWS account Value: Fn::ImportValue: !Sub "${Route53StackName}-dns" Export: Name: !Sub "${AWS::StackName}-dns" HostedZoneId: Description: The Zone ID for this account's Route53 Zone. Value: Fn::ImportValue: !Sub "${Route53StackName}-zone-id" Export: Name: !Sub "${AWS::StackName}-zone-id"