AWS 기술 블로그

단비교육의 AWS Control Tower 와 함께 시작하는 아키텍처 현대화

안녕하세요. 저는 단비교육에서 Engineering Excellence 개발실을 맡고 있는 주성식이라고 합니다. 단비교육은 이 세상 모든 어린이의 행복한 삶의 출발을 함께하고자 노력하는 에듀테크 기업으로 업계 최초 도입한 특허 학습기를 포함해 여러 기술과 콘텐츠들을 통해 유·초등 교육 시장을 선도하며 성장해왔습니다. 단비교육은 론칭 2년 만에 매출 약 500억 원을 달성, 2021년에Mod는 933억, 2022년에는 1,081억을 달성하며 매해 성장 하고 있습니다. 또한2018년 론칭한 유·초등 어린이들을 위한 블렌디드 러닝 서비스인 윙크에 이어2021년에 시작된 도서 큐레이션 서비스, 윙크북스를 론칭하였으며 새로운 신규사업을 준비하며 입지를 더욱 넓혀가고 있습니다.

이번 글에서는 저희가 아키텍처 현대화를 준비하면서 가장 먼저 한 의사 결정인 AWS Control Tower의 도입과 이것을 시작으로 진행했던 몇가지 아키텍처 현대화 과정에 대해서 말씀드리고자 합니다.

AWS Control Tower 도입 배경

2016년에 창업된 단비교육은 지난 몇 년 동안 에듀테크 분야에서 빠른 성장을 이루었습니다. 현시점에서 되돌아보면 빠른 성장을 위해 진행되었던 의사 결정이 미래의 성장을 제약하게 되는 이른바 기술 부채의 역습이 시작되고 있는 상황이었습니다. 따라서 현시점의 문제점을 구체적으로 도출하고 실행 계획을 세우기 위해 자체적으로 AWS Well-Architected 프레임워크를 사용하여 각각의 필러에 대한 아키텍처 리뷰를 진행하였습니다.

이에 따라서 애플리케이션 및 아키텍처 현대화에 대한 다양한 필요성을 인지하게 되었습니다. 아키텍처 리뷰를 통해 각 영역별 조치 및개선 사항의 우선순위를 식별하면서 가장 먼저 대두된 사항이 있었습니다. 그것은 바로 이제 우리의 워크로드들은 서로 격리된 환경에서독립적으로 실행되어야 하며 감사, 보안 및 추적성을 확보할 수 있어야 한다는 것이었습니다. 이때 가장 먼저 떠오른 것은 다수의 AWS 서비스를 오케스트레이션하는 동시에 조직의 보안 및 규정 준수 요구 사항의 유지 관리에 큰 도움을 주는 클라우드 거버넌스 서비스인 AWS Control Tower 였습니다. 저희에게 AWS Control Tower 는 아키텍처 현대화 과정의 중요한 첫 단추가 되었습니다.

아키텍처 결정 기록 (Architecture Decision Records)의 도입

AWS Well-Architected 프레임워크의 아키텍처 리뷰에서 도출된 영역별 조치 및 개선 사항 즉, 그동안의 기술부채를 해결하고 신규 아키텍처의 설계와 마이그레이션을 위한 로드맵을 수립할 수 있었습니다. 시스템을 구축하고 운영하는 과정에는 수많은 의사결정이 필요합니다. 그리고 그 의사결정은 매우 중요합니다. 또한 시스템 요구사항은 시간이 흐르면서 유기적인 생물체처럼 변화합니다. 이러한 기능적 비기능적 요구사항의 변화는 개발자와 시스템 설계자 그리고 아키텍트에게 항상 새로운 의사결정을 요구합니다. 그리고 새로운 의사결정은 쉽지 않으며 이것은 곧바로 소프트웨어와 시스템의 품질에 큰 영향을 미치게 되기 때문입니다

AWS Control Tower 도입을 결정 하면서 향후에 발생하는 모든 아키텍처 결정 사항에 대한 투명성을 확보하는 것이 중요해졌습니다. 또한 팀 내부 혹은 팀 간의 효율적인 의사소통을 지원하고 프로젝트와 제품에 대한 전략적인 방향성을 문서화하며 반복적이고 시간 소모적인 의사 결정 노력을 간소화할 필요가 생겼습니다.

