2022년 4월 8일 금요일

당신이 AWS 계정을 만들고 가장 먼저 해야 할 일 들과 하지 말아야 할 일 들 (2022년 업데이트)

 이 글은 tmknom님이 Qiita에 올려주신 'AWS 계정을 만들고 나서 바로 해야 할 일들 정리(AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ)'에서 영감을 받아 작성되었습니다. 처음 AWS 계정을 만들고 나서 무엇을 해야 할 것인가도 중요하지만 하지 말아야 할 것을 아는 것도 중요하기 때문에 해야 할 것들과 하지말아야 할 것들에 대해서 정리해 보았습니다. 전체 과정은 따라하는데 약 30분 정도가 소요됩니다. 아직 계정이 없다면 계정 생성을 먼저 진행해 주세요.


AWS 계정(루트 사용자) 보호

루트 사용자란?

AWS에 가입할때 맨 처음 만드는 이메일주소와 패스워드로 인증하는 계정을 루트 사용자 라고 합니다. 이 루트 사용자는 그야말로 모든 권한을 지니고 있으며 권한에 대한 제약이 불가능하기 때문에 각별히 신경써서 다루어야 합니다. AWS의 모범사례에 의하면 AWS 루트 사용자를 만든 이후 가장 먼저 해야 할 일은 IAM 계정을 만들고 권한을 부여할 수 있는 IAM 관리자 계정을 만들고 이후 루트 사용자 대신 그 계정을 사용하는 것 입니다. 루트 사용자는 원칙적으로는 평상시엔 사용하지 않는 것이 좋습니다. 혹시 이 글을 읽으시는 분 중에 아직 루트 사용자를 이용하여 작업을 하시는 분이 계시다면 지금 즉시 관리자 권한을 지닌 IAM유저를 만들고 루트 사용자의 사용을 중지하시기 바랍니다.


AWS 루트 계정에 대한 액세스 키를 만들지 말 것

AWS는 패스워드 인증 이외에 CLI나 SDK 사용을 위한 액세스 키 인증을 제공합니다. 하지만 루트 사용자에 대해서 액세스 키를 만들지는 마세요. 이미 있다면 삭제하시고 다른 IAM유저의 액세스 키를 사용해서 작업하시기 바랍니다.


루트 사용자 암호 변경

루트 사용자의 경우 강력한 암호를 사용하시기 바랍니다. 루트 사용자의 암호 변경 방법은 아래 링크에서 확안하실 수 있습니다.


루트 사용자에 대해 MFA 활성화

보안을 강화하기 위해 패스워드만 사용한 인증보다는 MFA(Multi-Factor Authentication)을 사용한 인증을 설정해 두세요. AWS에서는 Google Authenticator와 같은 개방형 TOPT 표준을 지원하는 애플리케이션이나 U2F보안키를 MFA에 사용할 수 있습니다. 루트 사용자의 인증에 MFA를 설정하는 방법은 아래 링크를 참고하시기 바랍니다.


관리자용 IAM 그룹과 사용자의 작성

관리자용 IAM그룹을 만들고 IAM 사용자를 작성하여 관리자 그룹에 배치시킵니다. 구체적인 방법은 아래 링크를 참고하세요.

IAM유저 중에서도 관리자 권한과 같은 강력한 권한을 지닌 유저에 대해서는 루트 유저와 마찬가지로 MFA사용이 필수 입니다. 


암호 정책 구성

관리자용 계정으로 로그인 한 후에 암호 정책을 설정하여 IAM 사용자의 암호에 대하여 복잡성 요건과 의무적인 교체주기를 지정할 수 있습니다.


보안 상태(Security Status)의 확인

여기까지 진행하셨다면 AWS를 안전하게 사용하기 위한 최소한의 조치가 완료되었습니다. IAM 서비스 페이지로 이동하여 대시보드 상에서 보안 권장 사항이 다음과 같이 모두 녹색이 되어 있는것을 확인합니다.


청구정보 관련 설정

IAM에 대한 설정이 끝났다면 다음은 청구정보에 대한 설정을 진행해 봅시다.


IAM유저의 청구서 정보에 대한 액세스 허가

기본설정에서는 루트 사용자 이외에 유저가 청구정보에 접극하는것이 허가되어 있지 않습니다. 루트 사용자를 가급적 사용하지 않기 위해 IAM유저가 청구서 정보에 접근할 수 있도록 허가해 봅시다.

IAM유저에 대해 결제 정보 액세스를 허용했다면 이후 작업은 관리자 권한을 지닌 IAM유저를 사용해서 진행 할 수 있습니다.


청구정보와 비용 관리에 대한 설정

이메일로 청구서 받기

아래 링크의 지시에 따라 간단한 설정으로 이메일로 청구서를 받아볼 수 있습니다.


프리티어(무료 용량) 한도 초과 경보 

또한 프리티어 한도를 초과할 경우 메일이나 휴대폰 문자(SMS)를 통해 알려주는 결제 경보를 생성할 수도 있습니다.


월별 예상 요금 경보 만들기

Amazon CloudWatch를 이용하면 월 초에 사용 용량을 측정하여 월간 예상 AWS 요금에 대해 경보를 받아 볼 수 있습니다.


그 밖의 설정들

git-secrets

git-secrets는 AWS가 만들어 공개하고 있는 툴로서 시크릿 액세스키와 같은 비밀 정보가 git에 커밋 되는 것을 막아줍니다.

GitHub에는 이렇게 잘못 올라온 비밀정보를 노리는 봇들이 수없이 동작하고 있어 실수로 정보가 공개되게 되면 악용되게 될 소지가 큽니다.


루트 계정 이메일 주소 변경

AWS에서는 여러가지 보안 관련 중요한 사안들에 대해 이메일로 통지되기 때문에 루트 계정의 이메일은 항시 사용 가능한 상태여야 하며 즉시 받아 볼 수 있는 메일 주소여야 합니다. 만약 기존 루트계정을 생성할때 사용했던 이메일을 변경하고 싶다면 아래 지침대로 이메일을 변경하시기 바랍니다.


끝으로

이것으로 일단 가장 기본적인 보안 및 비용 관련 설정이 끝났습니다.

추가적으로는 아래 IAM 모범 사례의 내용을 살펴보고 적용시킴으로서 더욱 강력한 보안을 확보 할 수 있습니다. 몇가지는 이 글과 겹치는 부분도 있지만 상세한 내용을 읽고 확인해 두는것도 좋을듯 합니다.

2020년 10월 5일 월요일

[번역] WeWork 대신 iWork에서! "내가 생각한 최고의 개라지 오피스" 구축기

 이 글은 전 AWS Japan 마케팅 헤더이자 현재는 커뮤니티 마케팅 전문가로서 일본의 여러기업에서 왕성한 활동을 이어나가고 있는 Ojima Hideki씨의 블로그 글을 본인의 허락을 받아 번역한 것 입니다. 

Ojima씨는 현재 여러 회사에 동시에 적을두고 활동하고 있으며 이러한 근무 방식을 글 안에서 '병렬 경력(Parallel career)'이라고 표현하고 있습니다.


리모트 워크가 일반화된 시대가 되었습니다. 사무실에는 좀처럼 갈 수가 없지만 그렇다고 해도 집은 장시간의 업무에 적합하게 설계되어 있지 않습니다. 이러한 이유로 WeWork가 아니라 '내가 생각한 최고의 사무실'을 직접 만들어 보았습니다!


코로나 사태 이전부터 가지고 있었단 사무실 구상(이라고 쓰고 망상이라고 읽는다)

자신의 사무실을 가지려는 생각은 지금 일을 시작했을 때 부터 가지고 있었으며 실제로 집을 보러 다니고 있었습니다. 뒤돌아 보면 저는 2018년,  마이크로소프트 테크서밋에서 니시와키씨, 사킨씨와 가졌었던 패널 토론에서도 'iWork를 만들겠다!'라고 선언한 바가 있습니다. 

그러나 이 구상이 좀처럼 구체화 되지 못한 가장 큰 이유는 '바이크를 실내에 둘 수 있는 집이 없다'라는 것 입니다. 개라지 오피스는 남자의 로망입니다. 기왕에 나만의 사무실을 만든다면 그것만큼은 양보할 수 없다고 생각했는데 여기에는

  • 1층의 도로에 접한 건물
  • 집주인이 바이크를 건물 내에 주차하는 것을 허락할 것
  • 현실적으로 임대 가능한 물건

이라고 하는 세 가지 장애물이 있어서 이를 충족하는 물건은 좀처럼 찾을 수 없었습니다. 특히 집주인의 허락을 받는것이 어렵더군요. 특히나 집주인들은 임대해준 집에 휘발유로 움직이는 바이크를 주차한다는 것에 난색을 보였습니다.

