...
실습이 종료되고 나면 리소스를 삭제해야 합니다. 해당 핸즈온은 CloudFormation 기반으로 진행됩니다. 배포 Stack을 삭제하고, 실습에 사용한 Cloud9과 같은 Stack을 삭제하면, 배포되어 있는 리소스도 함께 삭제가 됩니다. 반드시 상단에 게시된 리소스에 대해서 삭제가 이루어졌는지 확인 후 실습을 종료합니다. 만약 S3 버킷에 객체가 남아 있어서 삭제가 되지 않는 경우, 해당 S3 버킷을 직접 삭제하고 확인 합니다.
...
서버리스 웹
...
애플리케이션 구축 방법 소개
아래는 실습에 구축할 서버리스 웹 애플리케이션의 다이어그램입니다. 서버리스 서비스를 이용하기 때문에, 프로비저닝, 패치, 확장에 대해 고민할 필요가 없으며, 사용한 만큼만 비용을 지불합니다. 또한, 서버리스 서비스는 완전 관리형 서비스이기 때문에, 개발자는 애플리케이션 개발 자체에만 집중할 수 있습니다.
draw.io Diagram | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
...
구성 영역별 소개
이 애플리케이션은 다섯 가지 영역으로 구분할 수 있습니다.
정적 웹페이지 구현 - StaticWebBucket
- 이 시나리오는 Amazon S3(Simple Storage Service)에서 호스팅되는 정적 웹 페이지를 기반으로 실행합니다.
- 이 시나리오는 Amazon S3(Simple Storage Service)에서 호스팅되는 정적 웹 페이지를 기반으로 실행합니다.
새로운 뉴스를 등록 - PostNews
- MP3로 생성할 텍스트 정보는 Amazon API Gateway에 의해 노출된 RESTful API로 수신합니다.
- Amazon API Gateway는 MP3 파일 생성 프로세스를 초기화하는 전용 Lambda 함수인 "PostNews"를 설정합니다.
- "PostNews" Lambda 함수는 News에 대한 메타 정보를 "NewsTable" DynamoDB 테이블에 저장합니다.
- TTS 변환 프로세스를 비동기적으로 실행하기 위해 Amazon SNS의 Topic(NewsTopic)에 DynamoDB(NewsTable)에 등록한 새로운 id 값을 게시합니다.
텍스트를 MP3로 변환 - ConvertAudio
- Amazon SNS Topic에 의해서 트리거된 Lambda 함수인 "ConvertAudio"는 요청 텍스트를 오디오 파일로 변환합니다.
- "ConvertAudio" Lambda 함수는 Amazon Polly를 사용하여 텍스트를 지정된 언어의 음성을 이용하여 오디오 파일로 변환합니다.
- 생성된 오디오 파일인 MP3 파일은 전용 S3 버킷인 "PollyMp3Bucket"에 저장합니다.
- MP3는 S3 버킷에 대한 참조 URL 정보 및 해당 게시물 처리 상태에 대한 정보는 DynamoDB 테이블에 업데이트 합니다.
등록된 뉴스 정보 검색 - GetNews
RESTful 웹 서비스는 Amazon API Gateway를 사용하여 배포합니다. Amazon API Gateway는 게시물에- GET 메서드를 이용해서 뉴스에 대한 정보를 검색하는 방법을 제공합니다.
- "GetNews
- " Lambda 함수는 DynamoDB 테이블에서
- 뉴스 텍스트에 대한 정보와 버킷에 업로드한 MP3 버킷 URL 정보를 제공합니다.
기존 뉴스 삭제 - DeleteNews
- RESTful
- API로 Delete 메서드를 이용하여 삭제를 요청합니다.
- "DeleteNews"
- Lambda 함수는 DynamoDB에 저장되어 있는 해당 News 항목과 관련되어 생성한 MP3를 삭제합니다.
실습
이 예제는 Cloud9이 존재하는 Singapore 리전에서 English 언어로 진행합니다.
실습은 다음과 같은 순서로 진행됩니다.
Lab1. Cloud 9을 이용한 웹 애플리케이션 구축 실습
실습 순서는 다음과 같이 Lab1과 Lab2로 구성되어져 있습니다.
Lab1. Cloud9을 이용한 서버리스 웹 애플리케이션 구축
Lab1은 Cloud9 IDE를 이용하여 서버리스 웹 애플리케이션을 구축하는 방법을 살펴봅니다. 이 실습은 Cloud9이 존재하는 Singapore 리전에서 English 언어로 진행합니다. 통합 개발 환경(IDE)은 싱가포르 리전을 사용하지만, 서비스 배포는 리전을 선택 할 수 있습니다. 이 실습에서는 배포 서비스의 확인을 간단히 하기 위해서 Singapore 리전을 그대로 사용하겠습니다.
Cloud9 IDE 환경 생성
- AWS 콘솔 환경에서 Cloud9 서비스로 이동합니다.
- Create environment 버튼을 클릭하여 Cloud9 환경을 생성합니다.
- Cloud9 이름을 NewsWebApp 이라고 생성합니다. 설명(News Web Application using Serverless Service)은 옵션이기 때문에 넣지 않아도 됩니다.
- Cloud9의 환경설정을 합니다. 개발환경은 EC2 인스턴스로 선택하고 인스턴스 타입은 t2.micro를 선택합니다. 프리티어로 사용할 수 있습니다. Cloud9 IDE를 30분간 사용하지 않으면, 자동으로 EC2 인스턴스가 Stop 되어 비용을 절감할 수 있는 옵션을 기본적으로 제공합니다.
- Cloud9 최종 점검을 합니다. 모든 검수가 완료되면 Create environment 버튼을 클릭합니다.
- Cloud9 IDE가 준비중인 것을 확인할 수 있습니다. 몇 분이 지나면 IDE가 활성화 됩니다.
- Cloud9에서 IDE에 대해서 환경 설정을 할 수 있습니다. 화면과 같이 서비스 배포를 위한 리전을 별도로 지정할 수 있습니다. 여기서는 Singapore 리전을 그대로 사용합니다.
- 개발 환경이 설치되고 서버리스 애플리케이션 개발을 할 준비가 완료되었습니다.
- AWS 콘솔 환경에서 Cloud9 서비스로 이동합니다.
- Cloud9 IDE 환경 생성
Application 및 "PostNews" Lambda 함수 생성
SAM
(template.yml)에 DynamoDB, SNS, S3(Web, Mp3) 리소스 추가하기기반 서버리스 리소스 추가
"ConvertAudio" Lambda 함수 생성
"GetNews" Lambda 함수 생성
"DeleteNews" Lambda 함수 생성
SAM에서의 Outputs 설정
SAM에서의 CORS
SAM의 Output설정
정적 웹 호스팅을 위한 파일 업로드하기
서비스 동작 테스트
SAM을 CloudFormation 스택에 직접 반영하기
Lab2. Code* 서비스를 이용한 서버리스
...
CI/CD 배포 프로세스 구축
...
소스 리포지토리를 위해서 CodeCommit 생성
CodeBuiild를 위한 buildspec.yaml 파일 생성
CodePipeline 구축하기
소스 리포티토리에 코드 체크인하기
배포 결과 확인 (S3 정적 웹 페이지는 다루지 않습니다.)
API를 이용해서 결과 확인
Canary 배포를 위한 설정하기
CloudFormation에서 CodeDeploy 할 수 있도록 IAM 정책 설정 적용
코드를 변경하여 배포하고 CodeDeploy 중에 API를 호출하여 적용되는지 확인하기
기존 배포 버전으로 롤백하기
...
Lab3.
...
Cloud9 IDE 환경 생성
...
X-ray를 이용한 서버리스 서비스 모니터링 및 디버깅 (9월 예정)
Lab4. LocalStack을 이용한 로컬 테스트 환경 구축 및 테스트 (미정)
Lab5. ElasticSearch를 이용한 검색 서비스 구축 (미정)
...
Application 및 "PostNews" Lambda 함수 생성
- 새로운 애플리케이션 및 람다 함수 생성합니다. Cloud9 IDE 우측 네비게이션의 AWS Resources 탭을 클릭하고, Lambda 아이콘을 클릭하면 새로운 함수를 생성할 수 있습니다.
- Application name에는 WebApp을 Function name에는 PostNews를 입력하고 Next 버튼을 클릭합니다.
- Runtime은 Python 2.7을 선택하고, Blueprint는 hello-world-python을 선택하고 Next 버튼을 클릭합니다.
- 가나다
- 가나다
- 가나다
- 가나다
가나다
코드 블럭 language py theme RDark title PostNews linenumbers true # -*- coding: utf-8 -*- from __future__ import print_function import boto3 import os import json import uuid import datetime def lambda_handler(event, context): if "body" in event: event = json.loads(event['body']) print (event) recordId = str(uuid.uuid4()) voice = event["voice"] originText = event["text"] timbre = event["timbre"] pitch = event["pitch"] updateDate = datetime.datetime.now().strftime("%Y%m%d") print('Generating new DynamoDB record, with ID: ' + recordId) # Create the item in DynamoDB table dynamodb = boto3.resource('dynamodb') table = dynamodb.Table(os.environ['DB_TABLE_NAME']) table.put_item( Item={ 'id' : recordId, 'originText': originText, 'postDate': int(updateDate), 'pollyVoice' : voice, 'pollyStatus' : "PROCESSING", 'pollyTimbre': timbre, 'pollyPitch': pitch } ) # Sending notification about new post to SNS client = boto3.client('sns') client.publish( TopicArn = os.environ['SNS_TOPIC'], Message = recordId ) response = { 'statusCode': 200, 'body': json.dumps({'recordId': recordId}), 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } } return response
- 가나다
가나다
코드 블럭 language yml theme RDark title PostNewsTemplate_01 linenumbers true AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: >- Building Serverless development environment and CI/CD process for DevOps based on Cloud9 Globals: Function: Runtime: python2.7 Handler: lambda_function.lambda_handler MemorySize: 128 Timeout: 60 Resources: PostNews: Type: 'AWS::Serverless::Function' Properties: CodeUri: PostNews Description: Post news text to convert from text to speech Events: PostNewsApi: Type: Api Properties: Path: /news Method: POST Policies: - Version: '2012-10-17' Statement: - Effect: Allow Action: - 'logs:PutLogEvents' - 'logs:CreateLogStream' - 'dynamodb:PutItem' - 'sns:Publish' Resource: '*'
- 배포하기
...
가나다
코드 블럭 language yml theme RDark title PostNewsTemplate_02 linenumbers true AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: >- Building Serverless development environment and CI/CD process for DevOps based on Cloud9 Globals: Function: Runtime: python2.7 Handler: lambda_function.lambda_handler MemorySize: 128 Timeout: 60 Environment: Variables: DB_TABLE_NAME: Ref: NewsTable SNS_TOPIC: Ref: NewsTopic BUCKET_NAME: Ref: PollyMp3Bucket Resources: NewsTable: Type: 'AWS::Serverless::SimpleTable' Properties: PrimaryKey: Name: id Type: String ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 5 NewsTopic: Type: 'AWS::SNS::Topic' Properties: DisplayName: NewsTopic PollyMp3Bucket: Type: 'AWS::S3::Bucket' StaticWebBucket: Type: 'AWS::S3::Bucket' Properties: AccessControl: PublicRead WebsiteConfiguration: IndexDocument: index.html ErrorDocument: error.html PostNews: Type: 'AWS::Serverless::Function' Properties: CodeUri: PostNews Description: Post news text to convert from text to speech Events: PostNewsApi: Type: Api Properties: Path: /news Method: POST Policies: - Version: '2012-10-17' Statement: - Effect: Allow Action: - 'logs:PutLogEvents' - 'logs:CreateLogStream' - 'dynamodb:PutItem' - 'sns:Publish' Resource: '*'
- 가나다
- 가나다
"ConvertAudio" Lambda 함수 생성
- 가나다
- 가나다
- 가나다
- 가나다
- 가나다
- 가나다
- 가나다
"GetNews" Lambda 함수 생성
- 가나다
- 가나다
- 가나다
"DeleteNews" Lambda 함수 생성
- 가나다
- 가나다
- 가나다
S3 정적 컨텐츠 업로드
- 가나다
정적 웹 호스팅 파일 다운로드 받기
코드 블럭 language bash theme RDark linenumbers true wget https://s3.ap-northeast-2.amazonaws.com/polly.awsdemokr.com/301_static_web.zip
압축 풀고 폴더 이동
코드 블럭 language bash theme RDark linenumbers true unzip 301_static_web.zip cd 301_static_web
Cloud9에서 scripts.js 파일 열어서 CloudFormation Stack에 배포된 Output의 APIEndpointURL 값을 소스코드에 반영 (WebsiteURL이 아니므로 주의)
코드 블럭 language js theme RDark linenumbers true var API_ENDPOINT = "https://xxxxxxxxxx.execute-api.ap-southeast-1.amazonaws.com/Prod/news/"; if (API_ENDPOINT === "") { alert("scripts.js 파일의 상단에 API Gateway에 배포한 URL을 등록하고 실행하세요."); }
정적 웹 포스팅하고자 하는 S3 버킷에 public-read 권한으로 파일을 업로드 (CloudFormation Stack에 배포된 Output의 S3WebBucket 값을 아래에 대체)
코드 블럭 language bash theme RDark linenumbers true aws s3 sync . s3://cloud9-webapp-staticwebbucket-xxxxxxxxxxxx --acl public-read
- 웹 브라우저로 정적 웹 페이지에 접속 (CloudFormation Stack에 배포된 Output의 WebsiteURL 값을 웹 브라우저 주소창에 입력)
...