본문 바로가기

AWS

[AWS] Appstream 2.0을 이용한 원격환경 구성

반응형

1. 목적

이 가이드에서는 사용자에게 웹 페이지를 통하여 원격 데스크톱 환경을 제공하는 구성을 진행한다.

2. 구성도

Amazon AppStream2.0 으로 원격 데스크톱을 환경을 구성하고 CloudFront와 S3를 이용하여 사용자에게 원격 데스크톱을 이용할 수 있는 웹 페이지를 제공한다.

2.1 사전 요구 사항

다음 준비 사항이 사전에 준비되어 있어야 합니다. 이 가이드에서는 기본적인 VPC 구성은 완료된 상태라고 가정하고 진행한다.

  • CloudFront와 연결되는 도메인 주소
  • 정적 웹 페이지
  • Amazon SES 구성

2.2 서비스 흐름

  1. 유저는 CloudFront를 이용하여 정적 웹 페이지에 접근한다.
  2. 웹 페이지에서 이름과 메일 주소를 입력 후 Contiune 버튼을 누르면 API를 호출한다.
  3. API Gateway를 통해 연결되어있는 Lambda를 호출한다.
  4. Lambda에서는 AppStream2.0 스트리밍 URL 생성을 하여 정적 웹 페이지에서 생성된 스트리밍 URL로 리다이렉션을 하고, 사용자가 정적 웹 페이지에서 입력한 이름과 메일 주소를 이용하여 메일로 전달한다.

3. 구성

3.1 IAM 역할 생성

Lambda 서비스에서 AppStream2.0, SES 및 CloudWatch log를 사용할 수 있는 정책 및 역할을 생성한다.

  • 정책 코드
  • Resource 정보는 자신의 환경에 따라 변경될 수 있다.
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "appstream:CreateStreamingURL",
                "Resource": [
                    "arn:aws:appstream:ap-northeast-2:051280000000:fleet/test-app-stream-win-221008",
                    "arn:aws:appstream:ap-northeast-2:051280000000:stack/test-app-stream-win-stack_v1"
                ]
            },
            {
                "Effect": "Allow",
                "Action": "ses:SendEmail",
                "Resource": "*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": "*"
            }
        ]
    }
  • 역할 - 신뢰 정책
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

 

3.2 정적 웹 페이지 구성

이 가이드에서 S3에 정적 웹 사이트 호스팅을 진행하고 Cloudfront로 글로벌 엣지 로케이션에 배포하여 사용자에게 더 짧은 지연 시간으로 콘텐츠를 제공한다.

3.2.1 S3 구성

정적 웹 호스팅을 위한 S3 버킷을 생성하고 코드를 S3에 업로드한다.

 

CloudFront에서만 S3 버킷에 접근이 가능하도록 버킷 정책을 구성한다.

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::test/*"
        }
    ]
}

 

3.2.2 CloudFront 구성

3.2.1 항목에서 생성한 S3 버킷을 Cloudfront 원본으로 연결한다.

 

3.3 Lambda 구성

Lambda 함수에서는 AppStream 2.0을 통해 원격 데스크톱에 접속할 수 있는 Streaming URL을 생성하고, Amazon SES 서비스를 통해 이메일로 결과를 전달한다.

Lambda 서비스 구성시에는 앞서 생성한 IAM 역할을 이용하고, 아래 node.js로 작성된 코드를 실행하기 위해 node.js 런타임을 지정하여 생성한다.

// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

const AWS = require('aws-sdk');
const appstream = new AWS.AppStream;
const ses = new AWS.SES();
const crypto = require('crypto');

exports.handler = (event, context, callback) => {
    var eventdata = JSON.parse(event.body);

    var length = 16; //Adjust this value to shorten or lengthen the AS2 username - 32 chars is max length an AS2 username can be
    // var username = crypto.randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length); //generates a random string
    
    // /* 
    // Username could also be the name or email parameter from the event body

    // var username = eventdata.name
    var username = eventdata.email

    // */
    
    console.log("username: " + username);

    var params = { 
        FleetName: 'test-app-stream-win-221008', /* required */
        StackName: 'test-app-stream-win-stack_v1', /* required */
        UserId: username,
        Validity: 5 //TTL of URL

    };

    createas2streamingurl(params, eventdata, context.awsRequestId, callback);

};

function errorResponse(errorMessage, awsRequestId, callback) { //Function for handling error messaging back to client
    callback(null, {
        statusCode: 500,
        body: JSON.stringify({
            Error: errorMessage,
            Reference: awsRequestId,
        }),
        headers: {
            'Access-Control-Allow-Origin': '*', //This should be the domain of the website that originated the request, example: amazonaws.com
        },
    });
}