또한 현재 적을 두고 있는 회사의 대부분이 도쿄 중심지에 멋지게 꾸며진 사무실을 가지고 있었습니다. 그곳을 사용한다면 편안하게 작업 할 수 있기 때문에, 솔직히 자신만의 사무실에 대한 필요성도 그다지 크지 않은 것도 사실이었습니다. 이러한 이유로 차고를 지닌 사무실을 갖고 싶다는 망상은 좀처럼 실현되지 않는 상황이었습니다.


코로나사태로 인한 리모트워크 퍼스트와 갑자기 실현된 iWork구상

제 주변에 외국계 IT회사에 근무하는 사람이 많은 탓도 있지만, 코로나 대유행으로 인해 올 3월 무렵 대부분의 작업이 리모트 워크로 전환되게 됩니다. 그리고 이 상황은 2020년9월인 현재에도 이어지고 있습니다. 리모트 워크로 인해 전철등의 출퇴근에서 해방되는것은 물론 환영할만한 것이었고, 집의 인터넷 환경도 비교적 쾌적했기때문에 이러한 흐름에 반감이 들지는 않았지만, 역시 집이라는 공간은 장시간 업무를 하기엔 적합하지 않았습니다.

한동안 나는 침실에서 일을 하고, 두 아이는 각자의 방에서 온라인 수업을 듣는 생활을 했습니다. 세 명 모두 각자의 방에 틀어박혀 있는 동안 아내는 거실밖에 있을 수 있는 공간이 없었는데, 각자의 방을 청소하는 타이밍을 잡기도 어려웠습니다. 그런데, 도심의 수많은 멋진 사무실에 갈 기회가 없어진 바로 이 타이밍에, 갑자기 나의 iWork 구상을 실현시켜줄 집이 눈앞에 나타난 것 입니다!

뼈대로부터 시작

이번 물건은 원래 타코야키 배달 전문점에서 사용하던 것으로, 1. 도로에 접해 있으면서 폭이 넓고(바이크 출입이 쉽다!), 같은 건물에 바이크 가게가 들어온 적이 있어서 2. 바이크를 실내에 주차하는것에 대해 주인의 허락을 받기 쉬웠고, 3.물건이 10~15년 후 재건축을 검토하고 있는 낡은 건물이다보니 집세도 비교적 저렴했습니다.

사실 오랫동안 이 물건은 공실로 되어 있는것을 알았기에 "저기라면 싸게 빌릴 수 있을것 같고, 집에서도 가깝기 때문에 좋을텐데..."라고 생각했습니다만, 10년 후에 있을 재건축 전 까지만 임대가 가능하다는 계약조건 때문에 음식점에서는 실내 인테리어 비용등을 회수하는데 있어서 부담을 느껴 잘 나가지 않고 있었던것 같습니다. (역자 주: 한국 기준으로는 이상하게 들릴지 모르겠지만 일본은 같은 자리에서 10년 이상 음식점을 하는 경우가 매우 흔하다)

제가 맺은 계약도 10년 계약으로서 최악의 경우 계약 만료 전에 건물이 철거될 가능성도 있지만, 제 경우 어차피 사무실로 이용할 것 이기 때문에 비용처리가 가능하므로 ROI를 그렇게까지 엄격하게 따질 필요는 없었다는 것과, 10년 후에는 내 나이도 60을 지나고 있을테니 우선은 그 때 까지만 쓸 수 있으면 좋지 않을까 라고 생각했습니다.

그리고 집에서 근처 역으로 가는 길에 있었기 때문에 집에서의 출퇴근 뿐만이 아니라 사무실에 가기 전이나 후에 들럿다 가기에도 좋은 위치적으로 편리한 물건이라는 점에서 저에겐 딱 맞는 물건을 만나버린 느낌이었습니다.

앞서 언급했듯이, 이전에는 타코야키집이었지만, 당시의 시설과 인테리어는 완전히 철거되어 있어서 블럭과 콘크리트에서 시작해야 했습니다.


이것이 바로 물건을 보러 갔을 때의 사진입니다. 전기도 들어오지 않는 상태에다 바깥쪽 셧터도 열지 않은채 어둠속에서 물건을 확인했습니다. 하지만 충분한 넓이(약 15평)가 있었으며, 완전히 뼈대만 남겨놓은 상태였기에 비록 한정된 예산이긴 했지만 내 취향의 인테리어가 가능했기에 계약 의사가 굳어져 갔습니다.

개라지 오피스를 만드는데 있어서 물건 찾기보다 힘든것이 사실은 시공 업자 선정입니다. 대부분의 인테리어 업자들은 개라지 오피스를 만든 경험이 없으며, 원래 바이크를 좋아하는 사람이 담당자가 되는 경우도 흔치 않으므로 말이 통하지 않는 경우가 많습니다. 그래서 나의 구상을 설계와 목공에 강한 이벤트 시공업자 분들에게 이번 사무실 공사를 의뢰하기로 했습니다. 이러한 업체 분들과의 대화는 나 또한 많은 경험이 있기 때문에 편하다 라는 것과 코로나 사태로 인해 이벤트 수가 급감하여 결과적으로는 제 사무실 만들기에 시간을 내어주실 수 있었습니다. 아래 사진은 인테리어 공사를 담당한 팀이 처음 사무실 자리를 방문한 사진입니다. 이때 처음으로 셔터를 열고 바이크를 주차하기에 충분한 공간이 있는지와 출입이 가능한지를 확인 했습니다.


제가 시공 팀에게 제시한 요구 사항들은 다음과 같습니다.
  • 여러대의 바이크 보관
  • 헬멧이나 바이크 수트의 보관
  • 캠핑장비, 자전거 관련 용품의 수납
  • 작업 공간은 곡면의 대형 모니터와 넓고 높낮이 조절이 가능한 책상
  • 방송 제작에 충분한 조명
  • 유튜브와 웨비너를 위한 크로마키 벽면
  • 풍부한 전원 콘센트
  • 초고속 인터넷
  • 바 카운터로 사용 할 수 있는 미니주방
기본적으로 나만을 위한 작업 공간이지만, 지금까지 자신이 모아온 캠핑도구와 바이크들, 주차된 바이크, 자동차를 감상할 수 있어야 할 것, 그리고 4~6명정도 앉을 수 있는 바 카운터와 유튜브 스트리밍이 가능한 스튜디오 공간이라는 것이 저의 요구사항이었습니다.

전체적인 분위기는 까페 보다는 미국식 개러지를 지향하기로 했습니다.

그리하여 초기에 나온 계획이 이것 입니다.

이것으로 위 요구사항들이 포함되어 있는것을 확인 할 수 있었으므로, 나머지는 시공을 진행하면서 그때그때 디자인, 위치, 조달되는 자재등을 확인하는, 마치 이벤트 부스를 인터렉티브하게 설계, 시공하는것과 비슷한 느낌으로 진행해 갔습니다. 대략 디자인과 예산을 정하는데 한달 반 정도, 시공에 한달 정도가 걸렸습니다.

현지 확인을 통한 애자일한 진행


작업 첫날인 8월3일의 모습입니다. 바로 앞에 작업 및 자재 반입을 위한 트럭 주차가 가능하다는 것도 이 물건의 장점중 하나 입니다.


인테리어 공사에 들어가기전, 우선은 철저하게 청소를 합니다.


인테리어도 실물을 현지에서 확인하면서 결정해 가는 방식입니다.


벽면 인테리어가 진행된 것 만으로도 단번에 이미지가 달라졌습니다.


영상 촬영과 웨비너의 배경으로 사용될 부분도 현지에서 결정했습니다.


이번에는 바이크의 실내주차 관련해서 소방소에 신고하는 절차입니다. 소방서 분들이 작접 오셔서 현지 확인도 마쳤습니다.


책상이나 조명등이 들어서자 상당히 모양이 갖춰지기 시작했습니다.
(사진 준비중)

자전거는 벽에 걸어두었습니다.


폭이 제법 있기 때문에 바이크가 주차된 상태에서도 낮잠을 잘 수 있는 접이식 대형 해먹을 놓을 자리도 나옵니다.



Still Day One!


인터넷등 아직 일부 작업이 남아 있긴 하지만 거의 시공이 완료된 덕분에 2020년 9월 1일 부터 사무실 운용을 개시 했습니다!


9월1일은 이전 직장인 AWS Japan을 2016년 8월 31일에 퇴직하고 지금의 경력을 시작한지 딱 4년째가 되는 시점이었습니다. 이거야 말로 Still Day One을 다시 확인시켜준 하루가 되었네요. 앞으로 이 사무실에서 보낼 10년동안 또 어떤 새로운 일을 만날지 두근두근 합니다.

작금의 코로나 사태로 인해 여러모로 신경이 쓰입니다만, 여러분을 사무실에 초대할 수 있는 시기가 온다면 꼭 방문해 주시길 희망합니다.

