sunapsis_5_sftp.yaml
---

CloudFormation template for Sunapsis SFTP (5 of 5)

  • Deploys a containerized SFTP server via ECS
  • Mounts the Sunapsis file share via NFS (from template 3)
AWSTemplateFormatVersion: 2010-09-09 Description: Sunapsis (SFTP)

Parameters

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

Parameters: EnvironmentType: Description: Environment type of this resource (dev, tst, rpt, trn, prd) Type: String Default: prd AllowedValues: - dev - tst - rpt - trn - prd EcsInstanceType: Description: Instance type to use for ECS EC2 instance(s) Type: String Default: t2.micro AmiId:
Description: ECS optimized AMI ID Type: String Default: ami-40ddb938 # This is 2017.09-l DockerImage:
  • ua-uits-general-nonprod: 722748364533.dkr.ecr.us-west-2.amazonaws.com/eas/sftphub:2017-11-15
  • sls-prod: 918461542486.dkr.ecr.us-west-2.amazonaws.com/eas/sftphub:20180517
Description: Docker image to use for container Type: String Default: 918461542486.dkr.ecr.us-west-2.amazonaws.com/eas/sftphub:20180517 ### Tags TagService: Description: Name of the service associated with this resource (as listed in the service catalog) Type: String Default: Sunapsis TagContactNetID: Description: NetID of the primary technical resource Type: String Default: dbaty TagTicketNumber: Description: Ticket number for the CLOUD Jira project Type: String Default: CLOUD-85 TagAccountNumber: Description: Account number associated with the service Type: String Default: 2433643 TagSubAccount: Description: Sub account associated with the service Type: String Default: Sunapsis

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: Environment Parameters: - EnvironmentType - Label: default: Settings Parameters: - EcsInstanceType - AmiId - DockerImage - Label: default: Tags Parameters: - TagService - TagContactNetID - TagTicketNumber - TagAccountNumber - TagSubAccount ParameterLabels: {}

Conditions

Establishes conditions based on input parameters.

Conditions: IsNotPRD: !Not [!Equals [!Ref EnvironmentType, prd ]]

Resources

Resources:

EC2 Security Groups

EC2 Security Group for the ECS EC2 instance(s)

EcsInstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: !Sub EC2 Security Group for Sunapsis SFTP Hub ECS EC2 instances (${EnvironmentType}) VpcId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-vpc SecurityGroupIngress: - IpProtocol: tcp FromPort: 2022 ToPort: 2022 CidrIp: 128.196.0.0/16 Description: Tucson campus (restricting at EC2-level as NLB does not support security groups) - IpProtocol: tcp FromPort: 2022 ToPort: 2022 CidrIp: 150.135.0.0/16 Description: Tucson campus (restricting at EC2-level as NLB does not support security groups) - IpProtocol: tcp FromPort: 2022 ToPort: 2022 CidrIp: 172.16.0.0/12 Description: Tucson campus (restricting at EC2-level as NLB does not support security groups) - IpProtocol: tcp FromPort: 2022 ToPort: 2022 CidrIp: 10.128.0.0/9 Description: Tucson campus (restricting at EC2-level as NLB does not support security groups) - IpProtocol: tcp FromPort: 2022 ToPort: 2022 CidrIp: 10.64.0.0/10 Description: Tucson campus (restricting at EC2-level as NLB does not support security groups) - IpProtocol: tcp FromPort: 2022 ToPort: 2022 CidrIp: 192.80.43.0/24 Description: Tucson campus (restricting at EC2-level as NLB does not support security groups) - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 150.135.112.64/27 Description: InfraDev VPN - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 150.135.112.96/27 Description: EntApp VPN Tags: - Key: Name Value: !Sub "sunapsis-${EnvironmentType}-sg-sftp-ec2" - Key: service Value: !Ref TagService - Key: environment Value: !Ref EnvironmentType - Key: contactnetid Value: !Ref TagContactNetID - Key: accountnumber Value: !Ref TagAccountNumber - Key: ticketnumber Value: !Ref TagTicketNumber - Key: subaccount Value: !Ref TagSubAccount

EC2 Security Group Ingress to update the existing Security Group for SoftNAS to allow NFS access from the SFTP instance(s)

