TransferFamilyを使ってS3にFTPS接続してみる

目次
はじめに
こんにちは。shumpeiです。
AWS Transfer Familyは、AWSが提供するフルマネージドなファイル転送サービスです。
Transfer Familyでは FTP, FTPS, SFPT 等のプロトコルを使用して、S3, EFS などのAWSストレージサービスへファイル転送が可能です。
本記事ではS3に対してFTPSを使ったファイル転送を実施する方法を紹介していきます。
構成概要
以下のような構成で実装を行います。

※下記のリソースに関しては、作成してある前提で進めますのでご了承ください。
- VPC + サブネット
- Route53ホストゾーン(同アカウント内管理)
- ACM
- S3バケット
- ElasticIP
カスタムIDプロバイダーはLambdaを使用していきます。
IAM
TransferFamilyとLambdaに割り当てるのIAMポリシー・IAMロールをそれぞれ作成します。
(ポリシー名・ロール名は任意で問題ないです)
許可ポリシー
- Transfer Family用
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
// S3 ARN
"arn:aws:s3:::test-s3-buket",
"arn:aws:s3:::test-s3-buket/*"
]
}
]
}
TransferFamilyにS3への権限を与えたポリシーになります。
※ARNはそれぞれの環境に合わせて変更してください
- Lambda用
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:0123456789012:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
// Lambda関数ARN
"arn:aws:logs:ap-northeast-1:0123456789012:/aws/lambda/test-transfer-function:*"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter"
],
"Resource": [
// パラメーターストアARN
"arn:aws:ssm:ap-northeast-1:0123456789012:parameter/transfer/ftps/users/*"
]
}
]
}
Lambdaにパラメーターストアへの権限を与えたポリシーです。
※ARNはそれぞれの環境に合わせて変更してください
ロール
- TransferFamily用
信頼されたエンティティタイプ: AWSのサービス
ユースケース: Transfer
許可ポリシー: 作成したTransferFamily用IAMポリシー
ロール名: 任意の名前
- Lambda用
信頼されたエンティティタイプ: AWSのサービス
ユースケース: Lambda
許可ポリシー: 作成したLambda用IAMポリシー
ロール名: 任意の名前
Systems Manager
Transfer FamilyユーザーはカスタムIDプロバイダーを使って管理していきます。
SystemsManagerパラメーターストアでユーザーパスワード情報のパラメーターを作成します。

今回は下記の設定値で作成します。
名前: /transfer/ftps/users/ユーザー名/password
利用枠: 標準
タイプ: 安全な文字列
KMSキーソース: 現在のアカウント
KMSキーID: alias/aws/ssm
値: 任意のパスワード
Lambda関数
パラメーターストアからユーザー情報を呼び出すLambda関数を作成します。
関数の作成

下記設定で作成します。
関数名: 任意の関数名を設定 ex) test-transfer-function
ランタイム; Python 3.13
アーキテクチャ: x86_64
実行ロール: 既存のロール(作成したLambda用IAMロール)
ソースコード記述
作成したLambda関数のコードソースを下記に書き換えてデプロイします。
import boto3
ssm_client = boto3.client("ssm", region_name="ap-northeast-1")
def lambda_handler(event, context):
# ログインしたユーザー名を取得
username = event.get("username")
# ログインユーザーのパスワードを取得
parameter_name = "/transfer/ftps/test/users/" + username + "/password"
response = ssm_client.get_parameter(Name=parameter_name, WithDecryption=True)
stored_password = response["Parameter"]["Value"]
if event.get("password") == stored_password:
# TransferFamily用IAMロールのARN
return { 'Role': 'arn:aws:iam::0123456789012:role/test-transfer-s3-access-role' }
return {}
TransferFamily作成
Transfer Familyサーバーを作成しいていきます。
ステップ1 プロトコル設定

プロトコル選択 → 今回は FTPS を選択
ACM証明書 → FTPS通信で使用するACM証明書を選択
ステップ2 プロバイダー設定

IDプロバイダタイプ → カスタムIDプロバイダ
「Lambdaを使用してアイデンティティプロバイダーを接続する」を選択
Lambda関数 → 作成したLambda関数を選択
ステップ3 エンドポイント設定

- エンドポイント → 「VPCでホスト」を選択
- アクセス → 内部
- カスタムホスト名: TransferFamilyのホスト名として設定する名前 ex) ftps.example.com
※Route53ホストゾーンで管理しているドメインのサブドメインで設定 - アクセス: インターネット向け
- VPC: TransferFamilyを配置するVPCを選択
- アベイラビリティーゾーン: ap-northeast-1a
- サブネットID: サブネットを選択
- IPv4アドレス: EIPを割り当てる
- アベイラビリティーゾーン: ap-northeast-1c
- サブネットID: サブネットを選択
- IPv4アドレス: EIPを割り当てる
- アベイラビリティーゾーン: ap-northeast-1a
- セキュリティグループ名: TransferFamilyへの接続を制限するセキュリティグループを選択
ステップ4 ドメイン設定
アクセス先のストレージサービスを選択する

ドメイン: Amazon S3
これ以降も数ステップありますが、デフォルト値で設定します。
最後に設定値を確認しTransferFamilyを作成します。(作成完了まで少し時間を要します)
作成が完了した後、対象のRoute53ホストゾーンに設定時にカスタムホスト名として決めたレコードが追加されているので確認しましょう。
Lambdaアクセス権限設定
TransferFamily作成後にLambdaでアクセス権限設定を追加していきます。
設定の際にTransferFamilyのARNが必要なので、あらかじめ控えておくといいと思います。

ポリシーステートメントを編集
- AWSのサービス
- サービス: Other
- ステートメントID: 一意であれば問題なし ex) test-transferfamily-GetUserConfigLambdaPermission
- プリンシパル: transfer.amazonaws.com
- ソースのARN: 作成したTransferFamilyのARN
- アクション: lambda:InvokeFunction
まとめ
以上で設定は完了です!
カスタムドメイン名・ユーザー名・パスワードを使用してS3へFTPS接続してみましょう。
今回はTransferFamilyを使ってS3にFTPS接続する方法を紹介しました。
TransferFamilyは他のプロトコルでも接続可能なので、ぜひ試してみていただければと思います。
本記事がご参考になれば幸いです。