그 전 까지는 스트리밍과 웨비너를 통해 온라인으로 방문해 주셨으면 합니다. 웨비너를 원하시는 분은 연락 주시기 바랍니다!


2019년 1월 27일 일요일

소프트웨어 엔지니어 육성법으로서 패턴 언어의 가능성

디자인 패턴의 기원

일반적으로 GoF의 디자인 패턴이라는 이름으로 잘 알려진 디자인 패턴은 원래 건축가 크리스토퍼 알렉산더가 설계자와 사용자의 단절을 해체하기 위해 도입한 패턴 언어에 그 뿌리를 두고 있다.

여러 단어들이 모여 한 문장이 되고, 여러 문장들이 모여 하나의 글이 되듯이, 여러 패턴이 모여 하나의 패턴 언어가 되어 사람들이 기분 좋다고 느끼는 환경에 대한 분석을 가능하게 한다. 크리스토퍼 알렉산더에 의하면 각각의 패턴은 세계 각국의 아름다운 도시 및 주거 공간에 공통적으로 적용되는 보편적인 것으로, 예전에는 누구나 알고 있었던 것이지만 급격한 근대화로 인한 현대 도시 계획이 진행되면서 점차 잊혀져 버린 것이라고 한다. 각각의 패턴은 현대 도시 계획의 발상과는 정반대의 발상을 갖고 있으며, 인간적 척도 요소가 중시되고 있다.
바람직한 사회 전체를 한 번에 설계 및 건설 하는 것은 불가능하지만, 각각의 패턴에 따라 하나 하나의 진행되는 과정에서 일종의 커뮤니티를 형성하여 간다. 이러한 각각의 패턴을 찾아내는 것은 해당 도시 및 주거 공간에 거주하는 주민 자신이며, 건축가는 그들이 패턴을 찾아가는 것을 도와주고, 실제 모양이 되도록 설계 및 시공 감리를 하는 역할을 맡는다.     출전: 위키백과 패턴 언어페이지

크리스토퍼 알렉산더는 오늘날의 건축이 사용자를 위한 건축이 아닌 시공자를 위한 건축이 되어버린 원인을 설계에 대한 모든 권한이 건축가에게 일임 되는 건축설계 과정에서 발생하는 불완전한 커뮤니케이션에서 찾았고, 이를 해소하기 위해 일반인인 사용자를 건축의 설계에 참여시키기 위한 아이디어로서 패턴 언어를 생각해 내었다.

건축에 있어서 디자인 패턴은 이러한 패턴 언어를 지원하기 위해 과거 이루어졌던 건축이나 도시설계를 분석하여 패턴을 수집 하고 이를 바탕으로 패턴 언어를 구축하기 위한 어휘들을 지칭한다.

크리스토퍼 알렉산더의 이러한 주장은 건축분야에서는 큰 반향을 일으키지 못했지만 여기에서 영감을 받은 소프트웨어 개발자들의 연구에 의해 등장한 디자인패턴으로 소프트웨어 개발에 있어서는 큰 반향을 불러일으키게 된다.

프로그래밍에서의 패턴언어

소프트웨어 개발에 있어서 프로그래머 개개인간에 엄청난 생산성의 차이가 존재하는것은 익히 알려진 사실인데, 이러한 차이의 상당부분은 경험의 차이에서 오고 있다.
1994년 애릭감마를 포함한 네명의 저자에 의해 발표된 [디자인 패턴: 재활용 가능한 객채 지향 요소]는 소프트웨어 장인이라 불리우는 저자들의 수많은 성공과 실패의 경험속에서 축적된 노하우를 정제하여 스물세가지 패턴을 제시하였다. 초판 발간으로부터 20년이 흐른 오늘날에도 이 스물세가지 패턴은 꾸준히 이용되고 있으며, 오늘날에 와서는 이러한 패턴들을 기반으로 하여 앤터프라이즈 어플리케이션, 멀티스래드, UI, 데이터 구조, 아키텍쳐에 이르기까지 다양한 분야로 패턴을 확장하려는 노력이 꾸준히 시도되고 있다.

태권도 품새
디자인패턴을 익히고 사용하는것은 태권도에 있어서 품새을 익히고 사용하는 것과 동일하다. 태권도의 품새는 수많은 실전을 겪은 고안자가 수비와 방어 이동등에 있어서 이상적인 몸의 움직임을 정리하고 이를 패턴화 시켜 초보자가 이를 따라 함으로서 혼자서도 쉽게 익힐 수 있도록 한 것이다. 하지만 실전이나 겨루기에서는 품새의 형태대로 싸우지는 않으며, 그때그때 상황에 맞추어 대응하지만 기본이 되는것은 평소에 익혀둔 품새가 바탕이 된다.


패턴 랭귀지 3.0의 등장

물리적인 건축에서 시작된 패턴 랭귀지는 버전 2.0으로 불리우는 추상적인 소프트웨어의 디자인 패턴을 거쳐 교육이나 협력에 있어서 개인의 경험을 효과적으로 공유하기 위해 인간 행동을 대상으로 하는 버전 3.0이 등장하였다.

출전 :  패턴랭귀지:창조적인 미래를 만들기 위한 언어(Iba Takashi, 2014)
소프트웨어 개발자라면 디자인패턴의 유용성에 대해 잘 알고 있을것이다. 패턴 랭귀지는 대상을 소프트웨어 구현에서 인간 행동으로 확장 함으로서 개인의 경험을 효율적으로 공유하고 커뮤니테이션을 돕는 것을 목적으로 한다.

사실 패턴 랭귀지에서 다루는 패턴 그 자체는 대부분 전혀 새로울것이 없이 이미 존재하고 사용해 오고 있는 것 들이다. 패턴 랭귀지는 존재하는 패턴을 찾아내어 이름을 붇이고 일반적으로 적용하기 쉽게끔 언어를 정제하는 작업을 거친후에 마지막으로 각각의 패턴들간의 연관성을 찾고 연결함으로서 하나의 맵을 만드는 과정을 통해 완성된다.

프로그래머의 육성과 패턴 랭귀지

필자는 오래전부터 소프트웨어 개발자의 육성에 있어서의 패턴의 역할에 주목했다. 베테랑 개발자의 모든 습관에는 그 나름의 이유가 있으며 이를 패턴으로 정립하여 신입개발자들이 익혀서 따라해 볼 수 있게 한다면 이른바 도제 방식의 개발자 양성을 넘어 개발자 육성에 좀 더 효과적이지 않을까? 태권도의 품새와 같이 얼마간의 연습 기간을 통해 익히게 한 후 이것들이 일과 생활에서 효울적으로 사용 될 수 있도록 하면 효과적이지 않을까? 달인이라 불리우는 사람들이 저술한 설계와 구현, 매니지먼트 패턴은 이미 여러 책을 통해 세상에 나왔고 충분히 검증된 상태이다. 하지만 이 외에도 좀 더 패턴들이 있지 않을까?

예를 들자면 다음과 같은것들이 있다

학습패턴 : 우수한 개발자들은 끊임없이 변화하는 기술트렌드에서 뒤처지지 않게 나름의 학습패턴을 지니고 있다.
커뮤니케이션 패턴 : 주석을 포함한 문서화나 각종 메일, 프레젠테이션, SNS, 블로그 뿐만 아니라 일상의 대화나 회의등이 여기에 속한다.
네고시에이션 패턴 : 작업범위조정, 일정조정, 예산조정등 개발과 관련된 사항들에 대한 이해관계자들과의 조정능력.
품질 관리 패턴: 우수한 프로그래머들은 코드를 포함해 문서화등의 품질을 관리하는 나름의 방법론을 확립한 경우가 많다. 정밀 코드 레뷰나 믿을 만한 동료를 이용한 크로스 체크등 다양한 품질 관리의 패턴이 존재한다.
이 밖에도 일정관리/추정, 문서작성등은 물론이요 식사나 운동 습관, 구직/이직과 같은 사실상 인간 생활의 모든 분야에서 패턴을 찾을 수 있을것이다.

이러한 패턴을 찾아낸다면 그 다음엔 이름을 붙이고 사람들과 공유하고 토의해 보자. 아직도 세상에는 수많은 이름 없는 패턴들이 이름을 붙여주길 기다리고 있다.

2016년 4월 26일 화요일

회고에 대한 고찰 - KPT 진행의 노하우에 대하여

나프다Q&A에 동료에게 피드백을 주고받는 좋은 방법에 대해서 문의하는 질문이 올라왔다.

동료에게 피드백을 주고 받는 좋은 방법은 무엇입니까?


