Category: 한국 기술 문서


AWS MobileHub로 안드로이드 앱 시작하기

이번 글에서는 어떻게 AWS 모바일 허브를 통해 빠르게 안드로이드앱을 만들 수 있는지 과정을 설명드리고자 합니다. 이를 통해 손쉽게 AWS 서비스를 연동하여 여러분의 iOS용 앱의 주요 기능과 통합 할 수 있게 될 것입니다.

문서 목차

  1. AWS MobileHub 소개 및 시작하기
  2. AWS MobileHub로 iOS 앱 시작하기
  3. AWS MobileHub로 안드로이드 앱 시작하기

이 글을 처음 읽으시는 분들은 앞의 두 가지 글을 미리 읽어 봐 주시면 이해하시는 데 도움이 되실 것입니다. AWS Mobile Hub 프로젝트를 생성하고, 마법사를 통해 AWS 서비스를 선택하는 부분은 기본적으로 동일합니다.

1. 안드로이드용 소스 패키지 생성

iOS 앱 시작하기 글에서 처럼 유저 사인인(User Sign-in)만 선택해서 안드로이드 용 앱 소스 패키지를 생성해 보겠습니다.

  • User Sign-in : Not Required.

유저 사인-인만 선택하고 나머지는 선택하지 않습니다. 이렇게 설정을 하게 되면, 유저 로그인시 다른 서비스(페이스북 등)를 통한 로그인은 하지 않게 되고 Cognito의 Unauthenticated identities를 이용해서 로그인하게 됩니다. 즉 특별한 로그인 인증 없이 앱기능을 실행하게 됩니다.

여기서 사용한 개발 도구는 안드로이드 스튜디오(AndroidStudio), 시뮬레이터는 제니모우션(Genymotion)을 세팅해서 사용했습니다. 안드로이드 소스 패키징은 기본적으로 그레이들(Gradle)을 사용해서 빌드가 되기 때문에 안드로이드스튜디오에서 사용하기 쉽습니다.

먼저 앱 실행을 해보도록 하겠습니다. 만약 안드로이드 스튜디오에 제니모우션 플러그인이 설치되어 있으면, 스튜디오 맨 상단 우측의 제니모우션 아이콘을 클릭해서, 원하는 디바이스를 우선 런치하도록 합니다.


[그림 1] 안드로이드스튜디오에서 제니모우션 실행

시뮬레이터가 뜬 이후에, 안드로이드 스튜디오 상단의 실행 버튼을 눌러 실행중인 애뮬레이터에 패키지를 배포합니다.


[그림 2] 에뮬레이터에 앱 실행

앞서 iOS와 동일한 화면 결과가 나옵니다. 설정에서 유저사인인만 선택했기 때문에, 그림 3와 같이 그에 해당하는 메뉴만이 리스트에 나오게 됩니다.


[그림 3] 유저사인인 화면

기능을 실행해보면, 게스트 계정으로 로그인을 해서 특별한 인증 없이 유저 아이덴터티 값을 가져오게 됩니다. 프로젝트가 생성되면서, 설정에서 선택된 기능에 해당하는 서비스가 자동으로 생성됩니다. 예를 들어 여기서 Cognito의 서비스가 생성되고, POOL_ID값도 자동으로 생성되는데, 소스 패키지에 이 값이 기본으로 포함되어 있습니다.


[그림 4] 안드로이드 소스 패키지 생성

이후에 빌드 단계에서 안드로이드를 선택해서 소스를 다운로드 하시기 바랍니다. 적절한 곳에 소스를 푼 후에 본인의 개발 도구에 프로젝트를 가져오기 하시기 바랍니다.

이제 생성된 소스의 구조를 살펴보도록 하겠습니다.


[그림 5] 프로젝트 구조

AWS 서비스와 관련된 클래스들은 amazonaws.mobile 패키지에 위치합니다. 설정 단계에서 서비스가 추가될 때마다 xxxManager가 추가됩니다.

데모 앱의 화면과 관련된 클래스들은 mysampleapp 패키지 안에 위치합니다. 역시 설정 단계에서 서비스가 추가될 때마다 데모용 화면이 추가되면서 클래스가 늘어나게 됩니다.

AWS 서비스와 관련해서 가장 기본적인 파일은 AWSConfiguration과 AWSMobileClient 입니다. 그림 5에서 보듯이 AWSConfiguration는 AWS 서비스 리소스의 아이덴터티를 포함하고 있습니다.

또한 AWSMobileClient는 앱의 부트스트랩을 담당합니다. 각종 서비스의 매니징 클래스를 생성하는 일을 담당하는 것입니다. 여기서는 IndentityManager만 입니다. 서비스가 추가되면 이 또한 늘어나게 됩니다.

2. 안드로이드용 데모 앱 실행하기

먼저 데모 앱 실행을 해보도록 하겠습니다. 만약 안드로이드스튜디오에 제니모우션 플러그인이 설치되어 있으면, 스튜디오 맨 상단 우측의 제니모우션 아이콘을 클릭해서, 원하는 디바이스를 먼저 런치하도록 합니다.


[그림 6] 안드로이드스튜디오에서 제니모우션 실행

시뮬레이터가 뜬 이후에, 안드로이드스튜디오 상단의 실행 버튼을 눌러 실행 중인 애뮬레이터에 패키지를 배포합니다.


[그림 7] 에뮬레이터에 앱 실행

앞서 iOS와 동일한 화면 결과가 나옵니다. 그림 8와 같이 설정에서 유저사인인만 선택했기 떄문에, 그에 해당하는 메뉴만이 리스트에 나오게 됩니다.


[그림 8] 유저 사인인 화면

메뉴를 클릭하여 기능을 실행해보면, 게스트 계정으로 로그인을 해서 특별한 인증 없이 유저 아이덴터티 값을 가져오게 됩니다.

프로젝트가 생성되면서, 설정에서 선택된 기능에 해당하는 서비스가 자동으로 생성됩니다. 예를 들어 여기서 Cognito의 서비스가 생성되고, POOL_ID값도 자동으로 생성되는데, 소스 패키지에 이 값이 기본으로 포함되어 있습니다.

3. 안드로이드용 데모 앱에 서비스 추가하기

우리는 현재 모바일에서 로그인 기능을 Amazon Cognito로만 연결한 기능을 테스트해보았습니다. 이제 몇 가지 기능을 추가하고 다시 소스 패키지 모습과 서비스 모습을 살펴보도록 하겠습니다. 프로젝트 이름은 SecondTestApp이라고 하겠습니다.

기본 설정에서는 다음과 같이 구성을 하겠습니다. 먼저 유저 사인인에서 페이스북으로 로그인하도록 설정합니다.


[그림 9] 페이스북 사인인 설정

여기서 페이스북 앱 아이디는 페이스북 앱을 만들어서 생성된 앱 아이디입니다. 참고로 페이스북에 앱을 생성한 후에, 플랫폼 추가를 선택해서 안드로이드의 경우 패키지 네임, 런치 화면 클래스 이름, 키 해쉬 값을 넣어 주어야 합니다. 보다 상세한 내용은 페이스북 개발자 문서를 참고하시기 바랍니다.


[그림 10] 페이스북 안드로이드 세팅

이렇게 생성한 이후에, 소스 패키지를 다운 받아서 실행해 보기 바랍니다. 처음 예제와 마찬가지 방법으로 앱 실행을 하면, 이번에는 페이스북으로 로그인하라는 화면이 나옵니다.


[그림 11] 페이스북 로그인 하기

에뮬레이터에서 키보드 타이핑이 안되는 경우가 있을 수 있습니다. 이 경우 에뮬레이터의 설정에서 키보드 입력의 Physical Keyboard Input을 OFF 로 설정하면 됩니다.


[그림 12] 에뮬레이터 키보드 설정 변경

로그인을 하면 각 기능별로 데모화면을 볼 수 있게 됩니다.


[그림 13] 서비스별 데모화면

유저 데이터 스토리지를 실행하면, 하나의 파일을 볼 수 있습니다. 이 파일은 프로젝트를 생성하면서 자동으로 생성된 S3 버킷에 존재합니다. AWS 콘솔에서 확인을 해보면 파일이 존재하는 것을 알 수 있습니다.


[그림 14] 자동으로 생성된 S3 버킷과 그 파일

각 서비스별로 실행을 해보면 그 상태를 서버에서 확인 할 수 있습니다.

소스코드의 변경을 살펴보겠습니다. 아래 그림을 보면 어떤 파일이 추가되었는지 비교해서 알 수 있습니다.


[그림 15] 변경된 프로젝트 구조

amazonaws.mobile패키지에 서비스 별로 필요한 패키지들이 추가된 것을 볼 수 있습니다. 물론 화면이 추가 되었기 때문에 mysampleapp에도 여러 클래스들이 추가된 것을 알 수 있습니다. 개별 클래스는 안드로이드 프로그래밍에 익숙한 분은 쉽게 파악할 수 있습니다.

지금까지 살펴봤듯이 모바일 허브를 통해 생성된 소스 패키지는 본인의 앱을 개발하는데 있어서 아주 좋은 출발점이 됩니다. 서비스를 생성하고, 그에 맞는 클라이언트 기능을 일일히 SDK를 이용해서 구현하는 것 보다 훨씬 쉽고 빠르게 초기 작업을 진행할 수 있습니다.

또한, AWS 서비스에 대한 비용만 지불하며, AWS Mobile Hub 사용에 대한 추가 요금은 없습니다. 각 AWS 서비스에서 사용한 만큼만 요금을 지불하면 됩니다.

어렵게만 생각한 AWS 모바일 클라이언트의 개발, 이제 손쉽게 시작해 보세요.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.

AWS MobileHub로 iOS 앱 시작하기

지난 AWS re:Invent 행사에서 AWS를 활용하는 모바일 개발자를 위한 모바일 허브(Mobile Hub)라는 새로운 서비스가 소개되었습니다.

이미 기존에 모바일을 위한 AWS 서비스는 많이 존재합니다. 인증 및 데이터 동기화를 위한 Amazon Cognito, 분석을 위한 모바일 분석(Mobile Analytics), 다양한 기기별 테스트를 위한 디바이스 팜(Device Farm), 푸시 서비스(SNS) 등이며, 이를 모바일 개발 환경 별로 AWS 모바일 SDK를 통해 제공하고 있습니다.

그러나, 모바일 SDK를 사용해서 프로그래밍을 하는 것은 기본 구조를 파악하고, 적용하기까지 몇 번의 시행착오를 거쳐서 하나의 시작 애플리케이션을 만들 수 있습니다. 통상 그 시간은 매우 짧지만 보다 편리한 방법을 찾는 것이 개발자의 본능이라고 생각합니다. 이러한 개발자의 편의를 위해 새롭게 발표한 서비스가 바로 AWS 모바일 허브라는 서비스입니다.

문서 목차

    1. AWS MobileHub 소개 및 시작하기
    2. AWS MobileHub로 iOS 앱 시작하기
    3. AWS MobileHub로 안드로이드 앱 시작하기

이번 글에서는 어떻게 AWS 모바일 허브를 통해 빠르게 iOS 앱을 만들 수 있는지 과정을 설명드리고자 합니다. 이를 통해 손쉽게 AWS 서비스를 연동하여 여러분의 iOS용 앱의 주요 기능과 통합 할 수 있게 될 것입니다.

우선 Mobile Hub 콘솔에 들어가서 프로젝트를 생성하고, 간단한 마법사를 통해 원하는 AWS 서비스를 선택하는 과정을 거치게 됩니다. 처음에 프로젝트 생성하는 과정은 AWS 모바일 허브 시작하기 글을 참고하시기 바랍니다.

1. iOS용 소스 패키지 생성

먼저 생성된 iOS앱 샘플 앱을 생성해 보도록 하겠습니다. 프로젝트 생성 마법사의 마지막 단계에서 “iOS”를 선택하고 “Build Your App”을 하시면 됩니다. 생성되는 소스 코드에 대한 정보는 소스 패키지 다운로드 단계에 존재하는 Discover, Develop를 보면 어떤 소스 코드를 수정해야 하는지 어떤 부분을 추가 개발해야 하는지 상세한 가이드가 제시됩니다.

