如何通过AWS CDK创建SFTP服务器时配置自定义主机名?
解决方案
核心思路
- 分离资源生命周期:将Route53域名记录与SFTP服务器分属不同CDK栈,销毁SFTP栈时域名记录不受影响。
- 使用CDK原生配置:通过
aws-cdk-lib/aws-transfer模块的customHostname属性配置自定义域名,替代无效的标签方式。 - 独立管理证书与域名:ACM证书和Route53托管区域可复用或单独部署,避免与SFTP服务器绑定。
步骤1:部署域名管理栈(独立于SFTP栈)
这个栈负责创建Route53子域名记录,后续销毁SFTP时无需删除此栈,保留域名。
import * as cdk from 'aws-cdk-lib'; import * as route53 from 'aws-cdk-lib/aws-route53'; export class DomainStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 复用已有的Route53托管区域(替换为你的主域名) const hostedZone = route53.HostedZone.fromLookup(this, 'ExistingHostedZone', { domainName: 'example.com', }); // 创建CNAME记录,后续通过SFTP栈的输出更新端点 new route53.CnameRecord(this, 'SftpCnameRecord', { zone: hostedZone, recordName: 'sftp', domainName: 'placeholder.example.com', // 临时占位,后续替换为SFTP端点 }); } }
步骤2:部署SFTP服务器栈
在这个栈中创建Transfer Family SFTP服务器,配置自定义主机名,并输出端点供域名栈使用。
import * as cdk from 'aws-cdk-lib'; import * as transfer from 'aws-cdk-lib/aws-transfer'; import * as acm from 'aws-cdk-lib/aws-certificatemanager'; import * as route53 from 'aws-cdk-lib/aws-route53'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as s3 from 'aws-cdk-lib/aws-s3'; export class SftpStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 复用已有的Route53托管区域 const hostedZone = route53.HostedZone.fromLookup(this, 'ExistingHostedZone', { domainName: 'example.com', }); // 创建ACM证书(自定义SFTP域名必须绑定SSL证书) const sftpCert = new acm.Certificate(this, 'SftpCertificate', { domainName: 'sftp.example.com', validation: acm.CertificateValidation.fromDns(hostedZone), }); // 创建SFTP服务器,配置自定义主机名 const sftpServer = new transfer.Server(this, 'SftpServer', { protocol: transfer.FileTransferProtocol.SFTP, // 原生配置自定义主机名,自动关联证书与Route53 customHostname: { hostname: 'sftp.example.com', certificate: sftpCert, domain: hostedZone, }, // 配置身份提供者(此处用AWS托管身份,可替换为自定义方案) identityProvider: transfer.IdentityProviderType.SERVICE_MANAGED, // 配置日志角色(按需调整权限范围) loggingRole: new iam.Role(this, 'SftpLoggingRole', { assumedBy: new iam.ServicePrincipal('transfer.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess'), ], }), // 配置存储后端(此处用S3,可替换为EFS) storage: transfer.ServerStorage.s3({ bucket: new s3.Bucket(this, 'SftpBucket'), }), }); // 输出SFTP原生端点,供域名栈更新CNAME记录使用 new cdk.CfnOutput(this, 'SftpEndpoint', { value: sftpServer.endpoint, exportName: 'SftpEndpoint', }); } }
步骤3:关联域名与SFTP端点
更新域名栈,导入SFTP端点并修正CNAME记录:
// 更新DomainStack中的CnameRecord部分 const sftpEndpoint = cdk.Fn.importValue('SftpEndpoint'); new route53.CnameRecord(this, 'SftpCnameRecord', { zone: hostedZone, recordName: 'sftp', domainName: sftpEndpoint, });
关键说明
- 弃用标签方式:
aws:transfer:route53HostedZoneId和aws:transfer:customHostname标签为旧版配置,CDK已支持原生customHostname属性,无需再依赖标签。 - 资源隔离:域名记录在独立栈中,销毁SFTP栈时仅删除服务器资源,域名记录完整保留。
- 证书要求:自定义主机名必须绑定ACM证书,CDK会自动在Route53添加DNS验证记录完成证书激活。
- 端点获取:通过
sftpServer.endpoint可直接获取SFTP服务器的原生端点域名,无需额外API调用。
内容的提问来源于stack exchange,提问作者Yogesh Manware
相关产品推荐
相关产品推荐

