1. 목적
이 가이드에서는 사용자에게 웹 페이지를 통하여 원격 데스크톱 환경을 제공하는 구성을 진행한다.
2. 구성도
Amazon AppStream2.0 으로 원격 데스크톱을 환경을 구성하고 CloudFront와 S3를 이용하여 사용자에게 원격 데스크톱을 이용할 수 있는 웹 페이지를 제공한다.
2.1 사전 요구 사항
다음 준비 사항이 사전에 준비되어 있어야 합니다. 이 가이드에서는 기본적인 VPC 구성은 완료된 상태라고 가정하고 진행한다.
- CloudFront와 연결되는 도메인 주소
- 정적 웹 페이지
- Amazon SES 구성
2.2 서비스 흐름
- 유저는 CloudFront를 이용하여 정적 웹 페이지에 접근한다.
- 웹 페이지에서 이름과 메일 주소를 입력 후 Contiune 버튼을 누르면 API를 호출한다.
- API Gateway를 통해 연결되어있는 Lambda를 호출한다.
- 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
.
AWS reinvent 2021에서 발표된 자료
'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 |