[그림1] iOS의 샘플 앱 생성하기

한 가지 중요한 점은 샘플 코드에서 수정해야 할 주요 정보는 여러분이 실제로 사용할 AWS 서비스 정보입니다. 클라이언트 소스가 패키지 될 때 사용할 AWS 서비스(Cognito 또는 S3 버킷 등)가 같이 생성됩니다.

경우에 따라 생성된 프로그램에서 서비스에 필요한 정보를 수정하거나 변경할 필요가 있습니다. 예를 들어, 현재 베타 버전인 모바일 허브에서 생성된 서비스는 “us-east-1” 즉 버지니아 지역을 기준으로 생성됩니다. 만약 여러분이 Cognito 등을 기존에 사용하던 Identity Pool 정보라던가, 지역을 변경해서 새로 생성한 서비스로 연결하려면, 해당 ID 값들을 이용해야 합니다.

먼저 iOS의 프로젝트 구조를 살펴보도록 하겠습니다.


[그림2] iOS의 소스 패키지 구조

Demo 폴더에는 예제 실행이 가능한 각 화면들로 구성됩니다. 만약 여러분이 추가적으로 기능을 추가하면 그에 맞추어서 간단한 테스트를 할 수 있는 화면이 이 그룹에 추가됩니다. App 폴더 에는 앱의 가장 기본 파일들, AppDelegate나 Supporting Files가 기록됩니다.

AWS 서비스와 관련된 것은 AmazonAWS 폴더 입니다. 만약, 추가적으로 서비스 변경이 필요하다면 우선적으로 이 부분을 살펴보면 됩니다.

가장 먼저 보아야 할 부분은 AWSConfiguration.h이며, 그 다음에는 각 서비스 별로 그룹들이 추가됩니다. 통상 각 서비스에 대한 클라이언트 관리 클래스는 XXXManager라는 이름으로 구성됩니다. 여기서는 Identity 그룹에 AWSIdentityManager가 추가되어 있는 것을 볼 수 있습니다. AWSConfiguration.h를 살펴보면 그림3과 같습니다.


[그림 3] AWSConfiguration.h

여기에는 기본적으로 Amazon Cognito에 대한 POOL_ID 정보가 나와 있습니다. 만약 설정 단계에서 S3 스토리지나, 모바일 분석 서비스를 추가적으로 선택하면 Analytics의 앱 아이디나, S3의 버킷 이름이 추가적으로 나타나게 됩니다. 서비스를 추가하는 것은 이후에 살펴보도록 하겠습니다.

2. 데모 애플리케이션 실행하기

Xcode에서 Product에서 Run을 실행해서 데모앱을 실행해보면 아래와 같은 데모앱이 실행됩니다.


[그림 4] 데모 앱 실행화면

“User Sign-in”을 눌러보시면, Amazon Cognito를 통해 게스트(Guest)로 자격 증명을 얻은 것을 보실 수 있습니다. Amazon Congito를 통한 서비스에는 “프로젝트명_MOBILEHUB_번호” 형식으로 서비스가 생성된 것을 확인할 수 있습니다. 그 서비스를 클릭하고 들어가면, 그림 4처럼 앞서 게스트로 로그인해서 Identities의 s숫자가 증가된 모습을 볼 수 있습니다.


[그림 4] Amazon Cognito 서비스 화면

여기서 한 가지 점검할 사항이 있습니다. 만약 컴파일을 했는데, 그림 5처럼 “Illegal Configuration” 에러가 보인다면, 현재 Xcode버전이 7.0 이상인지를 꼭 확인해 보시기 바랍니다.


[그림 5] Xcode 7 미만 버전에서의 에러메시지

3. 데모 앱에 AWS 서비스 추가하기

Amazon Cognito로  Guest 로그인 기능만 있는 것에 몇 가지 기능을 추가하고, 다시 한번 소스 패키지 모습과 서비스 모습을 살펴보도록 하겠습니다. 새 프로젝트 이름은 SecondTestApp이라고 하겠습니다.

새 설정에서는 User sign-in 부분을 페이스북으로 로그인하도록 설정합니다.


[그림 6] 페이스북 로그인 설정

여기서 페이스북 앱 아이디는 페이스북 앱을 만들어서 생성된 앱 아이디입니다. 먼저, 페이스북에 앱을 생성한 후에, “플랫폼 추가”를 선택해서 iOS의 경우 번들 아이디를 넣어 주어야 합니다. 보다 상세한 설정 방법은 페이스북 개발자 문서를 참조하시기 바랍니다.

다음에는 사용자 데이터 스토리지와 모바일 분석, 클라우드 로직을 차례로 설정합니다.

  • User Data Storage : Store user data
  • App Analytics : Add analytics
  • Cloud Logic : Enable Logic

클라우드 로직의 경우에는 [그림 7]과 같이 예시적으로 나와있는 기본 AWS Lambda 함수를 모두 선택합니다.


[그림 7] 클라우드 로직 설정

이렇게 하고 소스 패키지를 생성한 이후에, 다운로드 받아서 Xcode로 열어보시기 바랍니다. Demo 폴더에는 화면이 더 추가되었고, AmazonAWS 그룹에도 서비스 이름이 더 추가된 것을 알수 있습니다.


[그림 8] 기능 추가 소스 패키지 프로젝트 구조

이제 실행을 시키면 먼저 페이스북 로그인 화면이 나타납니다. 여기서 본인의 페이스북 아이디로 로그인을 하면 첫번째 데모 화면이 나타납니다.


[그림 9] 추가된 서비스 데모 앱 화면

만약 유저 데이터 스토리지를 누르면  예제 파일을 다운로드 할 수 있습니다. 여기서 보이는 example-image.png파일은 어디에 존재하는 것일까요? 이것은 프로젝트에서 설정에 스토리지를 추가했기 때문에 자동으로 생성된 S3 버킷에 존재합니다.


[그림 10] S3의 샘플 이미지 다운로드

변경된 AWSConfiguration.h 내용을 살펴보도록 하겠습니다. 모바일 분석와 S3 버킷 이름이 추가된 것을 확인 할 수 있습니다.


[그림 20] 변경된 AWSConfiguration.h

새로 만들어 진 데모 앱 화면에서 다른 기능도 사용해 보시고, 여러분이 가진 AWS 자원으로 직접 연결하셔서 기본 기능을 수행해 보실 수 있습니다.

지금까지 살펴 보신 것과 같이 단일 콘솔을 사용하여 모바일 허브를 사용하면 AWS 서비스에서 구동되는 모바일 앱을 쉽게 개발할 수 있습니다. 샘플 앱을 새로 만들 앱의 기반으로 사용하거나, 코드 스니핏을 잘라내어 여러분의 앱에 삽입하여 서비스를 개발 할 수 있습니다.

또한, AWS 서비스에 대한 비용만 지불하며, AWS Mobile Hub 사용에 대한 추가 요금은 없습니다. 각 AWS 서비스에서 사용한 만큼만 요금을 지불하면 됩니다.

어렵게만 생각한 AWS 모바일 클라이언트의 개발, 이제 손쉽게 시작해 보세요.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.

AWS 한국어 설명서 목록

Amazon Web Services 설명서는 AWS를 처음으로 사용하는 사용자 부터 고급 사용자까지 각 서비스 소개로부터 고급 기능에 이르기까지 유용한 정보를 담고 있습니다. 지금까지 주로 영어로 제공되던 문서를 한국어로도 보실 수 있습니다. (우선 한국어로 제공 가능 한 것 부터 공유해 드리며, 앞으로 순차적으로 업데이트할 것을 약속드립니다.)

AWS 시작하기

컴퓨팅 서비스

네트워크 서비스

스토리지 서비스

데이터베이스 서비스

보안 및 인증 서비스

애플리케이션 서비스

요금 및 빌링 관리 서비스

더 자세한 것은 AWS 설명서를 참고해 주시기 바랍니다.

Amazon S3 멀티 파트 다운로드 이용하기

Amazon S3는 내구성 및 확장성을 요구하는 업무에 활발하게 이용되고 있는 오브젝트 스토리지입니다. 현재까지 꾸준히 기능이 추가 및 개선되고 있으며, AWS 모든 서비스의 맏형격으로 다양한 워크로드와 서비스들의 중앙에 위치해서 정적인 멀티미디어 컨텐츠부터 로그 데이터 저장, 백업과 아카이빙, 빅데이터 분석 및 재난 복구 등을 위해 널리 활용되고 있습니다.

Amazon S3에 저장된 오브젝트는 HTTP/HTTPS프로토콜을 통해 일반적으로 인터넷을 경유해서 이동하게 됩니다. 작은 크기의 파일은 짧은 시간 내에 전송되겠지만, 큰 크기의 파일을 하나의 작업으로 전송하는 것은 시간적인 측면에서 이용자에게 적잖은 부담으로 남게 됩니다. AWS는 하나의 큰 오브젝트를 Amazon S3상에 빠르게 올릴 수 있는 방법을 제공하고 있습니다.

일명 멀티파트 업로드. 기본적으로 Amazon S3에 단일 작업으로 올릴 수 있는 객체 크기는 최대 5GB입니다. 따라서 5GB보다 큰 오브젝트는 멀티파트 업로드를 반드시 이용해서 업로드해야하며, 최대 5TB 크기 오브젝트를 업로드할 수 있습니다.

일반적으로 오브젝트 크기가 100MB를 넘게되면 멀티파트 업로드를 권장하며, 멀티파트 업로드 API를 이용해서 큰 오브젝트를 여러 조각으로 나눠서 병렬적으로 빠르게 업로드 할 수 있습니다. 또한 AWS 명령줄 인터페이스를 이용하여 쉽게 멀티 파트 업로드할 수 있는 환경도 제공하고 있습니다.

그러면, Amazon S3상에서 있는 큰 크기의 오브젝트를 내려받는 것은 어떨까요? 아마도 ‘멀티파트 다운로드할 수 있는 API를 동일하게 제공하겠지?’라고 생각할 수 있습니다. 하지만 멀티파드 업로드 API처럼 오브젝트를 간편하게 멀티파트로 다운로드하는 API는 존재하지 않습니다. 다행히 AWS 명령줄 인터페이스의 s3 cp명령은 사용자에게 투명하게 오브젝트를 멀티파트로 내려받을 수 있도록 설계되어있습니다.

$ time aws s3 cp s3://shared/sample.zip sample.zip
download: s3://shared/sample.zip to ./sample.zip
real       3m46.765s
user       0m18.265s
sys        0m10.454s

기본적으로8MB 크기로 구성된 파트들로 멀티파트 다운로드하게 되며, 아래 예처럼 aws 명령줄 인터페이스 구성파일(~/.aws/credentials)을 수정해서 사용자화할 수 있습니다.

[profile development]
aws_access_key_id = xxxxxxxxxxxxxxxxxxxx
aws_secret_access_key = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
max_concurrent_requests = 20
max_queue_size = 10000
multipart_threshold = 64MB
multipart_chunksize = 16MB

이 블로그 포스팅의 목적은 AWS 명령줄 인터페이스의 s3명령을 통해서 멀티 파트 다운로드 받는 방법을 소개하려는 것은 아닙니다. 사용자가 직접 간단하게 구현할 수 있는 멀티 파트로 다운로드 방법을 소개하고자 합니다. 이 방법을 이용하면 자신만의 코드로 작성된 앱 내에서도 멀티 파트 다운로드를 간단히 구현할 수 있고, 경우에 따라서는 이어받기 기능까지 응용할 수 있습니다.

원리는 W3 표준인 RANGE GET를 활용하는 것입니다. AWS에서 제공하는 GET Object REST API를 이용해서 RANGE 헤더를 사용할 수 있고, AWS 명령줄 인터페이스의 s3api 명령을 이용해서도 RANGE 헤더를 사용할 수 있습니다.