결론부터 말하자면 동료에게 좋은 피드백을 주기 위해서는 진심으로 동료를 아끼고 배려하는 마음이 가장 중요하다. 좋은 약은 입에 쓰다는 오래된 속담만 믿고 거친 말로 자극을 주려 하면 오히려 마음의 담만 쌓게 될 수도 있다. 이해하고 받아들일 수 있을 적절한 방법과 타이밍을 찾아내는것이 중요하고, 그 이전에 나의 말에 상대방이 귀 기울일 수 있도록 평소에 쌓아 놓은 신뢰관계가 무엇보다 필요하다.

이제 본론으로 들어가서 오늘은 회고에 대해서 이야기를 해 보자.

피드백에 대한 질문으로 회고에 대한 이야기를 시작한것은 회고야 말로 피드백을 가장 부담없이 그리고 효괴적으로 전달 할 수 있는 이벤트 이기 때문이다.
하지만 안타깝게도 많은 조직에서 회고를 실시하고 있지만 제대로된 회고를 진행하는곳을 찾아보기 어렵다.
회고 자체가 어려운것이 아니라 회고에서 다루어야 할 포인트를 잘못 짚고 있기 때문인데 오늘은 그에 대한 좋은 두개의 글을 소개해 볼까 한다.


맨 먼저 경영컨설턴트이신 유정식님의 글을 소개한다. 정말 좋은 글 이기 때문에 직접 링크를 따라가 본문을 꼭 읽어 볼 것을 권한다.

조용하다고 당신의 조직이 건강한가


이 글의 결론은 다음과 같다.

 조직이 사람들로 이뤄진 이상 크고 작은 실수가 생기지 않을 리 없다. 그러므로 실수와 문제가 없는 조직일수록 무언가 감추는 것이 많다고 생각해야 옳다. 시끄러울 정도로 실수를 드러내고 지적하는 조직이 조용한 조직보다 성과가 높을뿐더러 높은 성과가 오래도록 유지된다. 실수를 ‘실패’로 보지 않고 환경에 적응해 가는 ‘진화’의 과정으로 인식하기 때문이다.  

 그렇기 때문에 조직의 건강성은 무결점의 ‘정적인 상태’가 아니라 문제를 끊임없이 제기하고 그것을 고쳐 나가려는 동적인 과정에서 찾아야 한다. 조용한 조직은 성과를 높일 수 있는데도 그렇게 하지 못하는 조직이다. 조용한 조직은 성과 향상이 끊임없는 ‘학습과 적응’을 통해서만 가능하다는 것을 알지 못한다. 사실, 조용한 조직은 위험한 조직이다. 그들이 억누르고 있는 실수가 언제 큰 파국으로 번질 지 모를 일이다.

 공자는 말했다. “지혜란 무엇을 아는지 그리고 무엇을 모르는지를 아는 것이다.” 이 말은 실수는 잘못이나 죄가 아니라, 모르는 게 무엇인지 깨닫는 과정이라는 뜻으로 해석될 수 있다. 실수를 용인하고 권장한다는 말이 더 이상 듣기 좋은 구호로 끝나지 않도록 실천에 옮기는 것이 지혜로운 리더의 의무다. 당신의 조직은 조용한가, 아니면 시끄러운가?



다음은 CTO파견업이라는 비즈니스 모델로 일본에서 주목받고 있는 일본 소닉가든의 CEO이신 쿠라누키(倉貫義人)씨가 쓴 "자율적으로 현장을 개선해 나갈 수 있는 회고의 진행방식 - KPT 진행에 대한 노하우" 번역하여 소개해 본고자 한다. 기사의 번역을 흔쾌히 허락해 주신 쿠라누키씨에게 감사의 말씀을 드린다.
(여담이지만 필자는 쿠라누키씨의 QCon Tokyo 2015강연에서 사회를 담당한 인연이 있다.)

자율적으로 현장을 개선해 나갈 수 있는 회고의 진행방식 - KPT 진행에 대한 노하우



현장의 운영을 개선하기 위해 먼저 착수한다면 뭔가? 고 물으면 항상 ‘회고’ 부터 시작하자 라고 대답 합니다. 과거에 카오스상태의 프로젝트에 들어 갔을 때 에도 가장 먼저 시작한 것은 '회고'에서 였습니다.


‘회고’는 말 그대로 현장의 활동을 되돌아보고 개선 작업을 생각하는 것입니다. 반성 회처럼도 보이지만, 모든 것이 끝나고 나서 반성하는 것은 아니고, 현상 분석을 실시하고, 잘 계속하기의 미래를 향한 활동입니다.


이 기사에서는 ‘회고’라는 문화, 그리고 회고를 실천함에 있어서 진행 방식과 포인트를 소개합니다.




회고의 진행 방식 "KPT"에 대해서



위의 사진은 우리 소닉 가든에서 ‘회고’를하고있는 모습입니다. 소닉 가든에서는 도제식 사원 육성 제도를 실시하고 있는데, 이 광경은 사수와 부사수(역자주:군대용어라서 죄송)가 참여하는 회고의 풍경입니다. 이처럼 특별한 도구는 아무것도 필요하지 않습니다. 필요한 것은 화이트 보드 하나면 충분합니다.


역자주) 소닉가든은 CTO 파견업이라는 비즈니스 모델을 가진 일본의 회사입니다. 나중에 기회가 된다면 자세히 소개를 하겠지만 혼자서 프로젝트를 진행하는 사원을 1대1 도제식 교육으로 5년에 걸쳐 육성하는 것을 목표로 한다 합니다.


사진 속 화이트 보드를 보면 그 회고의 내용이 적혀 있습니다. 3 개의 지역으로 나누어 져있는 것이 보이시나요? 소닉 가든에서 실시하고 있는 회고 방법은 "KPT"라고하는 것으로, 회고에서 주로 쓰이는 방법 입니다.


KPT는 Keep / Problem / Try의 약자로, 「Keep = 좋았던것」  「Problem = 나빴던 것」 「Try = 다음 시도 할」의  세 가지 프레임워크로 나누어 생각하는 방법입니다. 방금 보신 화이트 보드는 3 개의 구역인 Keep와 Problem와 Try으로 나누어 져 있습니다.


화이트 보드를 좌우로 나누고, 그 왼쪽을 더 아래로 나눕니다. 왼쪽을 Keep 왼쪽 하단을 Problem 오른쪽 절반을 Try를 내보낼 장소로 제공합니다. 자 우선 회고 시작해 봅시다.


역자주) T에 가장 큰 영역을 할당하고 있는것에 주목합시다.

회고 "KPT"의 구체적인 진행 방식



회고의 논의 대상은 '일하는 방식'에 대해서 입니다. 일의 진행 상황과 보고는 여기서 논하지 않습니다. 평소의 일을 할 때보다 조금 관점을 바꾸어 자신들의 업무 방식을 제3자 입장에서 객관적인 시선으로 보는 느낌을 가지고 진행합니다. 따라서 진척 회의는 별도로 가져가는 것이 좋습니다.


역자주) 진척회의와 회고를 분리해야 합니다.


먼저하는 것은 Keep와 Problem을 명확이 하는 것 입니다. 이 둘의 원천은 이전에 진행하였던 KPT의 Try입니다. Keep와 Problem을 정리할 때 중요한 것은 일어난 사건 자체 뿐만 아니라 좋았거나 나빴던 일에 이르는 과정에 대해 쓰는 것이 좋습니다.


이 때 중요한 것은 일단 논의를 뒤로 하고 생각 나는 것을 모두 꺼내 놓는것 입니다. 하나 하나 논의를 하고 있자면 끝이 없습니다. 우선 모두 발언하여 칠판에 적어나갑니다. 이렇게 화이트 보드에 꺼내 놓음으로써 비로서 개인 안고 있던 K와 P가 팀 K와 P로 변화하게 됩니다.


Keep와 Problem이 모두 나온 다음은, 나온 것 들을 일단 팀과 공유 한 후 Try(개선책)에 대해서 생각합니다. Try을 고려할 때 포인트는 구체적인 액션에 까지 구체화 시키는 것이 중요합니다. 예를 들자면 "○○를 조심" 이라고 하는 것은 Try가 될 수 없습니다.


"조심"이 왜 안 되는가? 그것이 구체적으로 무엇을 할 것인지, 다음 KPT의 때 제대로 할 수 있었는지 여부를 판정 할 수 있는 것이 아니면 안 되기 때문입니다. Try라는 정도이므로 이게 정답 이라는 게 나오기 힘들기 때문에 가설을 설정해서 이야기 합니다.


회고 기간과 그 효과



회고는 1 주일 단위 정도에서 실시하면 좋습니다. 첫 회고의 경우 전회의  Try도 없을 뿐더러 지금까지 진행해 온 방식도 있기 때문에, 길어지리라고 생각 합니다만, 1 주일 단위가 정착하면 회고 자체를 짧은 시간에 할 수 있습니다.


회고을 지속적으로 진행시켜 나가면 서서히 회고 방법 자체도 능숙해 지게 됩니다. 지난주보다 이번주, 이번주보다 다음주에 점점 더 잘 하게 되는 것 입니다.


