使用 Amazon 测试设置 WorkSpaces - AWS Management Console

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Amazon 测试设置 WorkSpaces

亚马逊 WorkSpaces 允许您为用户配置虚拟的、基于云的 Windows、Amazon Linux 或 Ubuntu Linux 桌面,即。 WorkSpaces您可以根据需求的变更,快速添加或删除用户。用户可以从多个设备或 Web 浏览器访问自己的虚拟桌面。要了解更多信息 WorkSpaces,请参阅《Amazon WorkSpaces 管理指南》

本节中的示例描述了一个测试环境,在该环境中,用户环境使用在上运行的 Web 浏览器登录 P AWS Management Console ri WorkSpace vate Access。然后,用户访问 Amazon Simple Storage Service 控制台。 WorkSpace 这旨在模拟企业用户在VPC联网的网络上使用笔记本电脑,通过浏览器访问 AWS Management Console 的体验。

本教程用于创建和配置网络设置和要使用的简单 Active Directory, WorkSpaces 以及 WorkSpace 使用设置的分步说明 AWS Management Console。 AWS CloudFormation

下图描述了使用测试 AWS Management Console 私有 WorkSpace 访问设置的工作流程。它显示了客户 WorkSpace、Amazon 托管VPC和客户管理之间的关系VPC。

使用 Amazon 测试 AWS Management Console 私有访问权限的设置配置 WorkSpaces。

复制以下 AWS CloudFormation 模板并将其保存到一个文件中,您将在步骤的第 3 步中使用该文件来设置网络。