아래는 두번째 방법인 AWS 명령줄 인터페이스의 s3api 명령을 사용해서 멀티파트 다운로드 스크립트를 간단히 구현해 보고, 멀티파트 다운로드에 대한 기본 아이디어와 실제로 다운로드 속도가 어느정도 개선되는지 살펴보도록 하겠습니다. (참고로 AWS 명령줄 인터페이스에서 내부적으로 투명하게 제공되는 멀티파트 다운로드 기능은 s3 명령에서만 지원되고, s3api 명령에서는 지원되지 않습니다.)

사전 준비 사항
스크립트를 작성하기 위해서는 아래 AWS 명령줄 인터페이스가 준비되어야 합니다. AWS 명령줄 인터페이스는 여기를 클릭하시면 다운로드 받을 수 있으며, 설치 가이드와 사용법도 확인할 수 있습니다.

스크립트 작성하기
위 선행 작업이 완료되었다면, 이제 스크립트를 작성할 준비가 되었습니다. 멀티파트 다운로드 스트립트의 작업 순서를 아래와 같이 아주 단순합니다:

  1. 다운로드 하려는 S3 상의 오브젝트 크기 확인
  2. 사용자가 원하는 분할 개수에 맞도록 파트 크기 계산
  3. RANGE GET을 이용해서 오브젝트의 파트들을 병렬적으로 다운로드
  4. 모든 파트들이 다운로드 될 때까지 대기
  5. 다운로드된 모든 파트들을 하나로 묶기

우선 특정 버킷내에 있는 오브젝트 목록 및 속성을 얻는 명령을 알아보도록 하겠습니다. 이는 첫번째 단계인 오브젝트 크기를 확인하는데 사용됩니다. AWS 명령줄 인터페이스의 s3api list-objects 명령을 이용하면 오브젝트에 대한 속성을 알 수 있습니다. 아래는 shared 버킷내에 있는 모든 오브젝트의 정보를 얻을 수 있는 예입니다.

$ aws s3api list-objects –bucket shared

하지만, 실제로 필요한 값은 원하는 특정 오브젝트의 크기 정보입니다. 이는 --query 옵션을 통해서 가능하고, 오브젝트 이름은 Key, 크기는 Size 속성으로 참조할 수 있습니다. 아래 명령줄을 통해서 shared 버킷 내에 있는 sample.zip 오브젝트에대한 크기만 추출해보겠습니다.

$ aws s3api list-objects --bucket shared --query "Contents[?Key==`sample.zip`]|[0].Size"

위 명령어에서 `sample.zip`을 둘러싸고 있는 것은 백쿼터(`…`)인 것에 유념해야 합니다. 그리고 파이프 연산자를 이용해서 파이프 앞에 있는 쿼리 결과를 뒤로 전달하도록 하였으며, [0].Size를 통해서 오브젝트 크기만 추출합니다.

위에서 얻은 오브젝트의 크기를 분할하고 싶은 파트 개수로 나누게 되면 각 파트의 크기를 얻을 수 있습니다. 그리고 W3 표준인 RANGE GET에서 소개된 형식을 바탕으로 각 파트의 순서에 맞도록 BYTE RANGE 연산자를 활용하여 다운로드할 각 파트의 바이트 범위를 명시합니다. AWS 명령줄 인터페이스에서는 --range 옵션을 사용합니다. 아래는 몇가지 사용 예입니다:

$ aws s3api get-object --bucket shared --key sample.zip --range bytes=0-33554431 sample.zip.part.1

위 예는 sample.zip 오브젝트의 첫번째 파트입니다. 파트 크기를 첫 바이트부터 총 32MB(bytes=0-33554431) 크기로 내려받아서 sample.zip.part.1로 저장합니다.

$ aws s3api get-object --bucket shared --key sample.zip --range bytes=33554432-67108863 sample.zip.part.2

sample.zip 오브젝트의 두번째 파트는 이후 두번째 32MB(33554432-67108863)를 내려받아서 sample.zip.part.2에 저장합니다.

$ aws s3api get-object --bucket shared --key sample.zip --range bytes=268435456- sample.zip.part.9

그리고 sample.zip 오브젝트의 마지막 파트 부분으로 나머지 부분을 모두 받게 됩니다. 위 예는bytes=268435456-으로 표현되어 있는데요, 256MB지점부터 끝까지 내려받아서 sample.zip.part.9에 저장한 예입니다.

BASH 쉘 상에서 내려받는 명령어들은 모두 백그라운드로 수행시켜서 병렬로 다운로드 받게합니다. 그리고 이런 백그라운드 프로세스들이 모두 종료될 때까지 wait(1) 명령어를 이용해서 대기합니다.

끝으로 모든 파트를 다운로드하면 파트 순서에 맞춰서 한 파일로 함께 연결하면 됩니다.

지금까지 스크립트를 구성하는 주요 내용에 대해 설명드렸습니다. 아래 스크립트는 앞서 설명드린 내용들을 기반으로 작성한 간단한 bash 쉘 스크립트입니다.

#!/bin/bash
#
[ $# -ne 6 ] && exit 1

while getopts ":b:k:s:" OPT; do
  case $OPT in
    b)
      BUCKET=$OPTARG
      ;;
    k)
      KEY=$OPTARG
      ;;
    s)
      SPLIT=$OPTARG
      ;;
    *)
      echo "Invalid option: -$OPTARG" >&2
      exit 2
      ;;
  esac
done

# MAIN
readonly THRESHOLD_PART_SIZE=8388608   # 8MB (8*1024*1024)
readonly TMP_DIR="./tmp.$$";

OBJECT_SIZE=$(aws s3api list-objects --bucket $BUCKET --query "Contents[?Key==\`${KEY}\`]|[0].Size")

let PART_SIZE=OBJECT_SIZE/SPLIT
[ $PART_SIZE -lt $THRESHOLD_PART_SIZE ] && echo "Part size is $PART_SIZE. Each part size except last one must be larger than $((${THRESHOLD_PART_SIZE}/1024/1024))MB" &&  exit 3
[ ! -d "${TMP_DIR}" ] && mkdir ${TMP_DIR}

I=1
START=0
let END=PART_SIZE-1
while [ $I -le $SPLIT ]
do
   aws s3api get-object --bucket $BUCKET --key $KEY   --range bytes=${START}-${END}  ${TMP_DIR}/${KEY}.${I} > /dev/null 2>&1 &
   let I=I+1
   let START=START+PART_SIZE
   let END=END+PART_SIZE; [ $I -eq $SPLIT ] && END=''
done

wait > /dev/null 2>&1

[ -f $KEY ] && rm $KEY
I=1
while [ $I -le $SPLIT ]
do
   cat ${TMP_DIR}/${KEY}.${I} >> $KEY
   let I=I+1
done
rm -rf $TMP_DIR

스크립트의 간결성을 유지하기 위해서 대부분의 에러처리 루틴을 배제하였습니다. 따라서 범용적으로 사용하기 위해서는 적절한 에러 처리 루틴들이 추가되어야 하고 충분한 테스트를 거친 후 사용하시길 권장합니다.

아래 두 예는 S3에 저장된 약 700MB sample.zip 파일을 위 스크립트를 활용해서 20개로 나눠 다운로드했을 때와 한번의 작업으로 다운로드 받을 때의 결과를 보여주고 있습니다.

$ time ./s3md.sh -b shared -k sample.zip -s 20
real       2m12.268s
user       0m26.010s
sys        0m11.952s

700MB의 단일 파일을 20개로 나눠서 받았을 때, 약 2분 12초 정도 시간이 소요되었습니다. 그리고 이어지는 AWS 명령줄 인터페이스는 단일 작업으로 해당 오브젝트를 내려받는 결과입니다.

$ time aws s3api get-object --bucket shared --key sample.zip sample.zip > /dev/null
real       4m17.417s
user       0m19.199s
sys        0m9.284s

단일 작업으로 다운로드 하였을 경우 약 4분 17초정도 소요되었습니다. 위 예에서는 멀티 파트로 다운로드 받을 경우 약 50%정도의 시간이 단축된 것을 확인할 수 있었습니다. 다만 고려 해야 할 것은 인터넷 환경 및 클라이언드 환경에 따라 위 결과와 다르게 나올 수 있습니다.

끝으로 Amazon S3상에서 큰 데이터를 자주 조작 하시는 IT팀이나 앱 내에서 S3로 파일을 주고 받아야 하는 경우, 오늘 소개해드린 멀티 파트 다운로드 방법이 조금이라도 아이디어를 제공해드렸기를 기대해봅니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박철수 솔루션즈 아키텍트께서 작성해주셨습니다.

2015년 10월 AWS 최신 보안 뉴스

re:Invent 보안 및 규정 준수 세션 동영상 공개

지난 10월 6일-9일간 라스베가스에서 열린 AWS re:Invent 2015에서는 Security & Compliance 트랙의 다양한 세션이 발표 되었습니다. 모든 세션은 동영상으로 제공하고 있으니 참고하시기 바랍니다.

동영상 목록 바로 가기 →

 

특정EC2 인스턴스에 대한 접근을 단일 VPC안으로 제한하기

고객들이 클라우드 기술 지원 엔지니어에게 종종 다음과 같은 질문을 합니다. “어떻게 하면 사용자의 EC2인스턴스 접근 범위를 단일 VPC 내로 제한할 수 있나요?” 본 포스팅에서는 해당 질문에 대해 AWS IAM 정책과 Role을 이용하여 접근 레벨을 제한하는 방식을 통해 해답을 제시합니다.

EC2 상에서, 사용자의 인스턴스 접근을 단일 VPC로 제한하기 위해서는 아래와 같은 2개의 질문들을 고려해야만 합니다.

  • 어떤 API 액션들이 Amazon Resource Names (ARNs) 과 조건들을 지원하는가?
  • 어떤 API 액션들이 ARNs과 조건들을 지원하지 않는가?

리소스 레벨의 퍼미션을 같는 API 액션은 IAM정책의 Resource 엘리먼트 내 ARN에 대한 지원을 갖습니다. 다음 링크에서 EC2 리소스 레벨 퍼미션에 대한 기본 정보를 확인할 수 있습니다(Demystifying EC2 Resource-Level Permissions). 또한 Supported Resource-Level Permissions for Amazon EC2 API Actions 문서에서는 ARN을 지원하는 EC2액션의 전체 목록이 있습니다. 그 목록에서는 어떤 조건이 어떤 ARN에 적용될 수 있는지도 보여줍니다.

자세히 읽기 →

신규 출시: AWS 보안 교육 클래스

보안과 관련된 새로운 AWS 교육 커리큘럼을 시작합니다. 보다 안전한 AWS 아키텍쳐를 만들고 주요 컴플라이언스 요건들을 충족 시킬 수 있는 방법들을 제시하면서, AWS 공유 책임 모델 상에서 여러분들의 클라우드 보안 목표를 달성할 수 있도록 디자인 된 2개의 교육 과정이 제공됩니다.

신규 클래스에 대한 좀 더 자세한 내용은 아래와 같습니다.:

  • AWS Security Fundamentals: 3시간짜리 무료 온라인 클래스로서 기본적인 클라우드 컴퓨팅 소개와 AWS 접근제어, 거버넌스, 로깅, 암호화 방법 을 포함하여 AWS의 보안 개념을 소개합니다. 본 교육과정은 AWS를 전혀 접해보지 못했거나 조금 경험 해보신 보안 담당자들을 주요 대상으로 하며 보안과 관련된 컴플라이언스 규정들, 리스크 관리 전략, AWS보안 인프라를 감사하는 절차 등을 교육합니다.
  • Security Operations on AWS: 3일동안 교육장에서 시행되는 본 교육은 AWS서비스의 보안 기능들과 데이터나 시스템들을 안전하게 관리하기 위한 베스트 프랙티스들을 자세하게 다룹니다. 여러분들은 규제나 컴플라이언스 기준들과 AWS 상의 워크로드 감사에 대한 실 사례들에 대해 배우게 되실 것입니다. AWS보안 제품과 기능들을 통해 다음단계로 보안 운영 레벨을 높이는데 도움을 줄 핸즈 온 연습과정도 포함됩니다.