이를 위해 단비교육의 Engineering Excellence 개발실에서는 아키텍처 결정 기록(Architecture Decision Records, ADR)을 도입하게 되었습니다.
아키텍처 결정 기록(ADR)은 아래와 같은 세 가지 비즈니스 성과를 목표로 합니다.

  • 현재의 팀 구성원과 미래의 팀 구성원을 연결해 주는 역할을 합니다.
  • 프로젝트 또는 제품에 대한 전략적 방향을 설정합니다.
  • 아키텍처 결정을 적절히 문서화하고 전달하는 프로세스를 정의하여 의사 결정 방지 패턴을 피할 수 있습니다.

아키텍처 결정 기록(ADR)에 관련해서는 잘 만들어진 여러 가지 다양한 템플릿들이 존재합니다. 저희는 많은 사람들에게 인기를 얻고 있는 마이클 나이가드(Michael Nygard)가 고안한 LADR(Lightweight Architecture Decision Record) 형식을 참고하여 사용하기로결정하였습니다. ADR에 대한 다양한 템플릿들은 아래의 사이트에서 살펴 보실 수 있습니다.

저희의 첫번째 ADR은 바로 ADR을 도입하기로 결정 함에 대한 것이었고 두번째 ADR이 바로 AWS Control Tower 를 도입하는 것에대한 부분이었습니다.  ADR은 다음과 같은 형식으로 문서화 할 수 있습니다. (3번째 ADR은 그라비톤 인스턴스에 대한 도입 결정이었습니다.)

ADR 프로세스를 운영하기 위해 컨플루언스와 같은 위키시스템을 사용하는 것 보다 GitHub과 같은 VCS를 사용하면 Proposed, Accepted, Rejected 와 같은 상태 관리를 PullRequest 기반의 전문가 리뷰를 통해 ADR 워크플로우 내에서 쉽게 관리가 가능합니다. 또한 ADR Toolsadr-log와 같은 CLI 도구들을 함께 사용하면 더 좋습니다.

최근 AWS의 공식 온라인 문서에도 ADR을 소프트웨어 개발 방식에 어떻게 도입할 수 있는지에 대한 내용이 추가되었습니다. 아래의문서를 참고하실 수 있습니다.

AWS Control Tower 도입

조직 구조 설계

AWS Organizations는 AWS 환경에서 다중 계정 환경을 관리하기 위한 것으로 OU(Organization Units)이란 단위로 조직 구조를설계할 수 있도록 해줍니다. 여기서 중요한 것은 OU의 단위는 서비스 제어 정책, 즉 Service Control Policy와 같은 조직 별 정책이 각각 적용되는 단위라는 것입니다.

초기 OU 설계

이 각각의 OU에 해당 조직의 특성에 맞는 워크로드를 배치하게 됩니다. 각각의 OU는 조직의 특성에 따라 하위에 서브 OU를 가질 수있습니다. 또한 각 OU에는 AWS 어카운트를 포함하게 됩니다. 단비교육에서는 AWS Control Tower 를 구성한 최상위 어카운트 바로아래에 Dept001, Dept002 와 같은 최상의 비지니스 유닛(사업본부)를 배치하여 각 사업본부 내부에서 자율적으로 하위 OU를 구성하도록 하였습니다. 자율성을 강조하였지만 각 사업본부에 따라서 OU에 대한 네이밍 규칙은 다음과 같은 룰을 따르게 하였습니다.

  • <사업본부식별자>+<하위OU>+<어카운트 태그>@<도메인>

즉 이메일 주소 뒤에 “+” 사인을 사용하여 태그를 지정하는 방식으로 새로운 계정을 지속적으로 확장 가능하도록 하였습니다.
AWS Control Tower 를 활성화시킨 후에 ‘Security’ OU가 자동으로 구성되고 ‘Log Archive’와 ‘Audit’ 어카운트가 자동으로 프로비저닝 된 것을 확인할 수 있습니다. 이 어카운트를 통해 보안 감사 로그가 통합 저장되며Account Baseline 또는 Network Baseline 설정을 통해 사용자의 환경에 맞는 구조와 정책을 설계해 나갈 수 있게 됩니다.
OU를 설계할 때 주안점을 주었던 부분 중 하나가 사내의 개발자분들이 자유롭게 AWS 클라우드 환경에서 다양한 실험을 해볼 수 있도록 샌드박스 OU를 따로 만들어서 그 아래에 목적별로 어카운트를 제공하고자 하였으며 아래와 같이 샌드박스 OU 운영 방침을 결정하였습니다.

  • 사용자는 사업본부 내 개발자를 대상으로 한다.
  • Sandbox OU에 속한 계정은 고객서비스와 관련된 모든 리소스와 격리한다
  • EC2 대신 Cloud9을 제공 한다. (Cost Saving Mode)
  • 서버리스 리소스가 허용된다.
    • AWS Lambda
    • Amazon API GW
    • Amazon DunamoDB
    • Amazon S3
  • SSO를 통한 Console Access를 제공한다
  • Access Key와 같은 LongTerm Credentials는 제공하지 않음