회고는 혼자 해도 효과는 있지만, 기본적으로는 팀 임 함께 하는 것이 더욱 좋습니다. 개개인이 자신의 내면에 가지고 있던 "좋았던 것" 과  "나빴던 것"을 팀원들과 공유하여 함께 "다음 시도”에 대해 생각한다는 것은 팀워크에도 큰 도움이 됩니다.


함께 팀을 개선하기 위한 아이디어를 생각하는 것을 계속하는 것을 통해 멤버들이 한 팀이 되어가는 느낌을 가질 수 있습니다.


또한 만약 팀에 새로 들어온 멤버가 있었다 하면, 그 멤버에 문화를 전하는 가장 효과적인 방법이 이’회고'가 되는 것이 아닐까 라고 생각합니다.


회고의 '습관화'에서 '일상화'를 목표로



회고을 계속 이어 가면, 팀은 스스로 현장을 개선해 나갈 것이다라는 의식이 싹 트게 됩니다. 그렇게되면, 스스로 회고을 실시하고  개선을 거듭해 나갈 수 있게 됩니다.


정기적 인 '회고'를 습관화 한다. 이것이 목표로 1 단계입니다.


다음 단계가 되면, 회고 자체가 당연하게 되어, 일상 업무 속에서 항시적으로 할 수 있게 됩니다. 평소의 일에서 뭔가가 진행되거나 변화가 필요하다고 생각되는 시점에서 자연스럽게 조금씩 회고를 하게 됩니다. 이 단계까지 가능해 지면 일주일이라는 기간은 의미가 사라집니다.


즉, 일부러 일주일에 한 번 타이밍까지 기다릴 필요가 없게 됩니다. 이렇게 일상 속에서 회고를 할 수 있는 단계에 이르면, KPT를 해도 아무것도 나오지 않게 될 것입니다. 그렇게 ‘회고 '를 일상화 해 버리는 것이 두 번째 단계입니다.


회고가 정기적 이벤트에서 상시화 되는 것 입니다.


소닉 가든은 평상시는 이벤트로서 회고를 하지는 않습니다. 잘게 나누어 모두가 당연하게 일상적으로 회고를 하고 있기 때문입니다.


그러나 중도 입사 한 사원에게는 멘토가 붙어 이벤트로 회고을 정기적으로 실시합니다. 이는 습관화 된 일상으로 회고을 할 수있게 될 때까지 계속됩니다. 소닉 가든은 정해진 규칙 등은 없지만, 회고을 한다는 것이 거의 유일한 룰 입니다.


회고을 하면 사람도 팀도 성장할 수 있습니다. 회고을 익힌 사람이나 팀은 자율적으로 성장해 나갈 수있을 것 입니다. 성장이 없는 일을 계속하는 것은 평생 같은 일을 계속하는 것입니다. 글을 읽는 여러분도 회고를 통해 조금씩 이라도 성장 해 나갈 수 있으면 좋겠습니다.


덤 : 회고에서 일어나는 일반적인 문제


회고을 시작하여 익숙해지기 전에는 여러가지 문제가 발생합니다. 그리고 이러한 문제들은  대체로 비슷한 고민을 안고 있습니다. 여기서 덤으로 회고 진행시에 자주 발생하는 문제를 사례별로 소개하고 대응 방법을 생각해 보겠습니다.


"Keep이 나오지 않는다"



자신의 프로젝트에 좋은 점은 하나도 없고, 문제 투성이 라는 것입니다. 이상이 너무 높거나 너무 금욕적인 것 인지도 모릅니다. 그러나 이전 진행했던 회고보다도 좋지 않은 점이 나오지 않는 것은 심각한 문제 입니다.


원래 이전 회고에서 나온 Try가 전부 제대로 되지 않았다면 Try를 낸 방법 자체에 문제가 있는 것 입니다. 우선 그것 부터 개선 하도록 합시다.


"Problem이 고민 상담이 되는 경우"



Problem을 낼 때 단순히 고민하고 있는것을 말하는 것으로 Try가 도출 되지는 않습니다. 실제로 일어나지도 않은 문제를 걱정 할 필요는 없습니다. 지나간 일은 "나빴던 일"로 내면 좋을 것입니다.


"Try가 구체적이지 않다"



Try를 생각할 때 "기분"을 반영시켜 버리는 것은 해서는 안될 일 입니다. 기분에 의존해서 진행 하다 보면 다음에 무얼 해야 할지를 모르게 되어버립니다. 무엇보다 다음 KPT의 회고때 무엇이 되어 있고 무엇이 안되어 있는지 명확하게 판정 할 수 없습니다.


Try는 "시도하는 것"이​​므로, 그것이 반드시 정답이 아니어도 좋습니다. 다음 회고까지 시도하여 좋은 것이라면 계속하면 되고, 좋지 않다면 방법을 바꿔야 합니다. 이를 위해서는 Try의 내용이 구체적인 조치 여야만합니다.


"생산성을 따져보자”



Problem를 발행 할 때 자주있는 것이 「늦었다」 「잔업했다」같은 것입니다. 그 자체가 엉켜 버린 문제이기 때문에 Problem에 올리는 것은 좋습니다. 그러나 회고의 Try에서 생산성을 따져서는 안됩니다.


만약 본인이 한껏 노력한 과정에서 늦게까지 작업을 한 것 이었다 하면 놀면서 한게 아니기 때문에 더 이상의 극적인 생산성 향상은 기대하기 어렵습니다. 이 경우는 시간을 들여서 생산성을 높일 수 밖에 없습니다. 본인의 노력이 아닌 프로세스와 방법에 있어서의 개선안을 생각합시다.


또한 비슷한 이야기로​​ "일정을 낙관했다"도 NG입니다. 일정은 원래 낙곽적이 되기 쉽습니다만  만약 문제 자체를 "일정의 낙관”'탓으로 돌려 버리기 시작하면 해결책으로는 일정에 대한 버퍼를 쌓게 되는 것이 되어버리고 결국 그 앞에는 지옥이 기다리고 있습니다.


"진척 회의가 되어 버린다"



회고를 진행하다보면 왕왕 진적회의로 변질되어 버리는 경우가 있습니다. 그러나 회고 라는 것은  "어떤 의식으로 일을 수행하고 있는가?" "어떻게하면 효율적으로 일할 수있는 것인가?” 라는 일의 진행 방식에 대해 논하는 것 입니다. 진척 회의는 반드시 별도로 진행 합시다!


또한, 자칫 Problem을보고, 리더가 설교에 들어가 버릴 수 있지만, 그것도 좋지 않습니다. 회고에서 목표로하고 싶은 것은 스스로 회고을 하고 스스로 개선해 나가는이라는 의식을 갖게하는 것입니다. 설교를 하고 정답을 말해 버리면 스스로 생각할 없게 되어 버리고, 결국은 발전도 성장도 기대할 수 없게 됩니다.

2016년 2월 13일 토요일

어려운 것을 쉽게 배우는 방법 : 슈퍼 파워를 장착하기 위한 3단계 학습법

이번 포스팅에서는 노르웨이의 개발자인 Per Harald Borgen (미디엄페이스북, 트위터, 깃헙, 링크드인)이 미디엄에 공개한 "The Easy Way To Learn Hard Stuff :Three steps to gain a new superpower. (어려운 것을 쉽게 배우는 방법 : 슈퍼 파워를 장착하기 위한 3단계 학습법)이란 글을 번역하여 소개하고자 한다. 그의  미디엄에는 다른 멋진 글들이 가득하므로 꼭 한번 들러보길 추천한다.

글을 시작하기에 앞서 이 멋진 글의 번역을 흔쾌히 허락해준 Borgen씨에게 감사의 말을 전한다.


어려운 것을 쉽게 배우는 방법

슈퍼 파워를 장착하기 위한 3단계 학습법


지난 몇 년 동안 저는 많은 시간을 웹 개발과 머신 러닝을 독학하는데 많은 시간을 써 왔습니다.
학습의 테마는 자바스크립트, NodeJS, React에서 Python, Scikit-learn 그리고 신경망 프로그래밍에 이르기까지 다양했지만 이 모든것을 저는 일관된 방식으로 공부해 왔습니다.

제가 사용한 이 공부법은 3단계로 진행이 되는데 진부하다고 말해도 될 정도로 단순합니다. 하지만 웹 개발에 완전히 문외한 이었던 제가 단 5개월만에 스스로 프로라고 느끼는 것이 가능할 정도가 된 것은 이 공부법의 효과 덕분이라고 생각합니다.

저는 이 학습법이 다른 사람에게도 도움이 될지 모른다고 생각하여 이 기사를 써 보기로 마음먹었습니다.