SecurityGroupIngressToSoftNasForNfsTcp: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-SoftNasSecurityGroupId IpProtocol: tcp FromPort: 2049 ToPort: 2049 SourceSecurityGroupId: !Ref EcsInstanceSecurityGroup Description: Allow NFS TCP from SFTP to SoftNAS SecurityGroupIngressToSoftNasForNfsUdp: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-SoftNasSecurityGroupId IpProtocol: udp FromPort: 2049 ToPort: 2049 SourceSecurityGroupId: !Ref EcsInstanceSecurityGroup Description: Allow NFS UDP from SFTP to SoftNAS SecurityGroupIngressToSoftNasForPortmapperTcp: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-SoftNasSecurityGroupId IpProtocol: tcp FromPort: 111 ToPort: 111 SourceSecurityGroupId: !Ref EcsInstanceSecurityGroup Description: Allow Portmapper TCP from SFTP to SoftNAS SecurityGroupIngressToSoftNasForPortmapperUdp: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-SoftNasSecurityGroupId IpProtocol: udp FromPort: 111 ToPort: 111 SourceSecurityGroupId: !Ref EcsInstanceSecurityGroup Description: Allow Portmapper UDP from SFTP to SoftNAS SecurityGroupIngressToSoftNasForDynamicPortsTcp: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-SoftNasSecurityGroupId IpProtocol: tcp FromPort: 32768 ToPort: 65535 SourceSecurityGroupId: !Ref EcsInstanceSecurityGroup Description: Allow dynamic TCP ports from SFTP to SoftNAS SecurityGroupIngressToSoftNasForDynamicPortsUdp: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-SoftNasSecurityGroupId IpProtocol: udp FromPort: 32768 ToPort: 65535 SourceSecurityGroupId: !Ref EcsInstanceSecurityGroup Description: Allow dynamic UDP ports from SFTP to SoftNAS

Elastic Load Balancers (ELB) v2

 - Includes ELB, target group & listeners

ELB itself

SftpLoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: !Sub sunapsis-${EnvironmentType}-sftp-elb Type: network Scheme: internet-facing Subnets: - Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-public-subnet-a - Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-public-subnet-b Tags: - Key: Name Value: !Sub sunapsis-${EnvironmentType}-sftp-elb - Key: service Value: !Ref TagService - Key: environment Value: !Ref EnvironmentType - Key: contactnetid Value: !Ref TagContactNetID - Key: accountnumber Value: !Ref TagAccountNumber - Key: ticketnumber Value: !Ref TagTicketNumber - Key: subaccount Value: !Ref TagSubAccount

ELB Target Group

ElbTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Sub sunapsis-${EnvironmentType}-sftp-tg HealthCheckIntervalSeconds: 30 HealthCheckProtocol: TCP HealthCheckPort: 2022 HealthCheckTimeoutSeconds: 10 HealthyThresholdCount: 2 UnhealthyThresholdCount: 2 Port: 2022 Protocol: TCP TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: 60 VpcId: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-vpc Tags: - Key: Name Value: !Sub sunapsis-${EnvironmentType}-sftp-tg - Key: environment Value: !Ref EnvironmentType - Key: contactnetid Value: !Ref TagContactNetID - Key: ticketnumber Value: !Ref TagTicketNumber - Key: accountnumber Value: !Ref TagAccountNumber - Key: service Value: !Ref TagService - Key: subaccount Value: !Ref TagSubAccount

ELB Listeners

ElbListenerSFTP: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref ElbTargetGroup LoadBalancerArn: !Ref SftpLoadBalancer Port: 22 Protocol: TCP

Auto Scaling Groups

 - includes ASG, Launch Configuration & Scheduled Actions

Launch Configuration

EcsLaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: ImageId: !Ref AmiId InstanceType: !Ref EcsInstanceType AssociatePublicIpAddress: false IamInstanceProfile: !Ref IAMProfileEcsEc2 KeyName: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-ec2-keypair SecurityGroups: - !Ref EcsInstanceSecurityGroup BlockDeviceMappings: - DeviceName: /dev/xvdcz Ebs: VolumeSize: 22 VolumeType: gp2 UserData: Fn::Base64: !Sub | #!/bin/bash echo ECS_CLUSTER=sunapsis-${EnvironmentType}-sftp >> /etc/ecs/ecs.config

Auto Scaling Group

EcsInstanceAsg: Type: AWS::AutoScaling::AutoScalingGroup DependsOn: EcsCluster Properties: VPCZoneIdentifier: - Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-private-subnet-a - Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-private-subnet-b LaunchConfigurationName: !Ref EcsLaunchConfig MinSize: 1 MaxSize: 1 DesiredCapacity: 1 TargetGroupARNs: - !Ref ElbTargetGroup NotificationConfigurations: - TopicARN: !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:sunapsis-${EnvironmentType} NotificationTypes: - autoscaling:EC2_INSTANCE_LAUNCH - autoscaling:EC2_INSTANCE_LAUNCH_ERROR - autoscaling:EC2_INSTANCE_TERMINATE - autoscaling:EC2_INSTANCE_TERMINATE_ERROR Tags: - Key: Name Value: !Sub sunapsis-${EnvironmentType}-sftp PropagateAtLaunch: true - Key: environment Value: !Ref EnvironmentType PropagateAtLaunch: true - Key: contactnetid Value: !Ref TagContactNetID PropagateAtLaunch: true - Key: ticketnumber Value: !Ref TagTicketNumber PropagateAtLaunch: true - Key: accountnumber Value: !Ref TagAccountNumber PropagateAtLaunch: true - Key: service Value: !Ref TagService PropagateAtLaunch: true - Key: subaccount Value: !Ref TagSubAccount PropagateAtLaunch: true