Description: | AWS Management Console Private Access. Parameters: ​ VpcCIDR: Type: String Default: 172.16.0.0/16 Description: CIDR range for VPC ​ PublicSubnet1CIDR: Type: String Default: 172.16.1.0/24 Description: CIDR range for Public Subnet A ​ PublicSubnet2CIDR: Type: String Default: 172.16.0.0/24 Description: CIDR range for Public Subnet B ​ PrivateSubnet1CIDR: Type: String Default: 172.16.4.0/24 Description: CIDR range for Private Subnet A ​ PrivateSubnet2CIDR: Type: String Default: 172.16.5.0/24 Description: CIDR range for Private Subnet B ​ # Amazon WorkSpaces is available in a subset of the Availability Zones for each supported Region. # https://docs.aws.amazon.com/workspaces/latest/adminguide/azs-workspaces.html Mappings: RegionMap: us-east-1: az1: use1-az2 az2: use1-az4 az3: use1-az6 us-west-2: az1: usw2-az1 az2: usw2-az2 az3: usw2-az3 ap-south-1: az1: aps1-az1 az2: aps1-az2 az3: aps1-az3 ap-northeast-2: az1: apne2-az1 az2: apne2-az3 ap-southeast-1: az1: apse1-az1 az2: apse1-az2 ap-southeast-2: az1: apse2-az1 az2: apse2-az3 ap-northeast-1: az1: apne1-az1 az2: apne1-az4 ca-central-1: az1: cac1-az1 az2: cac1-az2 eu-central-1: az1: euc1-az2 az2: euc1-az3 eu-west-1: az1: euw1-az1 az2: euw1-az2 eu-west-2: az1: euw2-az2 az2: euw2-az3 sa-east-1: az1: sae1-az1 az2: sae1-az3 ​ Resources: ​ iamLambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: describe-ec2-az PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - 'ec2:DescribeAvailabilityZones' Resource: '*' MaxSessionDuration: 3600 Path: /service-role/ ​ fnZoneIdtoZoneName: Type: AWS::Lambda::Function Properties: Runtime: python3.8 Handler: index.lambda_handler Code: ZipFile: | import boto3 import cfnresponse ​ def zoneId_to_zoneName(event, context): responseData = {} ec2 = boto3.client('ec2') describe_az = ec2.describe_availability_zones() for az in describe_az['AvailabilityZones']: if event['ResourceProperties']['ZoneId'] == az['ZoneId']: responseData['ZoneName'] = az['ZoneName'] cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, str(az['ZoneId'])) def no_op(event, context): print(event) responseData = {} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, str(event['RequestId'])) ​ def lambda_handler(event, context): if event['RequestType'] == ('Create' or 'Update'): zoneId_to_zoneName(event, context) else: no_op(event,context) Role: !GetAtt iamLambdaExecutionRole.Arn ​ getAZ1: Type: "Custom::zone-id-zone-name" Properties: ServiceToken: !GetAtt fnZoneIdtoZoneName.Arn ZoneId: !FindInMap [ RegionMap, !Ref 'AWS::Region', az1 ] getAZ2: Type: "Custom::zone-id-zone-name" Properties: ServiceToken: !GetAtt fnZoneIdtoZoneName.Arn ZoneId: !FindInMap [ RegionMap, !Ref 'AWS::Region', az2 ] ​ ######################### # VPC AND SUBNETS ######################### ​ AppVPC: Type: 'AWS::EC2::VPC' Properties: CidrBlock: !Ref VpcCIDR InstanceTenancy: default EnableDnsSupport: true EnableDnsHostnames: true ​ PublicSubnetA: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref AppVPC CidrBlock: !Ref PublicSubnet1CIDR MapPublicIpOnLaunch: true AvailabilityZone: !GetAtt getAZ1.ZoneName PublicSubnetB: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref AppVPC CidrBlock: !Ref PublicSubnet2CIDR MapPublicIpOnLaunch: true AvailabilityZone: !GetAtt getAZ2.ZoneName ​ PrivateSubnetA: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref AppVPC CidrBlock: !Ref PrivateSubnet1CIDR AvailabilityZone: !GetAtt getAZ1.ZoneName ​ PrivateSubnetB: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref AppVPC CidrBlock: !Ref PrivateSubnet2CIDR AvailabilityZone: !GetAtt getAZ2.ZoneName ​ InternetGateway: Type: AWS::EC2::InternetGateway ​ InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref AppVPC ​ NatGatewayEIP: Type: AWS::EC2::EIP DependsOn: InternetGatewayAttachment ​ NatGateway: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt NatGatewayEIP.AllocationId SubnetId: !Ref PublicSubnetA ​ ######################### # Route Tables ######################### ​ PrivateRouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref AppVPC ​ DefaultPrivateRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway ​ PrivateSubnetRouteTableAssociation1: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnetA ​ PrivateSubnetRouteTableAssociation2: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnetB ​ PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref AppVPC ​ DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway ​ PublicSubnetARouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnetA ​ PublicSubnetBRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnetB ​ ​ ######################### # SECURITY GROUPS ######################### ​ VPCEndpointSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Allow TLS for VPC Endpoint VpcId: !Ref AppVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !GetAtt AppVPC.CidrBlock ######################### # VPC ENDPOINTS ######################### ​ VPCEndpointGatewayS3: Type: 'AWS::EC2::VPCEndpoint' Properties: ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' VpcEndpointType: Gateway VpcId: !Ref AppVPC RouteTableIds: - !Ref PrivateRouteTable VPCEndpointInterfaceSignin: Type: 'AWS::EC2::VPCEndpoint' Properties: VpcEndpointType: Interface PrivateDnsEnabled: false SubnetIds: - !Ref PrivateSubnetA - !Ref PrivateSubnetB SecurityGroupIds: - !Ref VPCEndpointSecurityGroup ServiceName: !Sub 'com.amazonaws.${AWS::Region}.signin' VpcId: !Ref AppVPC VPCEndpointInterfaceConsole: Type: 'AWS::EC2::VPCEndpoint' Properties: VpcEndpointType: Interface PrivateDnsEnabled: false SubnetIds: - !Ref PrivateSubnetA - !Ref PrivateSubnetB SecurityGroupIds: - !Ref VPCEndpointSecurityGroup ServiceName: !Sub 'com.amazonaws.${AWS::Region}.console' VpcId: !Ref AppVPC ​ ######################### # ROUTE53 RESOURCES ######################### ​ ConsoleHostedZone: Type: "AWS::Route53::HostedZone" Properties: HostedZoneConfig: Comment: 'Console VPC Endpoint Hosted Zone' Name: 'console.aws.amazon.com' VPCs: - VPCId: !Ref AppVPC VPCRegion: !Ref "AWS::Region" ConsoleRecordGlobal: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'ConsoleHostedZone' Name: 'console.aws.amazon.com' AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] Type: A ​ GlobalConsoleRecord: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'ConsoleHostedZone' Name: 'global.console.aws.amazon.com' AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] Type: A ConsoleS3ProxyRecordGlobal: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'ConsoleHostedZone' Name: 's3.console.aws.amazon.com' AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] Type: A ConsoleSupportProxyRecordGlobal: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'ConsoleHostedZone' Name: "support.console.aws.amazon.com" AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] Type: A ExplorerProxyRecordGlobal: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'ConsoleHostedZone' Name: "resource-explorer.console.aws.amazon.com" AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] Type: A ConsoleRecordRegional: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'ConsoleHostedZone' Name: !Sub "${AWS::Region}.console.aws.amazon.com" AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceConsole.DnsEntries]]] Type: A ​ SigninHostedZone: Type: "AWS::Route53::HostedZone" Properties: HostedZoneConfig: Comment: 'Signin VPC Endpoint Hosted Zone' Name: 'signin.aws.amazon.com' VPCs: - VPCId: !Ref AppVPC VPCRegion: !Ref "AWS::Region" SigninRecordGlobal: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'SigninHostedZone' Name: 'signin.aws.amazon.com' AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceSignin.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceSignin.DnsEntries]]] Type: A SigninRecordRegional: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref 'SigninHostedZone' Name: !Sub "${AWS::Region}.signin.aws.amazon.com" AliasTarget: DNSName: !Select ['1', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceSignin.DnsEntries]]] HostedZoneId: !Select ['0', !Split [':', !Select ['0', !GetAtt VPCEndpointInterfaceSignin.DnsEntries]]] Type: A ​ ######################### # WORKSPACE RESOURCES ######################### ADAdminSecret: Type: AWS::SecretsManager::Secret Properties: Name: "ADAdminSecret" Description: "Password for directory services admin" GenerateSecretString: SecretStringTemplate: '{"username": "Admin"}' GenerateStringKey: password PasswordLength: 30 ExcludeCharacters: '"@/\' ​ WorkspaceSimpleDirectory: Type: AWS::DirectoryService::SimpleAD DependsOn: AppVPC DependsOn: PrivateSubnetA DependsOn: PrivateSubnetB Properties: Name: "corp.awsconsole.com" Password: '{{resolve:secretsmanager:ADAdminSecret:SecretString:password}}' Size: "Small" VpcSettings: SubnetIds: - Ref: PrivateSubnetA - Ref: PrivateSubnetB ​ VpcId: Ref: AppVPC ​ ​ Outputs: PrivateSubnetA: Description: Private Subnet A Value: !Ref PrivateSubnetA ​ PrivateSubnetB: Description: Private Subnet B Value: !Ref PrivateSubnetB ​ WorkspaceSimpleDirectory: Description: Directory to be used for Workspaces Value: !Ref WorkspaceSimpleDirectory ​ WorkspacesAdminPassword: Description : "The ARN of the Workspaces admin's password. Navigate to the Secrets Manager in the AWS Console to view the value." Value: !Ref ADAdminSecret
注意