function createas2streamingurl(params, sesdata, awsRequestId, callback) {
    var request = appstream.createStreamingURL(params);
    request.
        on('success', function (response) { //Successful Response
            console.log("Success! AS2 Streaming URL created.");
            var output = response.data;
            var url = output.StreamingURL;
            sendEmail(sesdata); //With a successful AS2 URL generated, trigger the SES SendEmail function
            callback(null, {
                statusCode: 201,
                body: JSON.stringify({
                    Message: url,
                    Reference: awsRequestId,
                }),
                headers: {
                    'Access-Control-Allow-Origin': '*', //This should be the domain of the website that originated the request, example: amazonaws.com
                },
            });
        }).
        on('error', function (response) { //an error occoured 
            console.log("error: "  + JSON.stringify(response.message));
            errorResponse('Error creating AS2 streaming URL.', awsRequestId, callback);

        }).
        send();
}

function sendEmail(data) {
    var sender = "test@test.co.kr"; //Sender needs to be a verified address in SES
    var receiver = data.email.trim(); /*Trim the string of any preceding and trailing whitespaces*/
    var name = data.name.trim();
    var params = {
        Destination: {
            ToAddresses: [receiver]
        },
        Message: {
            Body: {
                Text: {
                    Data: 'Hello ' + name + ',' + '\n\nThank you for trying Example Corp\'s Application Suite.',
                    Charset: 'UTF-8'
                }
            },
            Subject: {
                Data: 'Thank you for trying Example Corp ' + name,
                Charset: 'UTF-8'
            }
        },
        Source: sender
    };
    console.log("Sending Email.");
    ses.sendEmail(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);           // successful response
    });
}

 

3.4 API Gateway 구성

Amazon API Gateway를 이용하여 REST API를 생성하고 Lambda 함수와 통합한다.

사용자는 정적 웹 페이지를 통해 API Gateway와 통합되어있는 Lambda 함수를 호출하게 된다.

 

3.5 AppStream 2.0 구성

Amazon AppStream 2.0을 이용하여 사용자에게 제공 될 원격 데스크톱 환경을 구성한다.

이 가이드에서는 Windows OS에서 테스트하고 진행한다. 아래 그림의 Administrator Workflow에 따라 유저에게 제공 될 환경을 구성한다.

 

Image Builder 구성

Image builder를 통해 사용자에게 제공 될 Application 및 OS 베이스 이미지를 생성한다.

Fleet 구성

Fleet에서 인스턴스 리소스, 인스턴스 수, Scale out 정책, 사용자 세션 정보 등을 설정할 수 있다.

Stack 구성

Stack에서 streaming protocol 설정, AD 설정, 스토리지 설정 등을 할 수 있다.

이 가이드에서는 S3 버킷을 신규로 생성하여 스토리지로 지정하였다.

4. 테스트
웹 브라우저를 열고 주소 표시줄에 CloudFront 주소 or Route 53에서 연결한 도메인 주소를 웹 브라우저에 입력하여 접속한다. 이름과 이메일 주소를 입력 후 Contiune 버튼으로 계속 진행한다.

 

 

Contiune에 성공하면 몇 초 이내로 AppStream 2.0 스트리밍 URL로 리다이렉션된다. 리다이렉션이 되면 애플리케이션 페이지가 나타난다.

 

 

Desktop 버튼을 클릭하여 OS로 접속이 정상적으로 되는지 확인한다.

 

원격 데스크톱에서 파일을 저장 후 파일이 S3에 정상적으로 저장이 되는지 확인한다.

 

처음에 입력한 이메일 주소로 이메일 수신이 되었는지 확인한다.

 

 

APPENDIX

이 가이드문서는 아래 AWS workshop을 기반으로 작성하였습니다.

Create an Online Software Trial with AppStream 2.0

 

Create an Online Software Trial with AppStream 2.0

The following steps show how to use a template in AWS CloudFormation to automate the tasks described in Modules 1, 3, and 4 of this project. For a list of these tasks, see the “Tasks you’ll accomplish” section in the project Overview page. Note Altho

aws.amazon.com

.

AWS reinvent 2021에서 발표된 자료

https://d1.awsstatic.com/events/reinvent/2021/Provisioning_your_first_Amazon_AppStream_20_environment_EUC202.pdf

반응형

'AWS' 카테고리의 다른 글

[AWS] IAM 계정 생성  (0) 2023.09.05
[AWS] GWLB 구성 가이드 with Terraform(2)  (0) 2023.08.31
[AWS] GWLB 구성 가이드 with Terraform(1)  (0) 2023.08.31
[AWS] EBS 용량 증설 가이드  (0) 2023.08.29
[AWS] WAF 구성 가이드  (0) 2023.08.27