이 기사는 아무 것도 모른채 무작정 도전을 시작한 2012년 당시의 제 자신을 가르친다는 마음가짐으로 작성하였습니다.

1단계: 배우기전에 익숙해져라

새로운 기술을 배우기 위해서 가장 먼저 실행하는 첫 단계는, 머리로 이론을 학습 하려 하지 말고 어찌되었든 손을 움직여서 사용해 보는 것 입니다. 이러한 방식이야 말로 이론부터 머리속에 넣는 방법보다 훨씬 뛰어납니다.

그렇다고는 해도 배우고자 하는 테마에 대해서 아무 것도 모르는 상태 이므로 자력으로는 뭘 어찌 해 볼 도리가 없습니다.


Justine Michel의 Django 강좌는 완벽하게 "배우기전에 익숙해져라"라는 방식으로 진행이 됩니다.


그래서 우리가 맨 먼저 할 일은 작은 뭔가를 더미로서 만드는 과정을 개략적으로 설명해주는 튜토리얼 영상을 찾는것 입니다. 저자가 설치부터 한 줄 한 줄 끝까지 코드를 설명해 주는 튜토리얼을 찾아 비디오를 보며 여러분도 똑같이 코딩해 보세요. 그 연습용 프로젝트가 제대로 작동하는 것을 확인하며 한줄 한줄 쫓아가는 겁니다.

10분정도의 영상이라고 한다면 여러분이 그것을 끝까지 쫓아 하는데에는 1시간정도 걸린다고 생각해 두세요.

또한 MOOC 코스보다는 숙련된 아마추어가 YouTube에 올린 영상쪽이 오히려 공부하기가 쉬울지도 모릅니다. MOOC를 지금 단계에서 보기엔 너무 부담스러운 경우도 있기 때문입니다.

이 방법의 정 반대되는 접근방법은 그 주제에 대한 책을 읽고 이론부터 배워 나가는 것 입니다. 다만, 그 방법은 제게는 잘 맞지 않았습니다. 다 읽기도 전에 질려버리기 때문입니다. 초보자를 위한 책 조차도 대게는 너무 자세하기 때문입니다. 그래서 저는 책이나 문서를 처음 단계에서는 절대 보지 않으려고 합니다.
튜토리얼 비디오를 따라하는 과정속에서, 자신이 지금 무얼 하고 있는지 알 수가 없어 불안하게 느낄 수도 있습니다. 하지만 그런건 신경쓰지 마세요. 이해 할 수 없는 것은 일단 메모를 해 두고 2단계에서 다시 살펴 봅니다.

이 단계의 핵심은 혼란 스럽거나 지식이 부족하더라도 일단 끝까지 튜토리얼을 한번은 쫓아가는것 입니다.

이러한 방식의 단점을 넘어서는 장점은 다음과 같습니다.

1. 첫날부터 일단 뭔가 만들어 본다

첫날부터 실제로 뭔가를 만들기 때문에, 이론만 읽고 공부만 하는것 보다 만족감을 맛볼 수 있습니다. 그리고 이러한 만족감은 학습을 계속하려고 하는 의욕으로 연결됩니다.

제가 맨 처음 만든 Node.js서버 입니다. 두고두고 많은 참고가 되어 주었습니다.

2. 샘플코드를 얻을 수 있다


게다가 학습과정에서 언제든지 참고할 수 있는 샘플코드들이 여러분의 수중에 남게 됩니다. 이 단계에서 만들어진 샘플 코드들은 이후 단계에서 매우 유용하게 쓰여지게 됩니다.

저는 배우고자 하는 테마에 대한 이해가 깊어졌다고 실감 할 때마다 과거에 만들어둔 예제 코드를 여러번 반복해서 살펴 봄으로서 기억을 새롭게 하고 있습니다.

3. 자신이 무엇을 모르는지 파악 할 수 있게된다


또한, 제 자신은 스스로 공부해 나가는 중에 특히 어느 부분을 신경써서 공부해야 하는지를 발견하는데 있어서 이 방법이 가장 빠르다는것을 깨달았습니다.

학습을 시작하기 전에는 무엇을 아는지 모르는지도 알 수 없는 상태이기 때문에, 배우고자 하는 기술의 어떤 부분에 신경을 써야 하는지, 어느 부분이 까다로운 지를 알 방법이 없습니다. 그렇기 때문에 특히 주의가 필요합니다. 이러한 부분은 가능한 한 빨리 파악해 두는것이 필요 합니다만 이것이 하나의 장벽이 되지 않도록 이해하는 것은 나중에 천천히 해도 됩니다.



아래의 목록은 제가 다양한 테마를 배우기 시작하는데 있어서 많은 도움을 받은 튜토리얼들 입니다.



2단계: 난관에 도전하라


1단계에서 언급한 교제를 적어도 한번 끝까지 마치고 나면 배우고자 하는 기술의 전체적인 구조에 대한 감을 잡을 수 있게 됩니다. 하지만 분명 아직까지는 머리속이 뒤죽박죽일 껍니다. 그래서 다음 단계는 이러한 혼란을 해소하는 것 입니다.

React.js를 배우고 있다면, 그것은 상태와 속성의 차이가 무엇인지를 제대로 파악하는 것 일 겁니다. (참고로 여기를 읽어보시면 이해하실 수 있을것으로 생각합니다.)

이 단계에서는 사실 구체적으로 추천할 수 있는 무언가가 없습니다. 기본적으로는 상황에 맞춰서 책, 공식문서, 스텍오버플로등 어떤 것이라도 살펴볼 필요가 있습니다.

지난번 제가 이것을 경험한 것은 신경망의 코딩 방법을 공부 할 때 였습니다. 코세라 과정을 수강하고 알았지만 신경망의 전체를 이해할 수 있으려면 로지스틱 회귀를 이해할 필요가 있었던 겁니다. 그래서 로지스틱 회귀에 대한 기본적인 공부를 우선 마친 후에 다시 신경망에 대한 학습에 임한 결과 이번에는 훨씬 더 쉽게 이해할 수 있었습니다.

3단계: 뭔가 만들어 본다

1단계와 2단계는 절대 건너 뛸 수 없는것 이지만 사실은 3단계를 위한 디딤돌에 지나지 않습니다. 새로운 기술을 배우고 싶다는 것은 그 기술로 뭔가를 만든다는 것 입니다. 드디어 이번 단계에서 이러한 목적을 실행에 옮깁니다.

스스로 새로운 뭔가를 만들 수 있게 되었다면 즉시 있는 힘껏 부딧쳐 봅시다.

왜냐구요? 실제로 무언가를 만드는 것이야 말로 진정한 의미에서의 배움의 완성이기 때문입니다.

기술을 배우고 나서도 무언가를 만들지 않는다면 그건 진정한 배움이라 할 수 없습니다.

1단계와 2단계는 대충 넘길 수 있지만 3단계는 그럴 수가 없습니다. (여기서 말하는 만들기는 단순히 코드를 복사하고 붙여넣기가 아닙니다)

만들것은 평소에 관심을 가지고 있는것과 연결 시키는 것이 좋습니다. 예를들면, HTML과 CSS를 배우는 와인 애호가라면 와인 시음에 대한 웹사이트의 프로토 타입을 만들어보면 좋을겁니다. 머신러닝에 대해 배우고자 하는 의사라면 건강관련 데이터세트부터 시작해 보는것이 어떨까요?

제가 초기에 수행한 프로젝트에서는 다음과 같은 것을 만들었습니다.
어디가서 자랑할 수준은 아니지만 저에게는 많은 공부가 되었습니다.



제가 만든 최초의 Ajax프로젝트 입니다. 2014년 초순경에 Founders&Coders 팀으로서 구축에 참여하였습니다.

마지막으로 말씀드리고 싶은것은, 위에서 언급한 3단계는 때때로 얽혀 있기도 하여, 이 기사에서 적은것 처럼 순차적으로 진행되기만 하는것은 아니라는 점 입니다.

저는 반드시 1단계부터 시작해 3단계로 마무리를 하지만, 학습 도중 이전 단계로 돌아가는 일도 자주 있습니다.

중요한것은 이 세 단계가 각각 새로운 기술을 배우는 것 만큼이나 중요한 요소라는 사실 입니다.

여러분의 성공을 기원합니다!

역주: 혹시 이 기사가 마음에 드신다면 원문으로 가셔서 하트(미디엄의 좋아요)를 꼭 눌러 주시기 바랍니다. 그리고 영어가 되신다면 댓글도 남겨주신다면 고맙겠습니다. ^_^

2016년 1월 18일 월요일

고성능 비동기 처리 구현을 위한 Java web 프레임워크 - Ratpack

스마트 기기로의 권력 이양이 순조롭게 진행되고 있는 지금, 시대는 바야흐로 Single-page Application(SPA)의 전성시대이다.
필자가 속한 엔터프라이즈 어플리케이션 개발 영역에서도 반응형 웹앱 개발에 대한 요구가 점차 강해지는 가운데 안정성이 검증된 자바 생태계 위에 SPA를 도입하려는 움직임이 점차 본격화 되고 있다.

