AWSTemplateFormatVersion: '2010-09-09' Description: AWS Transfer and File Gateway Workshop Metadata: License: Description: | Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network Parameters: - cidrBlock - Label: default: AMI IDs (do not edit) Parameters: - linuxAmi - fgwAmi ParameterLabels: cidrBlock: default: 'VPC CIDR Block' linuxAmi: default: 'Linux' fgwAmi: default: 'File Gateway' Parameters: cidrBlock: Type : 'String' Default: '10.11.12.0/24' linuxAmi: Type : 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' fgwAmi: Type : 'AWS::SSM::Parameter::Value' Default: '/aws/service/storagegateway/ami/FILE_S3/latest' Resources: # Create a dedicated VPC with one public subnet and internet connectivity dmVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref cidrBlock EnableDnsSupport: 'true' EnableDnsHostnames: 'true' InstanceTenancy: default Tags: - Key: Name Value: WorkshopVPC dmSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref 'dmVPC' CidrBlock: !Ref cidrBlock MapPublicIpOnLaunch: 'True' Tags: - Key: Name Value: WorkshopSubnet1 dmInternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: WorkshopIGW dmAttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref 'dmVPC' InternetGatewayId: !Ref 'dmInternetGateway' dmRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref 'dmVPC' Tags: - Key: Name Value: WorkshopRouteTable dmSubnet1RouteAssociaton: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref 'dmSubnet1' RouteTableId: !Ref 'dmRouteTable' dmRoutetoInternet: Type: AWS::EC2::Route DependsOn: dmInternetGateway Properties: RouteTableId: !Ref 'dmRouteTable' DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref 'dmInternetGateway' # We use the same security group for all four resources. Technically port 80 # isn't needed for the NFS server, but nothing is listening on those ports on those servers. dmSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Workshop - Security Group for all resources VpcId: !Ref 'dmVPC' SecurityGroupIngress: - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: '0.0.0.0/0' - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: '0.0.0.0/0' # We use this so we can limit access on this port to the SG dmSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress DependsOn: dmSecurityGroup Properties: GroupId: !Ref 'dmSecurityGroup' IpProtocol: tcp ToPort: '2049' FromPort: '2049' SourceSecurityGroupId: !Ref 'dmSecurityGroup' transferServer: Type: AWS::Transfer::Server Properties: EndpointDetails: SubnetIds: - !Ref 'dmSubnet1' VpcId: !Ref dmVPC EndpointType: VPC IdentityProviderType: SERVICE_MANAGED Protocols: - SFTP linuxServerInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref 'linuxServerIamRole' linuxServerIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - ec2.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore # linuxServerRolePolicy: # Type: AWS::IAM::Policy # Properties: # PolicyDocument: # Statement: # - Effect: Allow # Action: # - s3:ListBucket # Resource: # - arn:aws:s3:::aft-vbi-pds # - Effect: Allow # Action: # - s3:GetObject # Resource: # - arn:aws:s3:::aft-vbi-pds/* # Version: '2012-10-17' # PolicyName: policy # Roles: # - !Ref 'linuxServerIamRole' linuxServer: Type: AWS::EC2::Instance Properties: ImageId: !Ref linuxAmi InstanceType: t2.micro IamInstanceProfile: !Ref 'linuxServerInstanceProfile' Tags: - Key: Name Value: Workshop-LinuxServer InstanceInitiatedShutdownBehavior: terminate BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: '8' DeleteOnTermination: 'true' VolumeType: gp2 NetworkInterfaces: - AssociatePublicIpAddress: 'true' DeviceIndex: '0' GroupSet: - !Ref 'dmSecurityGroup' SubnetId: !Ref 'dmSubnet1' fileGatewayInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref 'fileGatewayIamRole' fileGatewayIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - ec2.amazonaws.com Version: '2012-10-17' fileGatewayRolePolicy: Type: AWS::IAM::Policy Properties: PolicyDocument: Statement: - Effect: Allow Action: - storagegateway:* Resource: - '*' - Effect: Allow Action: - iam:PassRole Resource: - '*' Version: '2012-10-17' PolicyName: policy Roles: - !Ref 'fileGatewayIamRole' fileGateway: Type: AWS::EC2::Instance Properties: ImageId: !Ref fgwAmi InstanceType: c4.2xlarge IamInstanceProfile: !Ref 'fileGatewayInstanceProfile' Tags: - Key: Name Value: Workshop-FileGateway InstanceInitiatedShutdownBehavior: stop BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: '80' DeleteOnTermination: 'true' VolumeType: gp2 - DeviceName: /dev/xvdc Ebs: VolumeSize: '300' DeleteOnTermination: 'true' VolumeType: gp2 NetworkInterfaces: - AssociatePublicIpAddress: 'true' DeviceIndex: '0' GroupSet: - !Ref 'dmSecurityGroup' SubnetId: !Ref 'dmSubnet1' # We use the GUID from the ARN of the stack ID to generate # a unique bucket name s3Bucket: Type: AWS::S3::Bucket Properties: PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True BucketName: !Join - "-" - - "workshop" - !Select - 2 - !Split - "/" - !Ref "AWS::StackId" # Both Transfer and Storage Gateway need a role to access the bucket. We'll keep things simple # and create one role for both, with full access to S3. s3BucketIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - storagegateway.amazonaws.com - transfer.amazonaws.com Version: '2012-10-17' s3BucketRolePolicy: Type: AWS::IAM::Policy DependsOn: s3Bucket Properties: PolicyDocument: Statement: - Effect: Allow Resource: - !GetAtt s3Bucket.Arn - !Join [ "/", [ !GetAtt s3Bucket.Arn, "*" ] ] Action: - s3:* Version: '2012-10-17' PolicyName: policy Roles: - !Ref 's3BucketIamRole' Outputs: bucketName: Description: S3 Bucket Name Value: !Ref s3Bucket iamRoleForS3Access: Description: S3 IAM Role for Transfer and File Gateway Value: !GetAtt s3BucketIamRole.Arn linuxServerPrivateIP: Description: Linux Server Private IP Address Value: !GetAtt linuxServer.PrivateIp fileGatewayPublicIP: Description: File Gateway Public IP Address Value: !GetAtt fileGateway.PublicIp transferServerId: Description: AWS Transfer Server ID Value: !GetAtt transferServer.ServerId