본 교육 과정에 대해 좀 더 자세히 아시려면 AWS Training를 방문해 보세요. 여기(find a class )에서 교육 과정에 대한 상세 내용을 찾아 보실 수 있습니다.

빠르게 보안 베스트 프랙티스 준수하기 위한 두 가지 팁

보안 전문가에게는 베스트 프랙티스을 잘 준수하고 있는 지를 확인하는 것이 주요 임무입니다. 베스트 프랙티스를 준수하는 일은 단순하고 지루한 수작업을 통해 많은 시간이 필요하게 됩니다. 본 글에서는 과도한 시간 소비를 줄이면서 보안 베스트 프랙티스들을 AWS서비스들을 통해 어떻게 구현할 수 있는지에 대한 2개의 예제를 보여줍니다.

AWS Identity and Access Management (IAM) 베스트 프랙티스는 엑세스 키를 주기적으로 교체하거나 삭제하는 것과 관련됩니다. 그러나 어떤 엑세스 키가 사용되었는 지를 찾는 다는 것은 보통 AWS Cloud Trail 로그를 면밀하게 뒤져본다는 뜻입니다.

지난 5월 30일자 웨비나 (webinar)에서 소개되었던, 최근 사용된 엑세스키 기능(access key last used)을 이용하면 키 교체 작업을 좀더 쉽게 할 수 있습니다. 마지막으로 사용된 일자와 IP주소를 알게 되면, 어떤 키가 어디에 사용되었는지 좀더 쉽게 파악할 수 있습니다. 여러분들은 또한 엑세스 키가 오랫동안 사용된 적이 없는 것도 파악 할 수 있습니다; 삭제되었거나 오래된 사용하지 않는 엑세스 키들을 잘 관리할 수 있는 좋은 보안 태도를 유지하는데 도움을 줍니다.

자세히 읽기 →

민감한 S3버킷에 대한 접근 허용 Whitelist 정책 만들기

Amazon S3 버킷에 대한 안전한 접근을 위해 AWS는 다양한 옵션들을 제공합니다. 여러분들은 access control lists (ACLs), AWS Identity and Access Management (IAM) 사용자 정책이나 S3 엑세스 정책 등을 이용할 수 있습니다. S3엑세스 정책 내에서도 몇가지 옵션들을 선택할 수 있습니다. 여러분들은 Principal 엘리먼트 를 활용하여, 디폴트 정책이 Deny인 AWS Account목록에 대한 접근을 허용할 수도 있습니다. 또한 Principal 엘리먼트의 형제 요소인 NotPrincipal 엘리먼트를 가지고, 명시적으로 몇몇 지정된 사용자 외 어느 누구도 특정 리소스에 접근할 수 없도록 할 수 있습니다.

본 글에서는 어떻게 NotPrincipal엘리먼트를 통해 이런 민감한 S3버킷에 대한 엑세스 정책을 만들 수 있는지 보여드립니다.

자세히 읽기 →

접근 제어 정책을 테스트를 위한 신규 API 소개

AWS Identity and Access Management (IAM)은 여러분들이 IAM사용자, 그룹, 그리고 역할에 대한 퍼미션을 검증하고 감사하기 위한 신규 API을 발표했습니다. 이와 같은 2가지 API를 CLI나 SDK 형태의 IAM policy simulator를 활용할 수 있습니다.

새로운 iam:SimulatePrincipalPolicy API 를 가지고, 프로그램적으로 IAM정책이 의도된 대로 동작하는지, 특정 리소스 나 액션 별로 테스트할 수 있습니다. 신규 작성된 정책이나 갱신된 기존 정책을 iam:SimulateCustomPolicy API 를 호출하여 테스트 할 수 도 있습니다.

본 포스팅에서는 iam:SimulatePrincipalPolicy API를 사용하여 특정 사용자의 퍼미션을 검증합니다. 이 API는 목적하는 시뮬레이션의 타입에 대응하는 정책들을 포함하는 몇가지 파라메터들을 갖습니다.

자세히 읽기 →

9월의 AWS 보안 뉴스는 AWS코리아의 보안 분야 솔루션 아키텍트로 일하시고 있는 임기성님께서 작성해 주셨습니다.

공격 지점을 줄여서 DDoS 공격 대비하기

DDoS(Distributed denial of service) 공격은 악의의 공격자가 감당할 수 없는 규모의 트래픽이나 커넥션 요청을 네트웍, 시스템, 어플리케이션에 전송함으로서 야기됩니다. 예상하신 대로 AWS 고객도 어떻게 하면 이런 종류의 공격으로 부터, 어플리케이션을 보호할 수 있는지 많이 질문합니다. AWS에서는 여러분이 DDoS 상황에서도 복원력이 높은  아키텍쳐를 만드는 방법과 어떻게 AWS 확장성을 잘 활용할 수 있는지에 관한 베스트 프랙티스를 제공하고 있습니다.

먼저 최근에 공개한 AWS Best Practices for DDoS Resiliency(영문 백서)를 보시면 어플리케이션 가용성을 보호하고, DDoS 공격에 좀 더 잘 대비하기 위한 참고 아키텍쳐를 잘 알 수 있습니다. 이 글에서는 그 중에서도 공격을 방어하기 입장에서 공격받을 지점을 줄이는 사례를 좀 더 자세히 공유해 드리겠습니다.

간단히 설명하자면, 어플리케이션에 도달할 수 있는 가능한 트래픽의 유형을 줄이는 것을 뜻합니다. 간단한 예로 웹어플리케이션을 만들때, 인터넷으로 80과 443 포트만을 오픈하는 것입니다. 이를 통해서 DDoS 공격에 흔히 사용되는 다양한 공격 기법들을 막을 수 있습니다.

이 글에서는 Amazon Virtual Private Cloud (VPC) 를 활용하여 여러분들의 어플리케이션에 대한 접근을 어떻게 통제할 수 있는지, 네트웍 접근제어목록(network access control lists (ACLs))과 보안그룹(security groups)을 통해 공개된 통로를 어떻게 최소화 할 수 있는지 등에 관한 내용을 다룹니다. 이 내용들은 여러분들이 DDoS 복원 아키텍쳐(DDoS-resilient architecture)를 구축 할 때 고려하셔야 하는 몇 가지 베스트 프랙티스 중에 일부입니다.

통상적인 DDoS 공격

AWS VPC에 관한 내용을 시작하기 앞서, DDoS 공격 기법에 어떤 것들이 있는지 이해하고 전송되는 위해 트래픽을 막도록 어떻게 공격 지점을 최소화 할 수 있는지를 이해하는 것이 중요합니다. 가장 흔한 DDoS 공격기법은 반사공격(reflection attack)으로서, 네트웍이 감당할 수 없는 트래픽의 양을 생성하여 정상적인 트래픽을 처리하지 못하도록 하는 것입니다. 반사공격(reflection attack)을 시작하려면, SSDP(Simple Service Discovery Protocol)나 DNS(Domain Name System), NTP(Network Time Protocol), SNMP(Simple Network Management Protocol)과 같은 UDP(User Datagram Protocol)서비스를 제공하는 인터넷 서버들을 스캐닝하게 됩니다.

그리고 대부분 이와 같은 서버들은 구성에 따라, 원 요청보다 큰 결과를 반환하게 됩니다. 이러한 부분을 이용하는 것을 증폭 공격(Amplification Attack)이라고 하며, 이 두 가지 기법을 이용하여 공격자가 소스 IP를 공격 대상 IP로 임의로 변경하여 많은 요청들을 해당 서버들에게 보내게 되면, 10배 혹은 수백배 큰 응답들이 공격 대상에게 전달되어 정상적인 서비스를 방해하도록 하는 것입니다.

아래 그림1은 공격자가 어떻게 요청을 변조하여 DDoS반사/증폭(Reflection/Amplification)공격을 희생자에게 전송시키는지를 보여줍니다.


그림 1. Distributed reflection denial of service attack

보안 그룹 구성

반사공격(Reflection attack) 기법을 통해 공격자들은 전세계 어느 곳으로도 통상적인 UDP서비스를 이용하여 대규모 트래픽을 보낼 수 있게 됩니다. 다행히 이러한 공격들은 쉽게 탐지될 수 있고, AWS의 VPC에 있는 보안그룹(Security Group) 구성을 통해 감소시킬 수 있습니다. 이 기능은 여러분들의 인스턴스에 대한 인바운드, 아웃바운드 통신에서 허용할 포트나 프로토콜을 지정해서 통제할 수 있도록 해줍니다. 지정되지 않는 다른 포트나 프로토콜은 자동으로 접근이 불허됩니다.

아래 그림에선 앞에서 언급했던 웹 어플리케이션에 적용할 수 있는 Amazon VPC레퍼런스 아키텍쳐를 보실 수 있습니다. 좀 더 자세한 내용은 여기를 참조하시기 바랍니다. Security Groups for Your VPC.


그림 2. Reference architecture with Amazon VPC configuration

위의 아키텍쳐에서는 한 개의 퍼블릭 서브넷과 두 개의 프라이빗 서브넷으로 구성된 VPC를 사용합니다. 위 구성을 위해 몇 가지 보안 그룹(Security Group)을 정의해야 하는데, 우선 일반 사용자와 관리자가 인터넷을 통해 접근할 수 있도록 허용하는 것과 내부 리소스들을 DMZ로 부터만 접근이 가능하도록 제한하는 방법이 있습니다. VPC를 만들고 접근을 제한하는 것과 관련된 자세한 내용은 링크를 참조하시기 바랍니다. Your VPC and Subnets.

SSH bastion security group

SSH bastion 서버는 오로지 관리자만이 SSH를 사용하여 접근할 수 있도록 제한하기 위해 하나의 EC2인스턴스에 구성됩니다. 이를 통해 관리자는 TCP 22번 포트를 통해 인터넷이나 허용된 IP로부터 접근할 수 있게 됩니다. SSH bastion으로 접근한 뒤, 관리자는 웹어플리케이션 서버나 MySQL서버로 접근할 수 있습니다. 22번 포트에 대한 DDoS 공격을 받게 되면 SSH 서비스에 대한 부분만 지장을 받게 됩니다. 이로 인해, 공격자가 이 포트를 통해서 어플리케이션에 영향을 주려는 시도가 차단됩니다. 불법적인 접근을 최소화 하기 위해서는, SSH bastion의 보안그룹에 여러분 네트웍의 공용IP만 허용해주는 게 필요합니다. 다음 테이블은 SSH Bastion의 보안그룹을 설정할 때 참조할 수 있는 사례입니다.

ELB 보안 그룹

Elastic Load Balancing (ELB)는 EC2 인스턴스 장애에 대비하여 자동으로 인바운드 트래픽을 라우팅해 줍니다. ELB는 웹 어플리케이션 앞단에서 위치하여 공격받을 수 있는 부분을 줄여주게 되고, 자동으로 용량에 따라 스케일링 해 줍니다. 게다가, ELB는 웹어플리케이션으로 잘 정의된(유효한) 트래픽만 전달하도록 만들어져 있습니다. 이 기능을 통해 DDoS에 저항력 있는 레이어를 부가적으로 구성할 수 있습니다. 사용자가 여러분의 웹어플리케이션으로 접근할 수 있도록 하기 위해선, 우선 인터넷으로부터 80과 443포트를 통해서 만 접근 가능 하도록 하고, 그 다음 각 요청이 웹어플리케이션들이 운영되는 EC2인스턴스로 잘 분배될 수 있도록 보안그룹 설정을 합니다. 다음 테이블은 ELB 보안 그룹을 설정하는데 참조할 만한 규칙을 보여줍니다.

NAT 보안 그룹

본 사례에서, 웹어플리케이션 서버와 MySQL서버는 프라이빗 서브넷에 위치하는데, 이로 인해, 직접적으로 인터넷과 통신할 수 없습니다. ELB를 통해서 서비스하는 부분과는 별개로, 소프트웨어 업데이트 등을 위해 인스턴스가 인터넷과 연결되어야 할 필요가 있습니다. 이를 위해, 고유의 보안그룹을 갖는 network address translation (NAT) 인스턴스를 구성하게 됩니다. NAT 인스턴스를 통해, 프라이빗 서브넷에서 인터넷으로 나가는 아웃바운드 통신을 라우팅할 수 있게 됩니다.자세한 내용은 NAT Instances. 를 참조하시기 바랍니다.