이번 포스팅에서는 SPA의 구현에 있어서 본좌라고 할 수 있는 node.js와 유사한 처리모델과 고성능 비동기 처리의 실현, 그리고 심플한 구현을 특징으로 하는 자바 웹 프레임워크인 Ratpack을 소개해 보고자 한다.

포스트의 내용은 Ratpack의 메뉴얼, infoq의 기사인 Ratpack 1.0 Launches Aiming to make Asynchronous Programming Easier on the JVM 그리고 역시 infoq의 기사인 Build High Performance JVM Microservices with Ratpack & Spring Boot에 기반하여 작성되었다.



Ratpack이란?

Ratpack의 핵심 기능들은 Java8으로 작성되어 있고 빌드 시스템은 Gradle 2.6을 채용하고 있다. 처리 베이스는 non-blocking형 이벤트 구동 네트워크 엔진인 Netty를 사용하여 비동기처리를 구현하고 있다.

Ratpack은 마이크로서비스의 개발을 특별히 의식하여 디자인이 되어 있다. 대표적으로 JSON과 같이 특정 언어에 비 종속적인 프로토콜을 최 우선적으로 서포트하고 있으며, 옵션으로 넷플릭스의 서킷 브레이커 라이브러리인 Hystrix나 레포팅을 위한 Dropwizard Matrics를 지원하고 있다. 설정정보관리는 YAML과 JSON 그리고 Java프로퍼티가 사용 가능하다.
Ratpack은 오픈소스 프로젝트로서 개발이 진행되고 있으며, 아파치 라이센스를 사용하고 있다.

Ratpack은 2015년 9월에 1.0이 발표되었으나 사실은 제법 긴 스토리를 가지고 있다. 2010년 Groovy의 DLS구현체로서 출발하여 얼마 후에는 JVM상의 Sinatra 클론으로 프로젝트의 성격이 바뀌었고 2012년부터는 NIO를 이용한 고성능 비동기/non-blocking 어플리케이션 구현을 위한 프레임워크로 변경되어 오늘날에 이르렀다. 


Ratpack의 개발 목표

매뉴얼에 기재된 Ratpack이 표방하는 개발 목표는 다음과 같다.
  1. 빠르고, 확장가능하며, 고효율이어야 한다.
  2. 응용프로그램을 성능저하 없이 복잡하게 발전시킬 수 있어야 한다.
  3. non-blocking 프로그래밍의 장점을 활용하면서도 비용을 절감시킬 수 있어야 한다.
  4. 다른 툴과 라이브러리들과 통합함에 있어서 유연하고 개방적이어야 한다.
  5. 응요 프로그램을 쉽고 완벽하게 테스트 할 수 있어야 한다.
반면 다음의 사항들에 대해서는 지양하고 있음을 밝히고 있다.
  1. 완벽하게 통합된 "풀스텍" 솔루션
  2. 필요한 모든 기능을 제공하는 "만능 칼"
  3. "비즈니스 로직"을 위한 프레임웍 혹은 아키텍처

심플한 비동기 처리의 구현

Ratpack의 가장 큰 특징은 뭐니뭐니해도 심플한 비동기 처리의 구현이다. JVM위에서 비동기 처리라는 과제에 도전하고 있다는 점 에서 자주 Akka와 비교되곤 하는데, 코딩스타일에 있어서 자바8을 기반으로 한 만큼 모나딕을 전면적으로 도입하고 있는것이 메뉴얼에서 잘 드러난다.

아래 예제는 Ratpack의 메뉴얼에 실려있는 RESTful HTTP API 헨들러 체인의 구현이다.

package springpack;

import ratpack.server.RatpackServer;

public class Main {

  public static void main(String[] args) throws Exception {
    RatpackServer.start(spec -> spec
      .handlers(chain -> chain (1)
          .prefix("api", pchain -> pchain (2)
            .all(ctx -> ctx (3)
              .byMethod(method -> method (4)
                .get(() -> ctx.render("Received GET request"))
                .post(() -> ctx.render("Received POST request"))
                .put(() -> ctx.render("Received PUT request"))
                .delete(() -> ctx.render("Received DELETE request"))
              )
            )
          )
      )
    );
  }
}

처리모델

Ratpack의 처리 모델은 node.js의 그것과 닮아 있다. 다음 그림은 4코어 시스템에서 동작하는 Ratpack의 처리 모델의 개요를 나타내고 있다.


Ratpack은 기동과 함께 지정한 코어 수 만큼의 이벤트 루프가 바인딩 된다. Ratpack은 Netty를 이용해 "이벤트 루프 그룹"을 생성하고 사용 가능한 CPU코어에 각각의 단일 스레드로 동작하는 이벤트 루프를 바인딩 한다. 각각의 이벤트 루프는 응용 프로그램에서 도착하는 non-blocking 네트워크 요청을 처리한다. 즉, 하나의 비동기처리 요구에 대하여 하나의 CPU에 바인딩 되도록 하는 처리 방식을 통해 고성능 비동기 처리를 실현하려 하고 있는데, 최근 실시한 벤치마크에서는 단순 Hello World의 경우 32코어 머신에서 초당 1억 리퀘스트를 단일 JVM인스턴스로 처리 할 수 있는 것으로 알려져 있다.
비동기 & non-blocking에 대한 보다 상세한 내용은 Ratpack의 메뉴얼을 참고하기 바란다.

2016년 1월 17일 일요일

TDD, BDD를 넘어서 - 검증 주도 개발(Verification-Driven Development,VDD)에 대하여

최근 진행한 나는 프로그래머다 녹음에서는 서울대학교 컴퓨터 공학부의 이광근 교수님을 모시고 최근 저술하신 책 - 컴퓨터과학이 여는 세계와 학문으로서의 컴퓨터 과학을 주제로 방송을 진행하였다. 임작가님이 3연휴를 희생하여 편집에 의욕을 보여 주신 덕분에 빠르게 공유될 수 있지 않을까 기대해 본다. (블로그 글을 작성하고 있는 도중에 편집본이 도착했다 ^^)

방송 말미에 앞으로 교수님께서 주목하고 있는 언어 관련 최신 동향에 대해서 소개를 부탁드려 봤는데 그때 말씀해 주신것이 지금부터 소개하려 하는 정확한 검증(formal verification)이다. 아직은 학문적 영역에 머물러 있지만 조만간(이교수님 말씀으로는 5년) 우리 앞에 모습을 드러 낼 수 있을것으로 보이기에 어떠한 것인지를 현업 개발자의 시선에서 설명해 보고자 한다.

정확한 검증(formal verification) 과 정확한 사양(formal specification)


정확한 검증이란,  하드웨어 및 소프트웨어 시스템에서 정형기법과 같은 수학 논리를 이용하여 어떤 정확한 사양 기술 및 속성에 비추어 시스템이 올바른지를 증명 하거나 반대로 잘못된 것을 증명하는 것을 말한다. 구현하고자 하는 대상을 정확한 검증이 가능하도록 기술하는 것을 명세 언어(Specification language)라 하는데 대표적인 명세언어는 우리가 개발에서 흔히 사용하는 UML이 있다.

정확한 검증이 도입되면 대상 시스템이 명세 언어로 작성된 사양에 비추어 올바른지 여부를 자동으로 판정하는 것이 가능해진다. 이를 통해 개발 과정에서 구현과 동시에 사양에 대한 검증을 실시하는것이 가능해 진다. 

정확한 검증의 필요성은 설계 (또는 구현)의 '정당성'은 그 자체만으로 확인할 수 없다는 점에서 출발한다. 정당성은 주어진 사양과의 검증을 통해 처음으로 확인 가능하며, 정확한 사양의 표기가 해결해야 할 문제를 제대로 설명 할 수 있는지 여부는 또 다른 문제이다. 이것 또한 어려운 문제이며, 비 형식적인 실제 문제를 추상화 된 형식적인 사양 기술에서 제대로 설명해야 하는 문제에 귀착한다. 이러한 요약(abstraction)은 증명이 불가능하다. 그러나 사양에 대한 정리 를 증명할 수 있다면, 사양의 무결성을 검증하는 것은 가능하다. 

 검증에 대한 개요. 구현과 사양의 개발이 함께 진행되고 최종적으로는 툴에 의한 검증이 이루어 진다는 점에 주목하자.  이미지 출처: OS Verification -- Now! 