此测试设置设计为在美国东部(弗吉尼亚州北部)(us-east-1)区域中运行。

设置网络
  1. 登录您所在组织的管理账户并打开 AWS CloudFormation 控制台

  2. 选择创建堆栈

  3. 选择使用新资源(标准)。上传您之前创建的 AWS CloudFormation 模板文件,然后选择 “下一步”。

  4. 输入堆栈的名称(例如 PrivateConsoleNetworkForS3),然后选择下一步

  5. 对于VPC和子网,请输入您的首选 IP CIDR 范围,或使用提供的默认值。如果您使用默认值,请确认它们不与中的现有VPC资源重叠 AWS 账户。

  6. 选择创建堆栈

  7. 创建堆栈后,选择资源选项卡以查看已创建的资源。

  8. 选择输出选项卡,以查看私有子网和工作区简单目录的值。请记下这些值,因为您将在下一个创建和配置过程的第四步中使用它们 WorkSpace。

以下屏幕截图显示了输出选项卡的视图,其中显示了私有子网和工作区简单目录的值。

私有子网和工作区简单目录及其相应的值。

现在您已经创建了网络,请按照以下步骤创建和访问网络 WorkSpace。

要创建 WorkSpace
  1. 打开控制WorkSpaces 台

  2. 在导航窗格中,选择目录

  3. 目录页面上,验证目录状态是否为活动。以下屏幕截图显示了具有一个活动的目录的目录页面。

    “目录”页面,其中包含一个处于活动状态的目录的条目。
  4. 要使用中的目录 WorkSpaces,必须对其进行注册。在导航窗格中,选择 WorkSpaces,然后选择创建 WorkSpaces

  5. 对于选择目录,选择 AWS CloudFormation 在前面的过程中创建的目录。在操作菜单上,选择注册

  6. 要选择子网,请选择前述过程的步骤 9 中记下的两个私有子网。

  7. 选择启用自助服务权限,然后选择注册

  8. 注册目录后,继续创建 WorkSpace。选择注册的目录,然后选择下一步

  9. 创建用户页面上,选择创建其他用户。输入您的姓名和电子邮件以使您能够使用 WorkSpace. 当 WorkSpace 登录信息发送到该电子邮件地址时,请验证该电子邮件地址是否有效。

  10. 选择下一步

  11. 标识用户页面上,选择您在步骤 9 中创建的用户,然后选择下一步

  12. 选择服务包页面上,选择 Amazon Linux 2 标准版,然后选择下一步

  13. 对于运行模式和用户自定义使用默认值,然后选择创建工作区。 WorkSpace 开始进入Pending状态,然后在大约 20 分钟Available内过渡到状态。

  14. 可用 WorkSpace 时,您将通过您在步骤九中提供的电子邮件地址收到一封包含访问说明的电子邮件。