Scheduled Actions

ScheduledActionUp: Type: "AWS::AutoScaling::ScheduledAction" Condition: IsNotPRD Properties: AutoScalingGroupName: !Ref EcsInstanceAsg MaxSize: 1 MinSize: 1 Recurrence: "30 14 * * MON-FRI" # M-F, 2:30pm UTC (7:30am AZ) ScheduledActionDown: Type: "AWS::AutoScaling::ScheduledAction" Condition: IsNotPRD Properties: AutoScalingGroupName: !Ref EcsInstanceAsg MaxSize: 0 MinSize: 0 Recurrence: "30 1 * * SUN-THU" # M-F, 1:30am UTC (6:30pm AZ) - needs run "SUN-THU" as the UTC-7 crosses the midnight threshold

EC2 Container Service (ECS)

 - includes cluster, task definition & service

ECS Cluster

EcsCluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Sub sunapsis-${EnvironmentType}-sftp

ECS Task Definition

EcsTask: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub sunapsis-${EnvironmentType}-sftp NetworkMode: bridge ContainerDefinitions: - Name: !Sub sunapsis-${EnvironmentType}-sftp Essential: true Image: !Ref DockerImage PortMappings: - HostPort: 2022 ContainerPort: 22 Protocol: tcp Hostname: !Sub sunapsis-${EnvironmentType}-sftp Cpu: 200 MemoryReservation: 512 Privileged: true Environment: - Name: SFTP_ENV Value: SUNAPSIS - Name: SFTP_MOUNTS Value: !Sub - sunapsis-${EnvironmentType}-files.${HostedZoneName}:/=/mnt/sunapsis - HostedZoneName: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-hostedzone-name LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref EcsLogGroup awslogs-region: !Sub ${AWS::Region} awslogs-stream-prefix: !Sub ${EnvironmentType}-sftp

ECS Service

EcsService: Type: AWS::ECS::Service #Waiting for the DNS record to be created beause we know the LB has been #created if the DNS record is created, and the LB needs to be created #before the ECS service is created DependsOn: [ EcsInstanceAsg, Route53RecordSet ] Properties: ServiceName: !Sub sunapsis-${EnvironmentType}-sftp Cluster: !Ref EcsCluster TaskDefinition: !Ref EcsTask DesiredCount: 1 Role: !Ref IAMRoleForEcsService LoadBalancers: - ContainerName: !Sub sunapsis-${EnvironmentType}-sftp ContainerPort: 22 TargetGroupArn: !Ref ElbTargetGroup PlacementStrategies: - Field: attribute:ecs.availability-zone Type: spread DeploymentConfiguration: MaximumPercent: 200

Route53

Route53 Record Set Group

Route53RecordSet: Type: AWS::Route53::RecordSet Properties: HostedZoneName: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-hostedzone-name Comment: !Sub Sunapsis (${EnvironmentType}) - SFTP ELB alias Name: Fn::ImportValue: !Sub sunapsis-${EnvironmentType}-fqdn-for-sftp Type: A AliasTarget: HostedZoneId: !GetAtt SftpLoadBalancer.CanonicalHostedZoneID DNSName: !GetAtt SftpLoadBalancer.DNSName

CloudWatch Logs

 - Includes Log Group

CloudWatch Log Group

EcsLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub sunapsis-${EnvironmentType}-sftp RetentionInDays: 30

IAM

IAM Roles

IAMRoleForEcsEc2: Type: AWS::IAM::Role Properties: RoleName: !Sub sunapsis-${EnvironmentType}-role-ecs-ec2 AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role IAMRoleForEcsService: Type: AWS::IAM::Role Properties: RoleName: !Sub sunapsis-${EnvironmentType}-role-ecs-service AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ecs.amazonaws.com Action: - sts:AssumeRole Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole

IAM Instance Profiles

IAMProfileEcsEc2: Type: AWS::IAM::InstanceProfile Properties: Path: "/" Roles: - !Ref IAMRoleForEcsEc2