웹 어플리케이션 보안그룹

이 보안 그룹은 모든 웹어플리케이션이 올라가 있는 EC2인스턴스들의 설정에 대한 내용입니다. 이들 인스턴스들은 ELB로부터 오는 웹 요청들만 받아 들이게 됩니다. 공격 지점의 최소화를 위해, 이들 인스턴스에는 VPC 써브넷 IP 범위에서 할당되는 사설 IP만이 부여되어 인터넷으로부터의 직접적인 접근을 막아 주게 됩니다. 그 대신, ELB로부터의 TCP 포트 80, 443과 관리자의 접근을 위한SSH 22번 포트 접근만이 허용됩니다. 다음 테이블은 웹어플리케이션을 위해 보안 그룹을 설정할 때 참조하면 좋습니다.

MySQL 데이터베이스 서버보안 그룹

지금까지와 유사하게 생각해서, MySQL 데이터베이스 쪽은 오로지 웹어플리케이션이 올라가 있는 EC2인스턴스로부터의 접근만을 허용해 주게 됩니다. 이를 위해, MySQL 데이터베이스를 사설 서브넷 상에 두고 사설 IP를 할당하고, 웹 어플리케이션이 올라가 있는 EC2인스턴스로부터의 TCP포트 3306 트래픽만을 받아 들이도록 설정하게 됩니다. 아래 테이블은 MySQL서버를 위한 보안그룹 설정을 보여줍니다.

네트웍 ACL 구성하기

네트웍ACL을 통해, 상용 방화벽과 유사하게, 우선순위가 할당된 Allow, Deny 규칙을 생성하여 VPC를 보호하게 됩니다. 이것은 EC2 인스턴스 수준에서 트래픽을 허용할 지를 결정하는 보안그룹과는 다르게, 서브넷 레벨에서 Allow, Deny 규칙을 설정할 수 있도록 해줍니다.예를 들어, 원하지 않거나 악용될 수 있는 인터넷 IP 주소 혹은 범위를 규정하려면, 어플리케이션으로 들어오는 트래픽 중 해당 IP 범위를 Deny 하도록 구성하게 됩니다. 단일 IP 주소 혹은 전체 IP 서브넷을 타겟으로 할지는 필요에 따라 정하면 됩니다. 다음 테이블은 지금까지 기술한 부분에서 보안 그룹에 적용했던 규칙들에 상응하는 사용자 정의 네트웍 ACL 입니다. 보다 자세한 내용이 필요하면 Network ACLs. 을 참조하시기 바랍니다. (또한 1024에서 65535까지 중 임시 포트 범위를 선택하기 위한 정보가 필요하시면, Ephemeral Ports를 참조하시기 바랍니다.)

기타 고려사항

아마존 VPC상에서 보안 그룹과 네트웍 ACL을 구성하는 것은 여러분의 어플리케이션이 공격 받을 수 있는 지점을 줄여줄 수 있는 효과적인 방법입니다. 각각의 규칙들이 비슷해 보일 지라도 공격 지점을 줄여주는 데 중요한 몫을 하게 됩니다. 보안 그룹은 어플리케이션 상의 리소스에 접근할 수 있는 트래픽을 설정할 수 있게 해주며, 네트웍 ACL은 서브넷 레벨에서 명시적으로 Deny 해야 하는 포트, 프로토콜, 트래픽 소스들을 설정할 수 있게 해준다는 면에서 DDoS 방어에서 중요한 의미를 가집니다. 지금 여러분들은 두 가지 중요 기능, VPC와 보안 그룹을 설정하는 방법에 대해 안내를 받았으며, 이 외에도, DDoS에 대해 복원력이 높은 아키텍쳐를 구성할 수 있는 다음과 같은 서비스들(Amazon CloudWatch를 통한 모니터링, Amazon CloudFront, Amazon Route 53, Elastic Load Balancing, 과 Auto Scaling을 통한 스케일링) 을 고려해야만 합니다.

이 글은 AWS 보안 블로그 How to Help Prepare for DDoS Attacks by Reducing Your Attack Surface의 한국어 번역으로서 AWS 코리아 보안 담당 솔루션 아키텍트인 임기성님이 번역해 주셨습니다.

2015년 9월 AWS 최신 보안 뉴스

앞으로 AWS 한국 블로그 보안 카테고리를 통해 매월 AWS와 클라우드의 최신 보안 뉴스 요약 및 기술 백서 그리고 기술 문서 등을 소개하도록 하겠습니다.


MPAA Compliance Hub 사이트 개설

AWS Security Assurance에서는 연예/미디어 산업 고객들의 MPAA(Motion Picture Association of America) 컴플라이언스 관련 요청들을 충족시키기 위한 전담 웹 사이트(MPAA hub on AWS)를 소개하게 되었습니다.

본 웹 사이트에서는 관련 고객들이 최근 업데이트된 MPAA 보안 규정들을 확인하고, 새롭게 발표된 MPAA 클라우드 컴플라이언스 베스트 프랙티스를 받아 보실 수 있습니다. 또한 최신 MPAA 클라우드 컴플라이언스 가이드에 관한 자세한 내용을 담고 있는 4개의 문서들을 포함하고 있고, 이전 규정들과의 비교분석 및, 현재 제공되고 있는 AWS 컴플라이언스 기능들이 MPAA 보안 베스트 프랙티스를 어떻게 충족하는지에 대한 대략적인 소개를 살펴 보실 수 있습니다.

참고 자료:


개별 관리형 정책(Managed Policies)을 통해 접근 제어하기

AWS에서는 계정 내 만들었던 IAM 엔티티들(사용자, 그룹, 역할)에게 부여할 정책(Polic) 그룹을 생성할 수 있도록 해주는 관리형 정책 (managed policies)을 올해 공개했었습니다. 그 이후, 많은 고객분들이 하나의 보편적인 정책을 적용하기 보다는 여러 정책들을 섞어서 사용하는 것을 선호하신다고 말씀해 주셨습니다.

예를 들어, 복수의 서비스에 접근을 허용할 하나의 공통 정책을 만드는 대신, 각각의 서비스마다 접근을 허용해주는 정책을 개별로 만드는 것입니다. 논리적으로 분리 정의된 정책들의 관리를 유연하게 하기 위해서, 지금은 한개의 엔티티에 최대 10개까지 관리형 정책들을 적용할 수 있습니다. 여러분들은 각각의 엔티티에 할당된 정책 목록을 봄으로써 해당 엔티티에 부여된 퍼미션들에 대해 좀더 잘 이해하실 수가 있습니다. 자세한 설명 →


Simple AD를 통해 사용자 관리하기

How to Migrate Your Microsoft Active Directory Users to Simple AD에서 AWS 디렉토리 서비스(Directory Service)를 이용하여 수 분만에 Simple AD라 불리는 가용성 높은 AWS 관리형 디렉토리 서비스를 만드는 방법을 살펴보았습니다. Simple AD를 이용하면, 단일 도메인으로 조인된(joined to a domain) 아마존 EC2인스턴스들의 로그인 계정과 그룹 멤버쉽들을 통합해서 관리할 수 있게 해줍니다.

또한 한 개의 신원확인 정보를 가지고 어플리케이션에 인증받거나, 모든 EC2인스턴스에 로그인할 수 있게 됩니다. SimpleAD에 대해 보다 자세한 내용을 알고 싶으시면 여기를 클릭하세요(What is AWS Directory Service?)

또한 Microsoft Active Directory에서 사용자 정보(Identity)를 Simple AD로 마이그레이션 하는 방법도 다뤄보았습니다. 오늘자 포스팅에서는, 리눅스와 윈도우 환경에서 그러한 사용자 정보들을 관리하는데 도움을 줄 커맨드들에 대해서도 말씀드리겠습니다. 상세 내용 →


신규 보안 백서: AWS와 CJIS 컴플라이언스

AWS는 형사 판결 정보 서비스 보안정책(Criminal Justice Information Services (CJIS) Security Policy)에 의거하여 형사판결 정보(Criminal Justice Information, CJI)를 포함하는 모든 데이터를 통제하기 좋은 환경을 제공합니다. AWS 클라우드는 CJI정보를 포함하여 광범위하게 미 연방 및 주 정부의 민감한 업무들을 처리하는데 사용되어져 왔습니다. CJI를 처리해야 하는 사법고객 혹은 파트너들은 AWS의 다음 기능들을 이용함으로써, FBI(Federal Bureau of Investigation) 정책을 준수하면서 동시에 CJI데이터에 대한 보안성과 보호수준을 획기적으로 향상시킬 수 있습니다:

최근 발간된 백서 CJIS Compliance on AWS에서는 AWS 서비스를 통해 어떻게 CJIS 요건들을 만족시킬 수 있는지, CJIS 프레임웍 내부에서 어떤 AWS서비스들이 지원되는지, 그리고 AWS 와 CJIS 고객들 간의 책임범위에 대한 자세한 내용들을 다루고 있습니다. 상세내용 →


SAML2.0을 이용해서 Federated API/CLI 접근을 위한 솔루션 구현하기

How to Implement Federated API and CLI Access Using SAML 2.0 and ADFS 에서  ADFS(Active Directory Federation Services)와 파이썬 코드를 통해 federated API/CLI 접근 방법을 살펴보았습니다. 그 이후, SAML(Security Assertion Markup Language) 2.0을 지원하는 다른 아이덴티티 제공자(identity providers)들에도 동일한 방식으로 적용될 수 있는지에 대한 문의를 많이 받았습니다. 이에 대해 확실히 가능하다는 답변을 드릴 수 있겠습니다!

이 글에서는 이전에 했던 내용을 확장하여 입력 양식 기반 인증(form-based authentication)을 처리할 수 있도록 하면서, 거의 모든 아이덴티티 제공자(IdPs)들에 적용할 수 있는 방법을 기술하였습니다. 상세내용 →


2015 AWS PCI 컴플라이언스 패키지

새로 발표된 PCI DSS(Data Security Standard) 3.1버전에 대한 준수를 보증하는 2015 AWS PCI 컴플라이언스 패키지가 (요청 시) 제공되게 되었음을 알려드립니다. PCI DSS는 신용카드 정보의 보관과 처리를 포함한 광범위하고 민감한 업무를 지원하려는 고객들에게 글로벌하게 받아들여지는 보안 표준입니다.

이번 PCI 컴플라이언스 패키지는 AWS가 PCI DSS 버전 3.1기준의 레벨 1 서비스 제공자로서 검증 받았다는 AWS PCI 컴플라이언스 인증(AoC)을 포함합니다. 또한 200개 이상의 PCI DSS요건들 각각에 대해 고객과 AWS 각자의 공유책임을 설명하고 있는, 외부 독립 감사자에 의해 업데이트된 AWS PCI 책임 요약(Responsibility Summary)을 포함하고 있습니다. 본 문서는 1) AWS상에서 PCI 카드 홀더 환경을 효과적으로 관리하고자 하는 고객이나, 2)AWS상에서 높은 수준의 보안 환경을 구축하고 관리하고자 할때, 운영책임에 대한 보다 깊은 이해를 필요로 하는 고객들에게 도움이 될 것입니다.

Amazon Web Services 는 CloudFormation, CloudFront, Elastic Beanstalk, KMS등 현재 PCI를 준수하는 23개의 서비스를 제공중입니다. 추가적으로, AWS는 비자(Visa) 와 마스터(MasterCard)에 대한 검증된 서비스 제공자로서, 이 두 회사는 PCI DSS표준에 대한 AWS의 준수내용을 인정하였고, AWS의 개정된 AoC를 전달받았습니다.

AWS PCI 컴플라이언스 패키지를 신청하는 방법은?

2015 AWS PCI 컴플라이언스 패키지를 신청하기 위해선 AWS영업조직(AWS Sales and Business Development)을 컨택하시기 바랍니다. AWS PCI 컴플라이언스 리포트에 대해 자세히 알아보시려면 PCI DSS Level 1 Compliance FAQs 페이지를 방문하시기 바랍니다.

