クラウドインテグレーション部の渡邊です。
今回はAWS Transfer for SFTP(以降、Transfer Familyと呼ぶ)によって、別アカウントの複数のEFSへ接続します。
Transfer Familyのエンドポイントタイプとして、インターネット向けアクセスを持つVPCエンドポイント(EndpointType=VPC
)を使用します。
Transfer FamilyユーザにIAMロールをアタッチします。
IAMロールに付与したポリシーの内容は以下です。
こちらのIAMロールのARNは、このあとに設定するEFSファイルシステムポリシーで使用するため、値を控えておきましょう。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "RootFileSystemAccess", "Effect": "Allow", "Action": [ "elasticfilesystem:ClientWrite", "elasticfilesystem:ClientRootAccess", "elasticfilesystem:ClientMount" ], "Resource": [ "<接続先のEFS ARN1>", "<接続先のEFS ARN2>" ] } ] }
Amazon Elastic File System ユーザーガイドを参考にポリシーを設定しました。
マウントターゲットを経由したアクセス許可と、該当するIAMロールによるアクセス許可を設定しています。
{ "Version": "2008-10-17", "Statement": [ { "Sid": "NFS-client-read-write-via-fsmt", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "elasticfilesystem:ClientRootAccess", "elasticfilesystem:ClientWrite", "elasticfilesystem:ClientMount" ], "Resource": "<本ポリシーを設定するEFSのARN>", "Condition": { "Bool": { "elasticfilesystem:AccessedViaMountTarget": "true" } } }, { "Sid": "Grant-transfer-role-access", "Effect": "Allow", "Principal": { "AWS": [ "<Transfer Familyユーザのiamロールarn>" ] }, "Action": [ "elasticfilesystem:ClientRootAccess", "elasticfilesystem:ClientWrite", "elasticfilesystem:ClientMount" ], "Resource": "<本ポリシーを設定するEFSのARN>" } ] }</transferfamilyユーザのiamロールarn>
1つ目のSid値 NFS-client-read-write-via-fsmt
のブロックに関しては、ドキュメントにも記載があるように、Transfer Familyからのアクセスを許可するためにパブリックアクセスのブロックをする必要があるため記述しています。
Amazon EFS を AWS Transfer Family で使用する場合、ファイルシステムがパブリックアクセスを許可していると、ファイルシステムとは異なるアカウントが所有する Transfer Family サーバーから受信したファイルシステムのアクセス要求がブロックされます。Amazon EFS はファイルシステムの IAM ポリシーを評価し、ポリシーがパブリックである場合は、リクエストをブロックします。AWS Transfer Family のファイルシステムへのアクセスを許可するには、ファイルシステムポリシーを更新し、パブリックと見なされないようにします。
引用元:AWS Transfer Family を使用したパブリックアクセスのブロック
2つ目のSid値 Grant-transfer-role-access
のブロックに関しては、ドキュメントで記述されているアクションに、rootユーザとしてのアクセスを許可するアクションClientRootAccess
を追加しました。
また、Principalにワイルドカード(*)を指定しても、別アカウントのIAMロールでアクセスできないので明示的に指定する必要があります。
他のアカウントのプリンシパルの場合、アカウント内にリソースへのアクセスを許可する ID ベースのアクセス許可がある必要があります。これはクロスアカウントアクセスと呼ばれます。
引用元:すべてのプリンシパル
※ドキュメント記載の以下該当部分は、同じアカウントに対してどちらも設定した場合、SidGrant-transfer-role-access
は機能しませんので注意してください。
1つ目のSidGrant-cross-account-access
でアカウントごと許可しているためです。
{ "Sid": "Grant-cross-account-access", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root" }, "Action": [ "elasticfilesystem:ClientWrite", "elasticfilesystem:ClientMount" ] }, { "Sid": "Grant-transfer-role-access", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/EFS-role-for-transfer" }, "Action": [ "elasticfilesystem:ClientWrite", "elasticfilesystem:ClientMount" ] }
引用元:Transfer Family クロスアカウントアクセスの設定
コンソール画面上で別アカウントのEFSディレクトリを指定することができないため、AWS CLIでTransfer Familyユーザを作成します(私は、AWS CloudShellから実行しました)。
ユーザ作成時にディレクトリのマッピング設定も同時にやります。
まず、環境変数を用意してください。
EFS_ID1=<接続先のEFS ID1>
EFS_ID2=<接続先のEFS ID2>
SERVER=<Transfer FamilyのサーバID>
IAM_ROLE=<ユーザにアタッチするロールARN>
PUBLIC_KEY=<公開鍵情報>
次にユーザを作成するために、以下コマンドを実行します。
aws transfer create-user \ --home-directory-type "LOGICAL" \ --home-directory-mappings "[ { \"Entry\": \"/efs1\", \"Target\": \"/${EFS_ID1}\" }, { \"Entry\": \"/efs2\", \"Target\": \"/${EFS_ID2}\" }]" \ --posix-profile "Uid=0,Gid=0" \ --role "${IAM_ROLE}" \ --server-id "${SERVER}" \ --ssh-public-key-body "${PUBLIC_KEY}" \ --user-name "test"
マウントした複数のEFSのパスは以下のように表示される想定です。
/
├── efs1
└── efs2
この表示されるパスの名前は--home-directory-mappings
のEntry
で指定できるのでご自由に指定可能です。
今回はルートユーザを作成するためUIDとGIDは0
を指定しました。
ローカルからTransfer FamilyへSFTP接続して動作確認をします。
sftp -i <秘密鍵のパス> test@<Transfer Familyのエンドポイント名>
Connected to <Transfer Familyのエンドポイント名>
接続できたのでファイルをアップロードできるかを確認してみます。
sftp> put /Users/XXXX/Downloads/tmp /efs1
Uploading /Users/XXXX/Downloads/tmp to /efs1/tmp
tmp 100% 0 0.0KB/s 00:00
sftp> pwd
Remote working directory: /
sftp> ls
efs1 efs2
sftp> cd /efs1
sftp> ls
tmp
アップロードできました。マウントした各EFSのパスも想定通りです。
今回は、単一のアカウントにある複数のEFSへ接続することを想定しましたが、同様の方法で複数のアカウントにある複数のEFSに対しても接続が可能です。
Transfer Familyから複数のEFSを一括管理できるのはありがたいですね。
今回、Transfer Familyのエンドポイントとは別のVPCにある、マウントターゲットに対して接続を行いました。
その際に、Transit GatewayやVPCピアリングなどの、VPC間接続用のネットワークサービスの作成やEFS側のセキュリティグループの設定を行わず、接続に成功しました。
よって、Transfer Family用に、VPC間接続用のサービスの追加やEFS側のセキュリティグループの追加設定は不要です。
ちなみに、EFSポリシーのPrincipal
を明示的にIAMロール指定した記述をワイルドカード(*)へ変更したところ、やはり見られなくなりました。
sftp> ls remote readdir("/efs1"): Permission denied
【参考】
Transfer Family を使用して SFTP 経由でファイルを EFS に直接アップロードしてみた(VPCインターネット向け-鍵認証のみ編)
Virtual Private Cloud でサーバーを作成する