네트워크 설계

아키텍처 현대화 과정에서 네트워크를 설계할 때에 가장 염두에 두었던 부분은 레거시 환경의 워크로드들과 써드파티에서 제공하고 있는 워크로드들 그리고 서로 다른 비지니스 유닛의 리소스들이 구분되지 않고 네트워크 영역을 공유하고 있는 부분을 제거하고 각각의 워크로드들이 서비스 단위로 독립적인 네트워크 위에서 구동될 수 있도록 설계하는 것이었습니다. 결과적으로 VPC 단위로 워크로드들을분리하였고 환경에 대한 구분은 AWS 어카운트 수준으로 분리하였습니다. 자세한 내용을 풀어쓰기에는 내용이 많기에 설계 원칙을 간단히 정리하면 다음과 같습니다.

  • 워크로드 별로 VPC 분리
  • 환경에 대한 부분은 어카운트 수준으로 분리
  • 쿼럼(quorum)구성이 필요한 서비스를 위하여 3AZ를 기본으로 사용
  • 모든 어카운트에는 기본(Default) VPC를 포함하지 않음 (Account Factory를 통해서 구성)
  • VPC간의 연결은 피어링보다는 엔드포인트 연결을 지향
  • 모든 서브넷에는 SSM EndPoint를 구성하여 ssh-key를 사용하지 않고 SSM을 통해 액세스 하며 audit log를 자동 기록

리소스 네이밍 규칙

AWS Control Tower를 도입 하면서 가장 신경 쓰이는 부분은 OU 및 각각의 구성 요소에 대한 네이밍 규칙을 어떻게 가져갈까하는 부분이었습니다. 컴퓨터공학 3대 과제 중 하나가 ‘변수 이름 짓기’라는 이야기도 있듯이 네이밍 규칙은 상당히 고민이 되는 부분 중에 하나 입니다. 특히 IaC를 도입 하면서 리소스의 네이밍 규칙 뿐 만 아니라 태그의 네이밍 규칙도 어려워지는 것을 느끼게 되었습니다. 저희가 고민했던 리소스 네이밍 규칙의 일부를 공유해 보면 아래와 같습니다.

리소스의 쿼리를 쉽게 하고 분석에 도움이 될 수 있도록 필요하다고 생각되는 정보들을 추가하게 되었는데 일관된 정보를 얻을 수 있다는 것은 뒤에서 말씀 드릴 IaC 개발 과정에서 큰 도움이 되었습니다.

컨트롤

AWS Control Tower를 도입 시 얻을 수 있는 또 하나의 장점은 OU를 구성하면서 AWS 모범 사례를 기반으로 한 컨트롤을 제공하고있다는 점입니다. 이를 통해 중앙에서 정책적으로 권한을 통제하고 계정을 감사할 수 있습니다. 컨트롤을 활용해서 OU 단위에서 권한을통제하면 해당 OU에 속한 어카운트 수준에서의 통제와 감사가 가능합니다. 컨트롤의 유형은 예방적(preventive) 컨트롤과 탐지형(detective) 컨트롤이 있습니다. 각각의 컨트롤들은 강력 권고(Strongly Recommended), 필수(Mandatory), 선택(Elective)으로 구분됩니다.
저희는 컨트롤에 관련해서는 처음부터 너무 타이트하게 구성하여 운영하는 것보다는 필수 컨트롤들을 우선적으로 고려하고 강력 권고컨트롤을 그리고 선택적 컨트롤을 하나씩 적용해 나가는 작은 시작(Small Start) 방식으로 진행하기로 결정하였습니다. 우선적으로 고려한 컨트롤은 아래와 같았습니다.

AWS 솔루션즈 아키텍트분께서 제공한 다양한 참고용 템플릿이 많은 도움이 되었습니다.
AWS 모범사례로 제공되는 컨트롤로도 이미 많은 것들이 해결되지만 저희는 Compliance As Code를 추구하고 있고 여러 가지 상황에 맞춰서 커스텀 한 룰들을 사용하려고 하고 있기 때문에 AWS RDK 도입을 시작하였고 내부 숙련도를 높이고 있습니다.

AWS IAM Identity Center

AWS Control Tower는 이름에 걸맞게 AWS IAM Identity Center(구 AWS SSO)를 통해 멀티 어카운트를 통합적으로 관리할 수있는 Account Federation 기능을 함께 지원하고 있습니다.

1. 모든 IAM 사용자 제거
AWS IAM Identity Center 구성을 통해서 IAM 사용자를 제거함으로써 오랜 숙원이던 LONG-TERM CREDENTIALS들을FADE-OUT 시킬 수 있었습니다.

  • 콘솔 로그인 : AWS IAM Identity Center 포털 사용
  • CLI : AWS CLI v2 를 사용

AWS IAM Identity Center 사용자의 권한은 ROLE에 의해서 STS로 부여되기 때문에 만료시간을 가지고 있는 임시 자격증명을 사용하기 때문에 자격 증명 유출로부터 좀 더 안전합니다.

2. 그룹과 권한세트
AWS IAM Identity Center를 구성할 때 그룹과 권한세트를 잘 정하는 것이 중요합니다. 이럴 때는 다음과 같이 조직과 구성원의 역할그리고 해당 역할이 접근해야 하는 리소스들에 대하여 식별하고 매트릭스 형태로 표현하여 생각을 정리하는 것이 도움이 됩니다.

또한 기존에 이미 사용되고 있던 IAM 유저와 ROLE 등에 대한 권한을 조사해야 하는 작업도 필요할 수 있는데 이 부분은 저희의 데브옵스 엔지니어인 최준영 님이 작성하신 스크립트를 사용하시면 큰 도움이 되실 것입니다.

3. AWS IAM Identity Center 와 ABAC
AWS IAM Identity Center의 사용자와 AWS 리소스 사이의 관계를 ABAC을 통해 접근제어를 구현하려면 사용자에게 IAM Identity Center > Settings > Manage attributes for access control 메뉴에서 다음과 같이 AWS IAM Identity Center에서 사전에 정의된 속성값들을 원하는 값들로 매핑을 해주어야 할 필요가 있습니다. 새로운 속성값을 위한 Key 값을 늘리는 것이 아니라 매핑하여 Override 하는방식이다 보니 어색하게 느껴지기도 하지만 곧 적응할 수 있으실 것입니다.

4. 인라인 권한세트 구현
AWS IAM Identity Center의 권한 세트를 생성할 때 특정 어카운트에 원하는 정책을 지정하는 방법은 두 가지 방법이 있습니다.

  • 원하는 관리형 정책을 해당 어카운트에 미리 프로비저닝
  • 권한 세트에 지정되는 정책을 인라인 정책으로 생성

우리가 IAM에서 정책을 만들어 사용할 때 모범사례처럼 이야기되던 것이 인라인 정책은 재활용이 안되고 관리가 어렵기 때문에 웬만하면 관리형 정책을 만들어서 사용하는 것이 좋다는 것이었습니다. 하지만 SSO를 위한 권한 세트를 구현하다 보면 오히려 관리형 정책을사용하는 것이 훨씬 어렵게 느껴집니다. 그 이유는 해당 어카운트에 원하는 정책을 미리 프로비저닝 해놓아야 하는데 이 작업이 상당히번거롭게 느껴지기 때문입니다.
이 부분은 IaC를 사용할 경우 인라인 정책을 통해서 손쉽게 구현할 수 있습니다. IaC에서 작성된 인라인 정책은 관리가 편하고 재사용 가능하기 때문입니다. 아래는 테라폼의 template_file 기능을 사용하여 저희가 구현한 예시입니다. 다만 인라인정책의 경우 IAM 사용자의 경우 2,048 바이트, IAM 역할의 경우 10,240 바이트, 그룹의 경우 5,120 바이트의 제약사항을 가지고 있다는 것을 참고 하시기 바랍니다.

아키텍처 현대화

IaC 구현

AWS Control Tower의 도입과 함께 신규 아키텍처를 설계하고 구현 하면서 IaC 도구로 테라폼을 선정 하였고 멀티 어카운트에서의 프로비저닝을 위해 module 과 live로 두 개의 리포지토리를 구성하였습니다. 복잡한 구현과 재사용성에 대한 부분은 module에 감추고 운영 환경(live) 에서는 최대한 단순한 구성으로 가독성 있게 인프라 리소스를 관리하는 것에 초점을 두었습니다.

  • Module 리포지토리 컨셉 설계: 모듈은 ‘module’ prefix에 상위레벨의 기능의 묶음을 표현하는 component 레벨 그리고 해당 component를 구성하는 리소스 레벨로 구성 하였습니다.
  • Live 리포지토리 컨셉 (dev, stg, prod, management): dev, stg, prod, management 환경은 각각 어카운트 수준으로 격리되어 있으며 각각의 서비스들은 서비스의 구성요소별로 테라폼 스테이트를 독자적으로 가지도록 고려되었습니다.

DB 프록시 레이어 구성

AS-IS 환경에서는 서비스 애플리케이션이 RDS 서비스와 직접 연결되어 있었기 때문에 성능 및 리소스 효율성에서 좋지 못한 구조를 가지고 있었던 상황이었습니다. 이 부분을 개선하기 위해 기존 RDS PostgreSQLAurora PostgreSQL로 마이그레이션을 진행을 결정하였고 Read/Write 요청에 대한 분리의 장점을 누리면서 DB 커넥션의 재활용을 쉽게 할 수 있는 방안을 고민하게 되었습니다. 여러가지 도구들을 검토한 결과 저희에게 최적화된 도구는 Pgpool-II이라는 결론을 내리게 되었고 이를 위한 아키텍처를 다음과 같이 설계하였습니다. SysbenchLocust를 통한 성능테스트 진행을 통해 기존보다 최대 다섯배 정도의 처리량을 확보하면서 DB를 다운사이즈 할 수 있다는 결론을 얻었고 마이그레이션을 진행하여 현재 운영환경에서 안정적으로 동작하고 있습니다.

개발환경의 기능(feature) 브랜치 별 엔드포인트 워크플로우

새롭게 개발환경의 CI/CD 파이프라인을 재구성하면서 고민했던 부분은 개발 편의성과 테스트 편의성을 위한 고민이었습니다. 프론트엔드 앱의 배포를 AWS Amplify 로 가져가게 되면서 피처 브랜치를 손쉽게 배포 하고 테스트 할 수 있는 장점을 얻을 수 있었습니다. 이러한 장점을 백엔드에서도 가져가기 위해서 백엔드의 기능(feature) 브랜치가 PUSH 될때에 해당 브랜치에 대한 백엔드 엔드포인트를ArgoCD를 이용하여 POD로 프로비저닝하여 개발환경에서 손쉽게 프론트엔드와 연결하여 테스트가 가능하도록 하여 생산성을 높일 수 있었습니다. 또한 해당 브랜치가 삭제되면 POD도 함께 삭제되도록 구현하였습니다. 이러한 CI/CD 워크플로우 아이디어는 사실 Trek10에서 제공하던 서버리스 솔루션에서 예전부터 접할 수 있었는데 GitOps 도구인 ArgoCD를 이용하여 어렵지 않게 구현하였고 개발 및 테스트 생산성을 높일 수 있었습니다.

결론

AWS 클라우드를 기업 초기부터 도입하여 비즈니스를 성장 시켜온 많은 기업들은 아키텍처 현대화를 준비하고 있을 것입니다. 그리고 이를 위한 다양한 우선순위와 기업의 상황에 맞는 여러 가지 전략이 있을 것입니다. 만약 여러분께서 아키텍처 현대화를 준비 중이고 어디에서부터 시작하면 좋을지 고민 중이라면 먼저 AWS Well-Architected 프레임워크를 통해 자가 진단을 진행해 보시길 바랍니다. 방향성 수립에 큰 지표를 얻으실 수 있을 것입니다. 또한 AWS Control Tower를 적극적으로 활용 하신다면 기술검증을 위한 환경 구성을 손쉽게 할 수 있는 것은 물론이며 모범 사례 기반의 클라우드 거버넌스를 토대로 아키텍처 현대화를 가속화하실 수 있을 것입니다. 또한, 본문에 언급 하지는 못하였지만 Graviton2 인스턴스 도입의 경우도 아키텍처 현대화의 필수적인 요소라고 생각됩니다. 저희 같은 경우 파이썬환경의 장고(Django) 프레임워크로 구성된 OLTP성 워크로드에서 처리량과 응답속도에서 평균 20%정도의 이점을 얻으며 비용 효율적인 운영을 할 수 있었습니다.

Sungshik Jou

Sungshik Jou

주성식 실장은 새로운 것을 찾아내고 가까운 곳에 적용해 보기를 좋아하는 탐구자. 늘 배우는 것에 주저하지 않고 배움 앞에 겸손한 학생이 되고 싶습니다. 단비교육에서 SRE, 보안, QA, 서비스운영 조직을 리딩하고 있습니다.

Injae Park

Injae Park

박인재 시니어 솔루션즈 아키텍트 매니저는 Digital Native 고객을 포함한 한국 고객들이 Cloud Governance를 포함한 Cloud Operation 영역에서 고객이 최적의 아키텍처를 구성하여 고객의 비즈니스 성과를 달성하도록 돕고 있습니다.