登录后 WorkSpace,您可以测试自己是否正在使用 AWS Management Console 私有访问权限对其进行访问。

要访问 WorkSpace
  1. 打开您在前述过程的步骤 14 中收到的电子邮件。

  2. 在电子邮件中,选择提供的唯一链接来设置您的个人资料并下载 WorkSpaces 客户端。

  3. 设置您的密码。

  4. 下载您选择的客户端。

  5. 安装并启动客户端。输入电子邮件中提供的注册码,然后选择注册

  6. WorkSpaces 使用您在第三步中创建的凭证登录 Amazon。

测试 AWS Management Console 私有访问设置
  1. 从您的 WorkSpace,打开浏览器。然后,导航到 AWS Management Console并使用您的凭证登录。

    注意

    如果您使用 Firefox 作为浏览器,请确认您的浏览器设置中的 “启用DNS过来” HTTPS 选项已关闭。

  2. 打开 Amazon S3 控制台,您可以在其中验证您是否已使用 AWS Management Console 私有访问进行连接。

  3. 选择导航栏上的 lock-private 图标可查看正在使用的VPC和VPC端点。以下屏幕截图显示了 lock-private 图标的VPC位置和信息。

    显示锁私有图标位置和 AWS Management Console 私有访问信息的 Amazon S3 控制台。