또한 AWS Compliance website 에서는 AWS 컴플라이언스 프로그램에 대해 좀더 자세히 알아 보실 수 있습니다.

Chad Woolf, Director, AWS Risk and Compliance

참고 자료


HIPAA 백서 개정판 공개

AWS가 어떻게 HIPAA 와 HITECH 컴플라이언스 요건들을 준수하는지를 설명하는 Architecting for HIPAA Security and Compliance on Amazon Web Services 백서가 최근 업데이트 되었습니다.

헬쓰케어 기술의 성장과 발전에 따라 환자진료와 연구의 새로운 지평을 여는 클라우드 컴퓨팅의 적용이 가속화 되고 있습니다. 그러나 반면에 이러한 혁신적이고 창조적인 헬쓰케어 프로그램들은 미 연방 정보 표준 프레임웍의 기술적인 요건들을 맞추기가 어려워 질 수 있습니다.

본 백서는 AWS상에서 어떻게 HIPAA규정을 준수하는 서비스들을 이용할 수 있고, AWS상에서 데이터를 안전하게 암호화 하고 보호할 수 있는지에 대한 정보를 제공합니다. 또한 환자 의료정보(personal health information (PHI))의 암호화를 담당하는 AWS키관리(Key Management Service)를 사용하기 위한 가이드와, 감사, 백업, 재해복구에 관한 대략적인 내용들을 제공합니다.

참고 자료:


Amazon VPC를 이용하여 PCI DSS의 데이터 전송중 암호화 요건을 충족시키기

데이터의 전송 중 암호화에 관한 PCI 요건은 퍼블릭 네트워크를 사용할 때와 프라이빗 네트워크을 사용할 때가 다릅니다. 논리적으로 독립된 AWS인프라로서 여러분의 기존 데이터센터 네트웍을 클라우드 상에 확장시켜주게끔 Amazon Virtual Private Cloud (Amazon VPC)가 정확하게 설계되었다면 Payment Card Industry Data Security Standards (PCI DSS)를 준수하는 사설 네트웍으로 간주될 수 있습니다.

본 포스팅에서는 Amazon VPC에 의해 제공되는 논리적인 분리의 이해에 대한 중요성과 AWS인프라 외부로 민감한 정보를 전송할때 요구되는 PCI요건에 맞추어 설계할 때 고려할 중요 포인트들을 다룹니다. 또한 추가적인 보안성을 위해 Amazon VPC에 의해 제공되는 원천적인 분리방법을 보여줍니다. 더 자세히 보기 →


9월의 AWS 보안 뉴스는 AWS코리아의 보안 분야 솔루션 아키텍트로 일하시고 있는 임기성님께서 작성해 주셨습니다.

Route53 지연 속도 기반 라우팅 활용하기

AWS는 전 세계에 11개의 리전(Region)과 30개의 가용 영역(Availability Zone)으로 글로벌 서비스를 제공함으로써, 각 국가 또는 지역 사용자에게 가장 빠른 서비스를 제공합니다. 뿐만 아니라 Amazon CloudFront라는 전용 콘텐츠 전송 네트워크를 통해 네트워크 속도 측면에서 가장 가까운 53개의 에지(Edge)에서 더 빠르게 정적 콘텐츠 및 동적 캐싱을 통해 더 빠른 서비스 전달이 가능합니다.

이를 위해 원래 콘텐츠 위치(Origin)인 S3 버킷에서 가장 빠른 클라우드프론트 에지를 찾아야 할 필요가 있습니다. 그래야 더 빠르게 콘텐츠를 배포할 수 있을 테니까요. 많은 고객들이 이러한 질문을 해주셨습니다.

이 글에서는 도메인 네임 서비스로 알려진 Amazon Route53의 여러 가지 기능 중 지연 속도 기반 라우팅(Latency based routing)을 통해 위와 같은 질문에 대한 해결 방법을 찾아 보도록 하겠습니다.

지연 속도 기반 라우팅(Latency based routing) 설정하기
만약 AWS 위에서 운영 중인 서비스가 동경 리전(Tokyo region)과 버지니아 리전(Virginia region)을 통해 서비스 되고 있을 경우, 이 서비스 도메인 이름을 Route53을 통해 등록하고 지연 속도 기반 라우팅을 설정 할 수 있습니다. 이러한 경우 Route53은 해당 서비스의 DNS 질의를 했을 때, Tokyo와 Virginia region 중 고객 입장에서 보다 낮은 지연 속도(Latency)를 가질 수 있는지 판단하여 지연이 낮은 리전의 주소를 반환합니다.

대부분의 경우, 아시아쪽 고객은 동경 리전으로 미국쪽 고객은 버지니아 리전으로 DNS 주소를 반환하고, 사용자의 접속 속도는 훨씬 빨라지게 되므로 사용자의 경험은 증가할 것입니다.

우리는 이러한 라우팅이 잘 동작하는지 검증하기 위한 도구를 만들기 위해 버지니아, 아일랜드 및 동경 리전에 각각 S3 버킷을 만들고 정적 웹 호스팅을 구현한 후 location.txt라는 파일을 만들어 각각 자신의 리전이름(예: I’m in Virginia)을 표시하도록 하였습니다.

  • 버지니아: Virginia.cloudinternal.com
  • 아일랜드: Ireland.cloudinternal.com
  • 동경: Tokyo.cloudinternal.com

버킷 생성과 Index 문서 설정이 끝났다면, Route53으로 이동하여 해당 버킷이 도메인명을 통해 인터넷에서 접근할 수 있도록 Route53 Alias 기능을 이용해 ireland.cloudinternal.com, tokyo.cloudinternal.com, virginia.cloudinternal.com을 등록합니다.

사실 lbr.cloudinternal.com이 실제 지연 속도 기반 라우팅으로 설정할 도메인 이름입니다. 레코드에 등록할 때 Routing PolicyLatency로 설정하고, Region은 타겟 S3 버킷 위치에 해당하는 리전을 설정합니다. 예를 들어, ireland.cloudinternal.com을 Target으로 등록할 때는 리전을 eu-west-1으로 선택하게 됩니다.

즉, eu-west-1(아일랜드 리전)에 가까우면 ireland.cloudinternal.com로, ap-northeast-1(동경 리전)에 가까우면 tokyo.cloudinternal.com로, us-east-1(버지니아 리전)에 가까우면 virginia.cloudinternal.com으로 DNS 응답을 받을 수 있도록 설정합니다.

라우팅 결과 살펴보기
각 지역의 가까운 곳에서 DNS Lookup을 하여 실제로 가까운 S3 버킷으로 연결되는지 시험합니다. 아일랜드와 오레곤 리전에 각각 t2.micro로 인스턴스를 실행하고, dig 명령을 실행합니다. 동경은 한국에서 연결될 가능성이 높으니 직접 자신의 랩탑에서 시험해도 좋습니다.

Oregon Instance에서 DNS lookup실행

$ ssh -i [your_key_file1]  ec2-user@52.27.81.xxx 'dig +short lbr.cloudinternal.com'
virginia.cloudinternal.com.s3-website-us-east-1.amazonaws.com.
s3-website-us-east-1.amazonaws.com.
54.231.16.60

Ireland Instance에서 DNS Lookup 실행

$ ssh -i [your_key_file2] ec2-user@54.171.115.xxx 'dig +short lbr.cloudinternal.com'
ireland.cloudinternal.com.s3-website-eu-west-1.amazonaws.com.
s3-website-eu-west-1.amazonaws.com.
54.231.129.36

한국 내에서 DNS Lookup 실행

$ dig +short lbr.cloudinternal.com
tokyo.cloudinternal.com.s3-website.ap-northeast-1.amazonaws.com.
s3-website.ap-northeast-1.amazonaws.com.
54.231.230.12

가까운 AWS 리전의 S3 주소가 반환되는 것을 확인 할 수 있습니다.

빠른 CloudFront S3 Origin 설정하기

이제 lbr.cloudinternal.com으로 CloudFront Origin을 설정하면 자동으로 가까운 S3 버킷을 Origin으로 객체(Object)를 가져오겠지만, S3는 HTTP Request header 의 Host 정보를 참조하여 Bucket 이름과 다르면 404 Not Found 페이지를 반환합니다. 따라서 추가적인 설정이 필요합니다. 지연 속도 기반 라우팅이 잘 동작하니, CDN 서비스를 요청하는 클라이언트는 Route53을 통해 내가 어느 쪽 리전으로 접근해야 하는지 확인한 후, URL에 해당 리전 정보를 포함하여 요청하면 지연 속도가 낮은 쪽의 S3 버킷을 원래 소스 저장소(Origin)로 선택할 수 있습니다.

WHERE = `dig +short lbr.domainname.com`
CF_URL = dfoijefo2eoifjeaf.cloudfront.net/$WHERE/target_file.jpg

위와 같은 로직을 수행하기 위해서 CloudFront에서 Origin과 Behavior를 아래와 같이 설정합니다.

Origin 설정

Behavior 설정

간단히 아래와 같이 가까운 Region위치를 알 수 있습니다.
한국에서 수행

$ dig lbr.cloudinternal.com +short | awk -F "." '{ print $1 }' | head -1
tokyo

Oregon region 인스턴스에서 수행

$ ssh -i [your_key_file] ec2-user@52.27.81.xxx  'dig +short lbr.cloudinternal.com' | awk -F "." '{ print $1 }' | head -1
virginia

Ireland region 인스턴드에서 수행

$ ssh -i [your_key_file2] ec2-user@54.171.115.xxx 'dig +short lbr.cloudinternal.com' | awk -F "." '{ print $1 }' | head -1
ireland

최종적으로 알게된 리전을 URL Prefix에 포함하여 요청하여 원하는 결과를 얻을 수 있습니다.

$ curl http://d2r05xiwqufy6.cloudfront.net/ireland/location.txt
I'm in Ireland.
$ curl http://d2r05xiwqufy6.cloudfront.net/tokyo/location.txt
I'm in Tokyo
$ curl http://d2r05xiwqufy6.cloudfront.net/virginia/location.txt
I'm in Virginia

지금까지 우리는 Route 53의 지연 속도 라우팅 방식을 기반으로 CloudFront의 소스 파일이 위치한 가장 가까운 S3 버킷의 위치를 찾는 문제를 해결해 보았습니다. 이를 위해 S3 정적 웹 호스팅 및 CloudFront의 몇 가지 기능을 활용하기 위한 설정이 필요했지만, 단순히 리전간에 구성된 웹 서비스의 Elastic Load Balancing 주소를 지연 속도 기반 라우팅으로 Route 53에 구성하면 복잡한 설정 없이 CloudFront을 통해 동적 콘텐츠도 활용할 수 있는 구성을 할 수 있습니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김일호 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon Redshift에서 빠르게 데이터 로딩하기

Amazon Redshift는 페타바이트급의 데이터를 빠르고 저렴하고 간단하게 분석할 수 있는 클라우드 기반 데이터 웨어하우스(DW)서비스입니다. 병렬 실행, 압축 스토리지, 암호화 등 다양한 매니지드 서비스를 제공합니다. Amazon Redshift의 데이터 활용 크기는 160GB의 클러스터로 부터 1,000/TB/Year의 페타바이트급 대량 데이터를 다루는데 적합합니다.

우선 DW에서 데이터 로딩의 특성에 대해 살펴보겠습니다. 일반적으로 DW는 하나 이상의 서로 다른 데이터 소스에서 수집된 데이터의 통합 저장소로 사용합니다. 현재 및 과거의 데이터를 저장한 뒤, 데이터 분석가들이 기업 전체의 분석 보고서를 작성하는데 주로 사용됩니다. 상세한 일일 판매 분석, 연간 및 분기별 비교 또는 동향에 이르기까지 다양합니다.

일반적으로 데이터 분석가는 가능한 최신 데이터를 사용하고 싶어합니다만, 데이터 크기 및 업무의 특성으로 기존의 OLTP(Online Transaction Processing)와는 다른 방식으로 진행됩니다. 예를 들어, 웹 로그 분석 DW는 일반적으로 야간 또는 하루에 몇 번 데이터를 DW로 로드합니다. 하지만, 매 시간, 매 분 단위로 지속적으로 데이터를 갱신하려는 요구 사항도 있습니다.

이 글에서는 Amazon Redshift에서 짧은 주기로 지속적인 데이터를 로딩할 때, 더 빠르게 할 수 있는 모범 사례를 소개하고자 합니다. 이는 주별 또는 일별 로딩과는 다르게 빠른 시간 내에(수분 단위 등) 최신 데이터를 Amazon Redshift에 반영하기 위한 방법입니다. Amazon Redshift는 단일 MERGE 또는 UPSERT를 지원하지 않지만, 스테이징 테이블을 이용한 UPDATE 와 INSERT 조합을 이용하여 기존 테이블에 새로운 데이터를 효율적으로 추가할 수 있습니다. 스테이징 테이블에 아주 짧은 시간내에 데이터를 로딩하기 위해서 이 글에서 소개하는 방법이 여러분에게 의미 있을 것으로 생각합니다.

1. 데이터 입력 파일의 균형 맞추기
우선 Amazon Redshift 클러스터의 모든 컴퓨팅 노드를 효율적으로 사용하여 데이터를 로딩하기 위해서 COPY 명령어를 사용합니다. COPY 명령어는 Amazon S3, Amazon EMR, Amazon DynamoDB 또는 원격 호스트로 부터의 데이터 로딩을 병렬적으로 처리하기 때문에 많은 양의 데이터를 INSERT 구문에 비해 효율적으로 처리할 수 있습니다.

Amazon Redshift 클러스터는 노드들의 집합체 입니다. 클러스터의 각 노드는 자신의 운영체제, 전용 메모리 및 전용 디스크 저장 장치를 가지고 있습니다. 그 중 하나의 노드는 컴퓨팅 노드로 데이터 및 질의 처리 작업(query processing tasks)의 분배를 관리하는 리더 노드입니다. 그리고 컴퓨팅 노드의 디스크 스토리지는 몇 개의 슬라이스로 나누어 집니다. 이 때 슬라이스 갯수는 컴퓨팅 노드의 프로세서 갯수와 동일합니다. 예를 들어, DS1.XL 컴퓨팅 노드는 2개의 슬라이스를 가지고 있으며, DS1.8XL 컴퓨팅 노드에는 32개의 슬라이스가 있습니다. 가능한 모든 노드의 모든 슬라이스를 통해 고르게 데이터를 분산 저장하고, 병렬적으로 질의를 처리합니다.

가장 빠른 성능으로 데이터를 로딩하기 위해서는, 클러스터의 모든 슬라이스(하나의 가상 CPU, 메모리 및 디스크)에 동일한 양의 작업을 수행하도록 해야 합니다. 이것은 각 슬라이스당 수행 시간을 짧게 해주고, 선형에 가까운 확장을 보장합니다. 이를 위해서, 입력 파일의 수가 슬라이스 갯수의 배수인지 확인해야 합니다.

이제 여러분이 Amazon S3에서 데이터를 로딩하는 경우, Amazon S3에 업로드 하기 전에 Amazon Redshift 클러스터의 모든 슬라이스 갯수의 배수(1 또는 그 이상의)로 입력 파일을 분할하는 것이 필요합니다. 즉, 4대의 DS1.XL 컴퓨팅 노드로 클러스터를 생성하셨다면, 전체 슬라이스 갯수는 8 입니다. 이때 입력 파일을 8 또는 16/24/32 개로 분할하여 Amazon S3에 업로드 한 후, 단일 COPY 명령어로 모든 입력파 일을 병렬적으로 로딩하도록 하면 동시에 슬라이스 갯수만큼 로딩 작업이 수행됩니다.

아래 예는 Linux의 split 명령어를 통해 원하는 갯수로 파일을 분할하는 간단한 예제 입니다.

$ ls -la
total 12020
drwxrwxr-x 2 ec2-user ec2-user     4096 Jul 22 14:43 .
drwx------ 4 ec2-user ec2-user     4096 Jul 22 14:41 ..
-rw-rw-r-- 1 ec2-user ec2-user 12299878 Jul 22 14:41 customer-fw.tbl

$ split -l `wc -l customer-fw.tbl | awk '{print $1/16}'` -d --verbose customer-fw.tbl "customer-fw.tbl-"
creating file ‘customer-fw.tbl-00’
creating file ‘customer-fw.tbl-01’
...
creating file ‘customer-fw.tbl-14’
creating file ‘customer-fw.tbl-15’
$ ls -la
total 24052
drwxrwxr-x 2 ec2-user ec2-user     4096 Jul 22 14:44 .
drwx------ 4 ec2-user ec2-user     4096 Jul 22 14:41 ..
-rw-rw-r-- 1 ec2-user ec2-user 12299878 Jul 22 14:41 customer-fw.tbl
-rw-rw-r-- 1 ec2-user ec2-user   768750 Jul 22 14:44 customer-fw.tbl-00
-rw-rw-r-- 1 ec2-user ec2-user   768750 Jul 22 14:44 customer-fw.tbl-01
...
-rw-rw-r-- 1 ec2-user ec2-user   768750 Jul 22 14:44 customer-fw.tbl-14
-rw-rw-r-- 1 ec2-user ec2-user   768628 Jul 22 14:44 customer-fw.tbl-15

이제 Amazon Redshift를 통해 COPY 명령을 수행해 보겠습니다.

copy customer 
from 's3://<your-bucket-name>/load/customer-fw.tbl'
credentials 'aws_access_key_id=<Your-Access-Key-ID>; aws_secret_access_key=<Your-Secret-Access-Key>'

이제 Amazon S3에서 데이터를 로드하는 자세한 방법은 개발자 문서을 참고하시기 바랍니다.

2. 칼럼(Column) 압축 인코딩 미리 정의하기
Amazon Redshift 는 데이터가 저장될 때 크기를 줄일 수 있는 칼럼 레벨 압축을 지원합니다. 압축은 저장 공간을 절약하는 장점과 함께 스토리지로 부터 읽어야 할 데이터의 크기를 줄이기 위해 디스크의 I/O 를 줄임으로써 쿼리의 성능을 개선할 수 있는 방법입니다. Amazon Redshift 는 기본적으로는 압축되지 않은 형식으로 데이터를 저장합니다. 여러분은 테이블을 생성할 때 수동으로 각 칼럼의 압축 방식 또는 인코딩을 지정할 수 있습니다.

COPY 명령의 가장 큰 특징은 테이블이 비어있을 때 자동으로 최적의 칼럼 인코딩을 적용한다는 것입니다. 그러나, 이 작업은 약간의 시간이 필요합니다. 왜냐하면 자동 압축 분석을 위해서는 각 슬라이스 당 적어도 100,000행의 데이터를 먼저 샘플링 해야 하기 때문입니다. 아래는 COPY 명령을 통해 수행되는 자동 압축 분석 단계입니다.

  • 입력 파일로 부터 초기 샘플링을 위한 행을 로딩 합니다. 샘플 데이터의 크기는 COMPROWS 파라미터 값을 통해 정의되는데, 특별한 지정이 없을 시 기본값은 100,000 입니다.
  • 각 열에 알맞은 압축 옵션(인코딩 방식)이 결정됩니다.
  • 초기 로딩된 샘플 행이 테이블에서 제거됩니다.
  • 결정한 압축 옵션으로 테이블이 새롭게 생성됩니다.
  • 전체 입력 파일을 새로운 인코딩 방식을 사용하여 로딩하고 압축합니다.

추후에 추가적인 데이터가 해당 테이블에 추가될 때는 기존에 결정된 인코딩 방식을 이용하여 압축됩니다.

아주 짧은 주기로 스테이징 테이블에 데이터를 추가해야 하는 상황에서는 사전에 인코딩 방식을 결정하여 테이블을 생성해 놓는다면 이런 자동 압축 분석의 단계를 생략할 수 있습니다. 이때 각 컬럼에 알맞는 정확한 인코딩 방식을 미리 결정해 놓아야 합니다.

이렇게 하려면 아래와 같이 테이블을 대표할 수 있는 데이터를 한 번 COPY 명령어를 통해서 로딩하고 난 후, pg_table_def에 기록된 각 컬럼의 인코딩 방식을 사용합니다. 그런 다음 테이블을 DROP 하고 앞에서 찾은 컬럼의 인코딩 방식을 포함하여 테이블을 생성합니다. 이후 COPY 명령어를 사용하여 데이터를 로딩 할 때, 자동 압축 분석 작업을 생략하도록 ‘COMPUPDATE OFF’를 추가합니다.

select "column", type, encoding from pg_table_def where tablename = 'nations';

아래는 각 컬럼에 맞게 접합하게 선택된 인코딩 방법입니다.

Column Type Ecoding
nationkey integer DELTA
name character(25) TEXT255
regionkey integer RUNLENGTH
comment character varying(152) LZO

그런 다음 테이블을 DROP 하고, 테이블 생성 DDL에 ENCODE 키워드를 추가하여 컬럼에 대한 인코딩 방식을 명시하고 테이블을 다시 생성합니다.

CREATE TABLE NATIONS (
NATIONKEY INT ENCODE DELTA,
NAME CHAR(25) ENCODE TEXT255,
REGIONKEY INT ENCODE RUNLENGTH,
COMMENT VARCHAR(152) ENCODE LZO
);

이후 다시 데이터를 Amazon S3로 부터 COPY합니다.

copy nation 
from 's3://<your-bucket-name>/load/nations.tbl'
credentials 'aws_access_key_id=<Your-Access-Key-ID>; aws_secret_access_key=<Your-Secret-Access-Key>'
COMPUPDATE OFF;

3. 통계 계산의 빈도 줄이기
Amazon Redshift의 COPY 명령은 최적화(Optimizer)를 위해 각 데이터 로딩에 대해서 테이블의 통계를 계산합니다. 추후 질의(Query)를 위해서는 굉장히 유용하지만, 이 또한 시간이 걸립니다. 그래서 열 인코딩으로, 정해진 데이터 세트에 대해서 통계를 계산한 후 COPY 명령이 수행되는 동안 재계산을 막는 것이 빠른 데이터 로딩을 위한 좋은 방법입니다.

이를 위해서 압축 인코딩을 사전 정의하는 방식과 동일하게, 테이블을 대표할 수 있는 데이터 세트를 로딩한 다음, ANALYZE 명령어를 이용하여 분석을 할 수 있습니다. 그러고 난 후 매번 수행되는 COPY 명령어의 옵션으로 ‘STATUPDATE OFF’를 설정하여 자동 분석 작업을 중지할 수 있습니다.

단, Query를 효율성을 위해 테이블에 대한 통계정보를 최신으로 유지하기 위해서 주기적으로 ANALYZE 명령을 실행할 필요가 있습니다. 질의 설계기(Query planner)는 최적화된 query plan을 선택하기 위해서 테이블의 통계에 대한 메타데이터 정보를 사용하기 때문입니다.

만약 시간이 경과함에 따라 로딩한 데이터의 특성이 크게 변한 경우, 통계 및 컬럼 인코딩은 테이블 구조에 맞게 재계산해야 합니다.

4. 정렬키(Sort Keys) 순서로 데이터 로딩
Amazon Redshift은 테이블을 생성할 때 단일 또는 복수개 컬럼을 정렬키(Sort Keys)로 지정할 수 있습니다. Redshift는 1MB의 디스크 블록에 컬럼 데이터를 저장합니다. 각 블록에 저장된 최소값 그리고 최대값을 메타데이터로 관리합니다.

만약 질의에 범위 제한적인 조건이 포함된 경우, 테이블을 스캔하는 과정에서 필요한 블록만을 읽어 들일 수 있게 최소값, 최대값을 활용합니다. 질의에 필요한 블록에 대해서만 디스크 I/O를 일으킴으로써 질의에 대한 성능을 개선할 수 있는 좋은 기능입니다. 위와 같은 장점을 극대화 하기 위해, 데이터를 정렬키(Sort Keys)의 순서에 맞춰 로딩한다면 추후 테이블에 대한 VACUUM 작업을 회피할 수 있습니다.

Amazon Redshift 는 클러스터로 로딩하는 데이터를 정렬합니다.날짜 기반의 컬럼을 정렬키(Sort Keys)로 지정하셨다면 시간 순서로 데이터를 로딩하는 것이 좋은 방법입니다. 예를 들면, 정렬키로 설정된 순서대로 오후 1시 ~ 2시 데이터를 먼저 로딩하고 이후에 2시~3시 데이터를 로딩하는 방식입니다.

이 방식을 참고하여 데이터를 로딩한다면, VACUUM 명령을 delete 또는 update 작업의 결과로 발생하는 빈 공간(free space)을 회수하는 용도로만 사용하면 됩니다.

정렬키(Sort Keys)에 대한 자세한 내용은 기술 문서를 참고하시기 바랍니다.

5. SSD 노드 유형 사용하기
Amazon Redshift는 두 개(세부적으로는 6개)의 상이한 노드 유형을 제공하고 있습니다. 첫번째 ds1/ds2 패밀리는 마그네틱 디스크를 사용합니다. ds1(ds2).xlarge 노드 유형은 각 노드당 2TB의 사용 가능한 스토리지를 제공하고, ds1(ds2).8xlarge 노드 유형은 각 노드당 16TB 의 사용 가능한 스토리지를 제공합니다.

앞에서 설명드린 것 처럼 짧은 주기로 데이터를 로딩해야 하는 환경을 위해서라면 I/O 지연시간(latency)을 획기적으로 감소시킬 수 있는 SSD 디스크를 사용하는 dc1 패밀리를 사용하는 것이 도움이 됩니다. 데이터 로드의 간격(interval) 내에 원하는 데이터에 대한 로딩을 완료하기 위해서는 빠른 I/O가 필요 합니다. dc1.large는 각 노드당 160GB, dc1.8xlarge는 각 노드 당 2.56TB의 스토리지를 제공합니다. 이처럼 dc1 노드 유형은 높은 컴퓨팅-스토리지 비율을 제공하여 COPY 명령어를 수행할 때 낮은 지연 시간(latency)을 제공합니다.

지금까지 짧은 시간 간격으로 Amazon Redshift 로 데이터를 로드할 때 사용할 수 있는 다섯 가지 방법에 대해 알려드렸습니다. 특정 고객사의 경우, Amazon Redshift에서 위와 같은 방법들을 이용하여 데이터의 로드 시간을 90% 이상 개선한 경험이 있습니다. 물론 이러한 방법들이 모든 경우에 해당되는 것은 아닙니다. 다만, 하루에 한번 또는 일주일에 한번씩 배치(Batch)로 데이터를 로딩할 경우에는 약간 다른 방법을 사용 해야할 가능성도 있습니다. 여러분의 업무 목적에 맞는 적합한 방법을 사용하는 것이 업무의 효율성을 위해서는 매우 중요합니다.

마지막으로 2013년 re:Invent 에서 소개되었던 “Getting Maximum Performance from Amazon Redshift”세션에서의 HasOffers 사례 발표인 Fast Data Loads 부분도 참고해 보시길 권합니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 양승도 솔루션즈 아키텍트께서 작성해주셨습니다.
sd-yang-photo

AWS CLI를 통한 빠른 인스턴스 타입 변경 방법

클라우드 컴퓨팅 장점 중의 하나는 민첩성(Agility)입니다. 전통적인 IT환경에서 서버의 CPU나 메모리 또는 NIC 등의 부품 구성을 변경하는 작업은 운영자의 수작업이 동반됩니다. 하지만, AWS 환경에서는 웹 관리 콘솔을 통해서 몇 번의 클릭만으로 관련 작업을 신속하고 간단히 수행할 수 있습니다.

그러나, 수 십대 또는 수 백대의 인스턴스들을 운영하고 또 한정된 점검 시간 내에 관련 작업을 수행 해야한다면 이 작업 또한 그리 쉬운 일은 아닙니다. 이런 경우 AWS에서 제공하는 API나 CLI를 이용해서 간단한 프로그램이나 스크립트를 작성하면, 반복적인 작업을 일괄 처리 수행하여 쉽고 빠르게 목표한 결과를 얻을 수 있습니다.

이 글에서는 c3.large 타입의 인스턴스들을 새로운 세대인 c4.large 타입으로 한꺼번에 변경해야 하는 상황을 가정해서, 일괄 처리하는 스크립트를 작성하는 예를 소개합니다.

사전 준비 사항
스크립트를 작성하기 위해서는 아래 AWS 명령줄 인터페이스가 준비되어야 합니다. AWS 명령줄 인터페이스는 여기를 클릭하시면 다운로드 받을 수 있으며, 설치 가이드와 사용법도 확인할 수 있습니다.

스크립트 작성하기
위의 CLI 설치 작업이 완료되었다면, 이제 스크립트를 작성할 준비가 되었습니다. 인스턴스 타입을 변경하는 작업은 인스턴스가 정지된 상태서만 가능하기 때문에, 원하는 작업을 성공적으로 하려면 다음의 작업 순서를 따라야 합니다:

  1. 대상 인스턴스 목록 추출
  2. 인스턴스 정지
  3. 인스턴스 타입 변경
  4. 인스턴스 시작

1번에서 획득한 각 인스턴스를 대상으로 2, 3, 4번을 순차적으로 반복 수행하게 됩니다.

우선 인스턴스 목록을 얻기 위해서 describe-instances 명령을 이용합니다. 아래 명령어는 AWS 계정에서 운영되는 모든 인스턴스의 정보를 얻을 수 있습니다.

$ aws ec2 describe-instances 

작업 대상인 c3.large 타입의 인스턴스들에 대한 정보만 얻기 위해서는 필터 기능을 활용해야 합니다. --filters 옵션을 사용해서 instance-type이 c3.large인 인스턴스들만 추출합니다.

$ aws ec2 describe-instances  --filters "Name=instance-type,Values=c3.large"

위 명령어를 통해서 c3.large 타입의 인스턴스에 대한 모든 속성 정보를 볼 수 있습니다. 응답된 데이터에서 실제로 필요한 인스턴스 ID 정보만 얻기 위해서는 --query 옵션을 사용하고 그 값으로 Reservations[].Instances[].InstanceId 문자열을 사용합니다. 또한 스크립트에서 사용하기 용이하도록 출력되는 형태를 JSON 형태가 아닌 일반 텍스트로 출력되도록 변경합니다. 이를 위해서 --output 옵션과 옶션값으로 text 값을 선택합니다.

출력되는 결과의 필드 구분자는 탭문자(‘\t’)입니다. 즉, 인스턴스 ID들이 탭문자로 구분되어서 한 라인에 길게 나열되게 됩니다. tr(1)명령어를 이용해서 탭문자를 개행문자(‘\n’)로 대체시켜 한 줄에 하나의 인스턴스 ID가 출력되도록 변경합니다.

$ aws ec2 describe-instances  --filters "Name=instance-type,Values=c3.large" --query "Reservations[].Instances[].InstanceId"  --output text |  tr "\t" "\n"

이제 앞에서 얻은 인스턴스 ID 목록과 아래에 소개할 명령어들을 이용해서 인스턴스를 하나씩 c3.large에서 c4.large로 변경할 수 있습니다.

먼저 인스턴스 하나를 정지시킵니다.

$ aws ec2 stop-instances --instance-id=${INSTANCE_ID} 

위 명령어는 비동기 명령이기때문에 해당 인스턴스에 정지 명령을 실행시키고 결과에 관계없이 바로 리턴됩니다. 이 명령어 다음에 바로 인스턴스 타입을 변경시키면 에러가 발생할 수 있습니다.

따라서 인스턴스 상태를 주기적으로 체크하여 인스턴스가 정지(STOPPED)된 상태로 변경되었을 때 타입을 변경해야 합니다. 비동기 명령을 내릴 때마다 체크하는 부분을 스크립트 내에 코드로 작성한다면 다소 번거롭고 귀찮은 일입니다. 하지만 AWS 명령줄 인터페이스는 친절하게도 이를 대신 수행하는 명령을 제공합니다. 비동기 명령어가 수행되고 원하는 상태가 되었을 때까지 기다릴 수 있도록 wait라는 추가 명령 옵션을 제공하고 있습니다.

$ aws ec2 wait instance-stopped --instance-ids=${INSTANCE_ID}

위 명령어를 통해서 인스턴스가 실제로 정지될 때까지 스크립트는 다음 단계를 수행하지 않고 멈춰 있습니다. wait명령을 통해서 인스턴스가 정지할 때까지 아래 명령어를 수행하지 않고 대기합니다.

인스턴스 타입 변경은 modify-instance-attribute 명령을 이용해서 간단히 수행합니다.

$ aws ec2 modify-instance-attribute --instance-type=c4.large --instance-id=${INSTANCE_ID} 

타입 변경이 끝났다면, 이제 인스턴스를 다시 시작하기만 하면 됩니다.

$ aws ec2 start-instances --instance-id=${INSTANCE_ID}

인스턴스를 시작하는 명령도 비동기 명령입니다. 그렇기 때문에 인스턴스에 시작 명령을 내리고 실제 인스턴스가 정상적으로 실행되었는지와는 관계없이 바로 리턴됩니다.
아래와 같이 wait 명령어를 통해서 해당 인스턴스 상태가 정상적으로 시작된 상태인지를 확인한 후 다음 인스턴스에 대한 타입 변경 작업을 수행할 수 있습니다. 이 부분은 선택사항입니다.

$ aws ec2 wait instance-status-ok --instance-ids=${INSTANCE_ID} 

지금까지 스크립트를 구성하는 주요 부분에 대해서 설명드렸습니다. 아래 스크립트는 앞서 설명드린 내용들을 기반으로 작성한 간단한 bash 쉘 스크립트입니다.

#!/bin/bash
#
while getopts ":s:d:" OPT; do
  case $OPT in
    s)
      SRC_TYPE=$OPTARG
      ;;
    d)
      DEST_TYPE=$OPTARG
      ;;
    *)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
  esac
done

aws ec2 describe-instances  --filters "Name=instance-type,Values=${SRC_TYPE}" --query 'Reservations[].Instances[].InstanceId' --output text |tr "\t" "\n"| while read INSTID
do
    echo "Changing instance type for ${INSTID}... $(date)"
    aws ec2 stop-instances --instance-id=${INSTID} > /dev/null 2>&1
    aws ec2 wait instance-stopped --instance-ids=${INSTID} > /dev/null 2>&1
    aws ec2 modify-instance-attribute --instance-type=${DEST_TYPE} --instance-id=${INSTID} > /dev/null 2>&1
    aws ec2 start-instances --instance-id=${INSTID} > /dev/null 2>&1
    aws ec2 wait instance-status-ok --instance-ids=${INSTID} > /dev/null 2>&1
done
echo  "All done! $(date)"

스크립트의 간결성을 유지하기 위해서 모든 에러처리 루틴을 배제하였습니다. 따라서 범용적으로 사용하기 위해서는 적절한 에러 처리 루틴들이 추가되어야 하고 충분한 테스트를 거친 후 사용하시길 권장합니다.

아래 예는 실제로 두 개의 c3.large 리눅스 인스턴스를 c4.large로 변경하였을 때의 실행 결과를 캡처한 내용입니다.

$ ./migration.sh –s c3.large –d c4.large
Changing instance type for i-353294c7... 2015년 7월 20일 월요일 09시 27분 01초 KST
Changing instance type for i-253593d7... 2015년 7월 20일 월요일 09시 30분 22초 KST
All done! 2015년 7월 20일 월요일 09시 34분 44초 KST

이 스크립트를 통해 대규모 EC2 인스턴스 운영 환경에서 인스턴스 타입을 변경할 뿐만 아니다 각종 정보를 변경하는 등 다양한 운영 작업에 활용하시는데 도움이 되었으면 합니다. 감사합니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박철수 솔루션즈 아키텍트께서 작성해주셨습니다.