Serverless
Serverless 방식이 추구하는 성과는 충분히 설득력이 있다. 유지보수와 변경관리를 쉽게 만들고, 운영 환경에서의 자원 관리를 효율성을 높인다. 이 성과를 취하기 위해서는 변화를 수용해야 한다. 경험에 비추어 봤을 때, 팀 단위로 움직이고 있는 프로젝트에서는 변화의 정도에 비례하여 저항이 발생한다. Serverless 방식이 제공하는 구조적인 장점을 온전히 취하면서, 프로젝트에 환경에 맞게 최적화 하는 일은 기존에 동작하고 있는 업무 프로세스의 성숙도가 높을수록 큰 저항이 발생할 가능성이 높다.
이 글은 개별 엔지니어의 생산성을 넘어서 프로젝트 혹은 팀의 생산성과 성과에 대해 고민하고 있는 소프트웨어 엔지니어들과 나누고 싶은 이야기이다.
코드 작성에 사용하는 툴이나 프로그래밍 언어, 혹은 새로운 개발 프레임워크의 도입은 Serverless 방식을 온 전히 적용하는 것에 비하면 단순한 변화라 할 정도다. 이 포스트에서 경험을 바탕으로 다음의 주제에 대해서 생각을 나눠 보고자 한다:
- 왜 Serverless 방식을 선택해야 할까?
- 바꿔야 하는 것들
- 주어진 비즈니스 환경에서 성공에 기여하기 위한 소프트웨어 개발 전략과 기술적인 구현 사례
왜 Serverless 방식을 선택해야 할까?
왜 해야 하는지 따라서 어떻게 할 것인가가 결정된다.
소프트웨어 업계에서 'No Silver Bullet'1은 널리 알려진 명제이다. 특정 관점에서 우월할 수 있는 어떤 선택도 다른 관점과 상충(trade-off) 되는 경우는 매우 흔하다. 무엇보다도 소프트웨어 시스템은 순수 창작물이 아니라 비즈니스를 지원하고 혁신하기 위해 사용되기 때문에 비즈니스 환경 변화에 따라 적응해야 하는 것은 필연적이다. 이러한 특성에 비추어 Serverless 방식의 도입의 이유는 단순하고 직관적이다. 비즈니스 환경의 움직임을 자동차와 비교하면 이 생태계는 항상 accelerator-pedal을 힘껏 밟고 있다. 단순히 특정 방향으로 움직이고 있는것이 아니라 항상 가속을 하고 있는 것이다. 역사적으로 이 위태로워 보이는 질주를 지속하는 방법은 감속 장치((brake))를 발전시키는 것이 아니라, 더 단단한 섀시(chassis)와 스테빌라이저(stabilizer)를 보완하면서 동시에 더 빠른 가속 장치를 추가하는 것이다. Serverless 방식은 새로운 가속 장치이다.
산업 현장에서는 소프트웨어 시스템을 활용해서 비즈니스 기회를 확장하고 실행을 가속화 하고있다. 소프트웨어 제품의 구현과 유지보수도 이러한 속도에 발을 맞춰야 한다. 이 변화는 이미 정립된 기술 분야의 연속적인 발전으로는 설명하기 힘들다. 이 변화의 속도는 구조적인 진화에서 비롯된 것이다.
소프트웨어를 기초로 인터넷을 통해 연결된 디지털 세계는 비즈니스의 한 관점에서 보면 일종의 실험실이다. 위험(risk)를 효과적으로 관리 하면서 구상하고 있는 비즈니스를 실증하고 동작시켜볼 수 있는 기회다. 시장 경쟁 구도 속에서 이 실험을 얼마나 효율적으로 실행하고 효과를 극대화 하느냐 하는 것이 비즈니스의 경쟁력에 영향을 미친다. 개별 실험들은 시스템화 되면서 체계적으로 조직되어 개별 실험의 생명 주기는 더 빨라지고, 데이터로 확인된 기회들은 비즈니스 가치로 변환된다. 소프트웨어 개발, 즉 구현 관점에서는 실질적으로 동작하여 사용자에게 전달될 수 있는 소프트웨어 제품들이 이러한 프로세스에 맞춰 공급돼야 한다. 빨리 만들어서 사용자에게 공개 해야 하는 것이다.
일정 수준 이상 품질의 소프트웨어를 개발하는 역량은 개별 엔지니어의 역량과 밀접한 관련성이 있을 수 있다. 하지만 프로젝트의 규모가 일정 수준 이상 커지면 개인의 역량으로는 제어할 수 없는 위험 요소들이 생긴다. 그 중 한가지가 제품을 배포하고 변경을 관리하는 부분이다. 소프트웨어의 본질적인 속성에 의해 소프트웨어는 지속적으로 변경된다. 이 속성 은 비즈니스 환경의 변화를 수용할 수 있는 기초가 되기도 한다. 문제는 이 변경이 동작하고 있는 제품과 지원하고 있는 비즈니스 성과에 영향을 미치는 위험 요소라는 것이다. 개발 과정에서 발견되지 못한 프로그램 오류나 기대하지 않은 부작용(side effects)과 같은 현상을 개별 엔지니어의 역량 만으로 통제 하는 것은 불가능한 일이다.
바꿔야 하는 것들
운영 환경(코드가 최종적으로 동작하는 환경)에서 개발하기
코드를 작성한 개발자가 확인해야 하는 것은 이 코드가 실제 사용자의 요청을 제대로 처리할 수 있는가 하는 것이다. 소프트웨어가 놀라울 정도로 잘 작동하기 때문에 사람들은 종종 실체적 복잡성과 위험에 대해 잘 생각하지 않는 듯 하다. 개발 환경에서 실행한 빌드의 결과와 배포 과정에서 실행한 빌드의 결과는 정말 같을까? 개발 환경의 느슨한 보안 정책으로 인해 잘 동작하던 외부 API연동은 운영 환경에서도 당연히 문제 없이 동작할까? 프로그램이 참조하고 있는 특정 환경 변수의 값은 내 컴퓨터의 메모장에만 존재하는 것은 아닐 까? 컨테이너 기술의 보급은 큰 의미가 있는 진보이다. 작성된 코드가 최종적으로 사용자에 의해 사용될 수 있도록 만들기 위한 모든 단계에서 위험성을 제어할 수 있는 기반을 마련했다.
Serverless 방식을 고려 한다면 운영 환경은 일반적으로 클라우드 서비스가 제공한다. 클라우드 서비스에서 동작하는 개발 환경이 필요하고, 상당히 잦은 주기로 로컬 개발 환경의 작업물이 동기화 되고 테스트 케이스의 실행 결과를 확인할 수 있어야 한다. 여기에 더해서 Serverless 어플리케이션의 주요 전략 중 하나가 상태 관리의 책임을 분리하는 stateless라는 것을 생각 해 본다면, 상태를 관리하는 어떤 컴포넌트와의 연동이 필요할 것이다. 우리의 경험을 통해서 제안하고자 하는 방법은 클라우드 환경에 개별 소프트웨어 엔지니어를 위한 개발 환경을 제공하는 것이다. github에서 제공하는 Codespaces와 AWS의 CodeCatalyst와 같은 서비스가 좋은 대안이다. 우리 팀은 개발과 운영 환경으로 사용하고 있는 AWS와 더 쉬운 통합을 위해 CodeCatalyst를 선택했다.