현재 현업 개발현장에서 사용되고 있는 일반적인 자동화 검증 기법은 다음과 같은 것 들이 있다.

  • 단위 테스트(Unit test) : 함수(또는 메소드)단위로 테스트 코드를 작성하여 실시하는 자동화 테스트. 반복개발 프로세스 안에서 단위 테스트를 구현과 묶어서 개발 하는 방법론을 테스트 주도 개발(Test-Driven Development,TDD)이라 부른다.
  • 행위 테스트(Behavior test) : 테스트 범위를 함수 단위에서 기능단위로 확장시킨 테스트형태를 말하며 테스트가 사양 명세(Specification) 그 자체가 되는것을 목표로 하기때문에 테스트 코드의 작성에는 자연 언어에 가까운 도메인 고유 언어(DSL)가 선호된다.  TDD와 마찬가지로 개발 프로세스에 행위 테스트 작성을 프로세스의 일부로서 도입한 개발 형태를 행위 주도 개발(Behavior-Driven Development,BDD)이라 부른다.
  • End-To-End 테스트(e2e test): 독립적으로 작동하고 Mock와 Stub를 사용하는 BDD 나 단위 테스트와는 반대로,  End-to-End 테스트는 가능한 한 실제 시스템의 사용자에 가깝게 에뮬레이션하려고한다. 대표적인 툴 로는 Selenium 이 있다.

자동화 테스트와의 차이

 위에서 소개한 자동화 테스트들이 정해진 숫자의 테스트 케이스만을 소화해 내는 형태인데 비해 정확한 검증은 구현된 로직 자체가 사양과 일치 하는지를 검증해 내고자 한다. 실제로 TDD를 이용해 개발을 해 본 개발자라면 사람이 예상한 테스트 케이스와 실제 동작에서 발생하는 경우의 수 사이에 늘 차이가 존재 할 수 밖에 없다는 사실에 동의할 것이다. 설사 많은 노력을 투입하여 모든 경우의 수를 커버하는 테스트 케이스를 작성한다 할 지라도 그것이 애초에 구현하고자 한 대상과 동일한 것이라는 사실을 보장해 주지 못한다. 이상적인 정확한 검증의 구현은 사양 자체가 검증과 일체화 되기 때문에 구현에 대한 버그가 발생하게 될 여지가 존재하지 않는다. 이러한 점은 BDD가 이루고자 하는 목표와도 일치한다.

정확한 검증 방법

정확한 검증은 크게 두 가지로 분류된다.


모델 검사

첫 번째 방법인 모델 검사는 수학적 모델을 통해 체계적이고 철저하게 검증하는 것을 말한다. 여기서 말하는 모델은 유한 상태 모델을 지칭 하지만 무한의 상태를 가지는 모델도 추상화를 통해 유한 표현으로 전환이 가능하다면 확인 가능한 모델로 취급한다. 일반적으로 모델의 전체 상대와 전체 상태 전환의 검증을 포함하며, 연산 시간을 줄이기 위해 영역고유의 추상화 기법을 이용하여 효율화를 도모한다.

다만, 모델 검사는 하드웨어 설계에 적용되는 경우가 많고 소트웨어에 대한 모델 검사는 결정 불능이므로 알고리즘적인 방법만으로는 완전하지 않고, 증명도 반증도 할 수 없는 경우가 있다. 모델검사에 사용되는 방법으로는 선형시상논리(Linear Temporal Logic,LTL)나 계산 트리 논리(Computational Tree Logic, CTL)가 있다. (솔직히 나 자신은 이 글을 작성 하면서도 위의 링크를 눌러 볼 엄두가 안난다.)

논리적 추론

두 번째 방법은 논리적 추론이다. 일반적으로 엄밀한 논리 추론을 돕는 자동도구(Automated Theorem Proving, ATP) 소프트웨어를 사용하여 시스템에 관한 정확한 추론을 실시한다. 이 기술은 완전 자동화 되어있지 않은것이 일반적이었으나 최근들어 Perfect DeveloperEscher C Verifier와 같은 도구가 등장하여 증명에 대한 완전 자동화를 시도하고 있다. 

Java Modeling Language(JML)과 Spec#

학교와 연구소에서 벗어난 정확한 검증이 우리 앞에 어떠한 모습으로 나타날까? Java Modeling Language(JML)과 Spec#은 논리적 추론을 통해 정확한 검증을 구현하려는 프로젝트이다. 어노테이션에 검증을 위한 사양을 JMS 사양 이라는 표기법으로 기술한다.

이해를 돕기 위해 위키사전에 실려 있는 JML 의 예제를 살펴보자.

public class BankingExample
 {
 
    public static final int MAX_BALANCE = 1000; 
    private /*@ spec_public @*/ int balance;
    private /*@ spec_public @*/ boolean isLocked = false; 
 
    //@ public invariant balance >= 0 && balance <= MAX_BALANCE;
 
    //@ assignable balance;
    //@ ensures balance == 0;
    public BankingExample()
    {
        this.balance = 0;
    }
 
    //@ requires 0 < amount && amount + balance < MAX_BALANCE;
    //@ assignable balance;
    //@ ensures balance == \old(balance) + amount;
    public void credit(final int amount)
    {
        this.balance += amount;
    }
 
    //@ requires 0 < amount && amount <= balance;
    //@ assignable balance;
    //@ ensures balance == \old(balance) - amount;
    public void debit(final int amount)
    {
        this.balance -= amount;
    }
 
    //@ ensures isLocked == true;
    public void lockAccount()
    {
        this.isLocked = true;
    }
 
    //@   requires !isLocked;
    //@   ensures \result == balance;
    //@ also
    //@   requires isLocked;
    //@   signals_only BankingException;
    public /*@ pure @*/ int getBalance() throws BankingException
    {
        if (!this.isLocked)
        {
                return this.balance;
        }
        else
        {
                throw new BankingException();
        }
    }
 }

cucumber나 RSpec을 접해본 독자라면 위와 같은 표기법이 낮설지 않을것이다.

이번에는 마이크로소프트의 연구소에서 연구중인 Spec#의 예제를 살펴보자. 아래 예제는 C#에 기술된 Spec#이다.

static void Main(string![] args)
        requires args.Length > 0;
    {
        foreach(string arg in args)
        {
            Console.WriteLine(arg);
        }
    }

'requires args.Length > 0;'이 Spec#의 구문으로 자바에서 흔히보는 Assertion과 흡사하다. 위 예제는 설명을 위해 단순한 값에 대한 검증만을 기술하고 있지만 API레벨에서 이뤄지는 복잡한 동기화에 대한 기술도 가능하다.
Spec#에 대해 좀 더 자세히 알고 싶으신분은 공식 사이트를 방문해 보시길 권한다.

멀티코어,비동기, 동시성, 함수형 그리고 검증 주도 개발(Verification-Driven Development,VDD)

필자가 정확한 검증에 주목하는 이유는 유닛테스트나 e2e테스트와 같은 기존의 테스트 패러다임으로는 동시성과 관련하여 발생하는 오류를 찾아내기가 힘들기 때문이다. 오늘날의 컴퓨팅 한경은 멀티코어가 일반화 됨에 따라 이에 대응하기 위한 비동기, 동시성 프로그래밍 패러다임이 출연하였다. 그리고 이를 보다 효과적으로 구현하기 위한 함수형 프로그래밍은 본격적으로 하나의 큰 흐름을 시작하고 있는 단계이다. 비동기 프로그래밍의 가장 큰 난관으로 꼽히는 것은 테스트의 어려움이다. 발생할 수 있는 경우의 수에 대한 파악도 어렵고 재현도 어렵기 때문이다. 이제 막 보급되기 시작한 이러한 새로운 개발 패러다임 에는 테스트의 복잡도 제어와 효율적인 검증이라는 큰 숙제가 여전히 남겨져 있는 상태인 것이다.
하지만 만약에 코드 자체가 스스로의 완전성을 보장해 준다면 어떨까?
정확한 검증이 그 대안이 되어 줄 수 있지 않을까? 꿈같은 이야기로 들릴지 모르지만 어차피 지금 우리들이 사용하는 기술들은 과거엔 마법같이 여겨지던 것들이다.
이교수님의 말씀처럼 가까운 실일내에 정확한 검증 기술이 상용 코드에 적용 가능한 수준으로 성숙된다면 BDD를 넘어서서 검증 주도 개발(VDD)이라는 패러다임이 등장할 수도 있다는 것이 필자의 생각이다.

필자의 의견으로는 지금 현업에 있는 대부분의 프로그래머에게 있어 당장 정확한 검증을 익혀두거나 도입을 서두를 필요는 없을것이라 본다. 다만, Cucumber와 같이 트레이드 오프에 대한 검증이 끝난 BDD 프레임웍의 도입은 DevOps시대를 맞이하여 효율적인 품질관리와 생산성 증대를 위해서라도 살펴봐 두는 자세가 필요할 것이다.


참고 문헌 & 관련 링크


※이광근 교수님의 피드백을 받아 학술 용어의 번역에 대해서 수정을 하였습니다.(2016.1.17)