Skip to content

Instantly share code, notes, and snippets.

@glnds
Last active February 23, 2024 09:53
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save glnds/dac9fb18c3cad10ba42a203526b8caf2 to your computer and use it in GitHub Desktop.
Save glnds/dac9fb18c3cad10ba42a203526b8caf2 to your computer and use it in GitHub Desktop.
CloudFormation template for AWS Transfer for SFTP
---
AWSTemplateFormatVersion: '2010-09-09'
Description: some-sftp-server
Parameters:
HostedZoneIdParam:
Type: String
Description: Hosted Zone ID
SFTPHostnameParam:
Type: String
Description: Hostname for the SFTP Server
Resources:
SFTPServer:
Type: AWS::Transfer::Server
Properties:
EndpointType: PUBLIC
Tags:
- Key: Application
Value: some-sftp-servver
SFTPServerDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
Name: !Ref SFTPHostnameParam
HostedZoneId: !Ref HostedZoneIdParam
Type: CNAME
Comment: SFTP Transfer custom hostname
TTL: 300
ResourceRecords:
- !Sub ${SFTPServer.ServerId}.server.transfer.${AWS::Region}.amazonaws.com
SFTPServerS3Bucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
BucketName: some-sftp-bucket
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Tags:
- Key: Application
Value: some-sftp-servver
SFTPUserRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- transfer.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: S3FullAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:ListAllMyBuckets
- s3:GetBucketLocation
Resource: "*"
- PolicyName: AllowListingOfUserFolder
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:ListBucket
Resource: !GetAtt SFTPServerS3Bucket.Arn
- PolicyName: HomeDirObjectAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:DeleteObject
- s3:DeleteObjectVersion
Resource: !Sub "${SFTPServerS3Bucket.Arn}/*"
TestUser:
Type: AWS::Transfer::User
Properties:
ServerId: !GetAtt SFTPServer.ServerId
UserName: john
HomeDirectory: !Sub "/${SFTPServerS3Bucket}/home/john"
Policy: >
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListingOfUserFolder",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::${transfer:HomeBucket}",
"Condition": {
"StringLike": {
"s3:prefix": [
"home/${transfer:UserName}/*",
"home/${transfer:UserName}"
]
}
}
},
{
"Sid": "HomeDirObjectAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:DeleteObject",
"s3:DeleteObjectVersion"
],
"Resource": "arn:aws:s3:::${transfer:HomeDirectory}*"
}
]
}
Role: !GetAtt SFTPUserRole.Arn
SshPublicKeys:
- ssh-rsa AAAAB3NzaC1********************************cMNTZKrQTDjrpvCJ83w== john.doe@gmail.com
Tags:
- Key: Application
Value: some-sftp-server
@mirwasim
Copy link

mirwasim commented Feb 4, 2021

I am not able to see how to add the custom hostname to it . is it something that is not supported by AWS CFN yet

@glnds
Copy link
Author

glnds commented Mar 11, 2021

SFTPServerDNSRecord:
    Type: AWS::Route53::RecordSet
    Properties:
      Name: !Ref SFTPHostnameParam
      HostedZoneId: !Ref HostedZoneIdParam
      Type: CNAME
      Comment: SFTP Transfer custom hostname
      TTL: 300
      ResourceRecords:
        - !Sub ${SFTPServer.ServerId}.server.transfer.${AWS::Region}.amazonaws.com

@mirwasim This will set a 'custom hostname' by using a CNAME record

@mirwasim
Copy link

Thanks @glnds, but what I meant was to update custom hostname in SFTP server. when you create from console you have an option to add a custom hostname but in template there is nothing of that sort and we do not have it in AWS documentation either.

screenshot

@malammar
Copy link

malammar commented Oct 7, 2021

You can use tags to do this:

Resources:
  Server:
    Type: AWS::Transfer::Server
    Properties:
      EndpointType: PUBLIC
      Tags:
        - Key: Name
          Value: your-server-name-here
        - Key: aws:transfer:customHostname
          Value: sftp.YourHost.com

See https://docs.aws.amazon.com/transfer/latest/userguide/requirements-dns.html#tag-custom-hostname-cdk

@PeixerGabriel
Copy link

How can I inject ssh-key values via AWS SecretManager in this type of configuration?

@Pabl0Aceved0
Copy link

same question

"How can I inject ssh-key values via AWS SecretManager in this type of configuration?"

@NageshwarJaiswal
Copy link

do you have cloud formation for FTPS server?

@mikemountjoy99
Copy link

same question

"How can I inject ssh-key values via AWS SecretManager in this type of configuration?"

If your AWS Secret were a username/password combo and you wanted to access the password in Cloudformation then you could do something like this:

  MySecretKey:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Statement:
          - Sid: "Enable IAM User Permissions"
            Effect: "Allow"
            Principal:
              AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
            Action: "kms:*"
            Resource: "*"

  MySecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub "MySecret"
      Description: !Sub "MySecret"
      KmsKeyId: !Ref MySecretKey
      GenerateSecretString:
        SecretStringTemplate: !Sub '{"username":"admin"}'
        GenerateStringKey: "password"
        PasswordLength: 16
        ExcludePunctuation: True

You can resolve the password for use elsewhere in your template using the following syntax:

!Sub "{{resolve:secretsmanager:${MySecret}::password}}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment