Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.

AWS Transfer 패밀리로 SFTP 구성하기 #1

AWS Transfer 패밀리는 AWS에서 관리해주는 SFTP 서버로 S3를 스토리지로 사용할 수 있고 2018년에 공개되었다. 개발 자동화에는 API나 CLI를 이용하는 것이 더 편하지만, 업무의 성격상 SFTP를 운영해야 하는 경우가 있다.

SFTP를 운영하는 게 대단한 노력이 드는 것은 아니지만 또 용량관리나 계정 관리 등 은근히 관리하기 귀찮기도 하다. 그럴 때 AWS Transfer 서버는 괜찮은 대안이 될 수 있지만, 가격이 싸진 않다. SFTP에 접속할 수 있는 엔드포인트를 기준으로 시간당 $0.30이 과금되기 때문에 한 달을 운영한다면 $216가 되고 업로드에 기가당 $0.04가 들기 때문에 이득이 되는지 가격을 잘 계산해 봐야 한다. 회사에서 인프라가 커지면 $200가 큰 비용은 아니지만 그래도 하는 일에 비해서는 좀 비싸다는 생각은 든다.

작년에 필요해서 이 SFTP 서버 구성을 좀 만져봤는데 미루다가 이제야 정리를 한다. AWS Transfer 패밀리에서는 프로토콜도 SFTP, FTPS, FTP 중에서 선택해서 사용할 수 있지만, 서비스 프로바이더도 "Service managed"와 "Custom"으로 나뉜다. "Service managed"는 사용자 관리는 AWS Transfer 패밀리 내에서 다 할 수 있고 Custom은 Amazon API Gateway와 연결해서 사용하는 방식이다. 장단점이 있는데 비교하기 위해 "Service managed"를 먼저 만들어 보자.

Service managed AWS Transfer for SFTP 구성

Terraform으로 구성하기 위해 일단 Terraform 설정을 한다. 여기선 Terraform v0.12.29를 사용했다.

provider "aws" {
  region = "ap-northeast-2"
  version = "~> 3.8"
}

SFTP의 파일을 저장할 S3 버킷을 먼저 생성한다.

resource "aws_s3_bucket" "stfp-sample" {
  bucket        = "outsider-sftp"
  acl           = "private"
}

꼭 필요한 건 아니지만 SFTP의 활동을 CloudWatch에 로그를 남길 수 있어서 로깅을 위한 IAM Role을 생성했다. transfer.amazonaws.com AssuemRole을 지정하고 CloudWatch에 로그를 남길 수 있도록 권한을 부여했다.

resource "aws_iam_role" "sftp_logging" {
  name               = "sftp-logging"
  description        = "write logs from transfer"
  assume_role_policy = data.aws_iam_policy_document.sftp_logging.json
}

data "aws_iam_policy_document" "sftp_logging" {
  version = "2012-10-17"
  statement {
    effect = "Allow"

    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["transfer.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy_attachment" "sftp_logging" {
  role       = aws_iam_role.sftp_logging.name
  policy_arn = aws_iam_policy.sftp_logging.arn
}

resource "aws_iam_policy" "sftp_logging" {
  name   = "sftp-logging"
  policy = data.aws_iam_policy_document.sftp_logging_cloudwatch.json
}

data "aws_iam_policy_document" "sftp_logging_cloudwatch" {
  version = "2012-10-17"
  statement {
    sid       = "AllowFullAccesstoCloudWatchLogs"
    effect    = "Allow"
    actions   = ["logs:*"]
    resources = ["*"]
  }
}

Terraform에서는 aws_transfer_server를 사용해서 SFTP를 생성할 수 있다.

resource "aws_transfer_server" "service_managed_sftp" {
  identity_provider_type = "SERVICE_MANAGED"
  logging_role           = aws_iam_role.sftp_logging.arn
}

AWS Transfer Family에 접속하면 SFTP 서버가 생긴 것을 볼 수 있다.

AWS Transfer에 생성된 SFTP 서버

잘 만들어졌지만, 호스트네임을 지정하지 않았으므로 호스트네임이 지정되어 있지 않다. 안타깝게도 AWS API에서 이 기능을 제공하지 않기 때문에 Terraform 리소스에서도 이를 지정할 수 없다. Terraform으로 관리하고자 한다면 꼼수가 있기는 하다.

먼저 Route53에 연결할 DNS 레코드를 생성한다. 여기서는 sftp.outsider.dev를 사용했다. 이 레코드는 CNAME으로 aws_transfer_server.service_managed_sftp.endpoint에 연결하는데 <Server ID>.server.transfer.ap-northeast-2.amazonaws.com의 형태가 되므로 여기서는 s-faabc20d45d74e9a9.server.transfer.ap-northeast-2.amazonaws.com이 된다.

resource "aws_route53_record" "sftp_outsider_dev" {
  zone_id = aws_route53_zone.outsider_dev.zone_id
  name    = "sftp.outsider.dev"
  type    = "CNAME"
  ttl     = "300"
  records = [aws_transfer_server.service_managed_sftp.endpoint]
}

이를 null 프로바이더를 이용해서 sftp 서버에 커스텀 호스트네임을 지정해 준다. null 프로바이더를 추가했으므로 terraform init으로 설치해 주어야 하고 여기서는 local-exec 프로비저너를 이용해서 로컬의 AWS CLI를 이용해서 SFTP 서버에 aws:transfer:customHostname을 지정해 주는 방법이다. 즉, 로컬에 AWS CLI가 설치되어 있어야 한다.

provider "null" {
  version = "~> 2.1"
}

resource "null_resource" "service_managed_sftp_custom_hostname" {
  depends_on = [aws_transfer_server.service_managed_sftp]

  provisioner "local-exec" {
    command = <<EOF
aws transfer tag-resource \
  --arn '${aws_transfer_server.service_managed_sftp.arn}' \
  --tags 'Key=aws:transfer:customHostname,Value=sftp.outsider.dev' \
  --region 'ap-northeast-2'
EOF
  }
}

아래처럼 커스텀 호스트네임이 지정된 것을 볼 수 있다. 태그라서 Terraform으로도 가능할 것처럼 보이지만 Terraform의 태그로 지정하면 InvalidTag: System tags cannot be added/updated by requester 오류가 발생한다.

생성된 SFTP 서버에 sftp.outsider.dev 도메인이 설정됨

서버는 설정되었으므로 이제 SFTP에 접속할 사용자를 추가해야 하는데 그전에 이 사용자한테 부여할 IAM Role을 생성한다. 이 Role이 앞에서 만든 S3 버킷에 접근할 권한을 지정한다. 즉, 사용자에게 권한을 다르게 주고 싶다면 Role을 여러 개 만들어서 사용자를 생성할 때 지정해 주면 된다. 여기서는 사용자마다 디렉터리를 부여하고 자신의 디렉터리만 접근할 수 있도록 권한을 부여했다.

resource "aws_iam_role" "sftp_user" {
  name               = "sftp-user"
  description        = "Access S3 bucket from tranfer SFTP"
  assume_role_policy = data.aws_iam_policy_document.sftp_user.json
}

data "aws_iam_policy_document" "sftp_user" {
  version = "2012-10-17"
  statement {
    effect = "Allow"

    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["transfer.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy_attachment" "sftp_user" {
  role       = aws_iam_role.sftp_user.name
  policy_arn = aws_iam_policy.sftp_user_s3_access.arn
}

resource "aws_iam_policy" "sftp_user_s3_access" {
  name   = "sftp-user-s3-access"
  policy = data.aws_iam_policy_document.sftp_user_s3_access.json
}

data "aws_iam_policy_document" "sftp_user_s3_access" {
  version = "2012-10-17"
  statement {
    sid    = "AllowListingOfUserFolder"
    effect = "Allow"
    actions = [
      "s3:ListBucket",
      "s3:GetBucketLocation"
    ]
    resources = ["arn:aws:s3:::${aws_s3_bucket.stfp_sample.id}"]
  }
  statement {
    sid    = "HomeDirObjectAccess"
    effect = "Allow"
    actions = [
      "s3:PutObject",
      "s3:GetObject",
      "s3:DeleteObjectVersion",
      "s3:DeleteObject",
      "s3:GetObjectVersion"
    ]
    resources = ["arn:aws:s3:::${aws_s3_bucket.stfp_sample.id}/*"]
  }
}

위 Role을 사용해서 testuser라는 SFTP 사용자를 만든다.

resource "aws_transfer_user" "test_user" {
  server_id      = aws_transfer_server.service_managed_sftp.id
  user_name      = "testuser"
  role           = aws_iam_role.sftp_user.arn
  home_directory = "/${aws_s3_bucket.stfp_sample.bucket}/testuser"
}

home_directory를 지정하지 않으면 /가 되는데 여기서는 사용자의 username으로 홈 디렉터리를 지정했다. 여기서는 사용자의 IAM Role을 하나만 만들었고 이 Role이 해당 S3 버킷의 전체 접근 권한을 가지고 있음으로 홈 디렉터리를 만들었을 뿐 다른 디렉터리의 접근 권한을 막은 것은 아니다.

SFTP 서버에 추가된 testuser 사용자

AWS 콘솔에 들어가면 사용자가 생성된 것을 볼 수 있다. 이 사용자가 로그인하려면 SSH 키가 필요하므로 테스트를 위해서 키를 생성한다.

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/outsider/.ssh/id_rsa): ./mykey
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./mykey.
Your public key has been saved in ./mykey.pub.
The key fingerprint is:
SHA256:Vk3hLaHQkSyyq/qS7R918ICTRUPAX/BPN8huHOUudiE outsider@Outsiderui-Mac-Pro.local

mykeymykey.pub이라는 파일이 생성되는데 "Add SSH public key"를 눌러서 공개키 파일인 mykey.pub의 내용을 복사해서 붙여넣으면 공개키가 등록된다.

testuser에 등록한 SSH 공개키

이제 비공개키를 이용해서 sftp.outsider.dev에 SFTP로 접속할 수 있고 지정한 대로 홈 디렉터리 위치로 접속된다.

SFTP 프로그램으로 서버에 접속해서 파일을 업로드

업로드한 파일이 S3에 잘 올라갔음을 확인할 수 있다.

지정한 경로에 파일이 S3에 올라가 있는 것을 확인

Service managed AWS Transfer는 쉽게 설정할 수 있지만, 실사용에서의 문제가 좀 있다. 사용자를 웹 콘솔에서 쉽게 설정할 수 있지만(여기서는 Terraform을 이용했지만...) 로그인을 비밀키/공개키 방식으로만 해야 한다는 점이다. 정상적으로 생각하면 SFTP에 접속하는 사람이 SSH 키를 생성하고 공개키만 나한테 전달해 주어야 내가 등록해 줄 수 있는데 회사에서 보통 SFTP를 쓰는 사람은 개발에 대한 이해도가 낮을 거로 생각되어서 SSH 키를 생성하도록 안내하기는 쉽지 않을 수 있다. 내가 비밀키/공개키를 모두 만들어서 줘도 되긴 하지만 비밀키를 쓰는 장점이 사라지고 사용자들은 아무래도 username/password 방식이 훨씬 익숙할 텐데 이 방식을 제공하지 않는다.

다른 방식의 로그인을 이용하려면 Service managed가 아니라 Custom AWS Transfer를 이용해야 한다. 글이 길어져서 Custom AWS Transfer는 다음 편에 다룰 예정이다.

2020/09/30 17:07 2020/09/30 17:07

오픈소스 컨트리뷰톤 2020 참가 후기

작년 컨트리뷰톤에 참가하고 어느새 1년이 지났다.

컨트리뷰톤 2020 공지

다시 컨트리뷰톤 2020이 열리는 걸 알았을 때는 고민을 많이 했다. 작년 경험이 좋기는 했지만, 올해는 작년과 달리 회사 업무가 바빠서 시간을 충분히 낼 수 있을지 걱정되었기 때문이다. 컨트리뷰톤을 하면 6주간은 꽤 시간을 써야 했고 작년에 해본 경험이 있어서 어느 정도 노력이 필요한지도 알았기 때문이다. 프로젝트 신청 마지막 날까지도 고민하다가 항상 내가 그렇듯이 일단 일을 벌이고 보자는 생각으로 작년과 똑같이 mocha로 신청했다.

26개 컨트리뷰톤 참가 프로젝트

작년보다 규모가 커져서 26개의 프로젝트(작년엔 20개)로 시작이 되었다.

참가자 선정

내가 생각하는 컨트리뷰톤의 목표는 작년과 달라지지 않아서 단순히 오픈소스 프로젝트에 기여를 경험하기보다는 오픈소스를 하고 싶은 생각은 많은데 어떻게 해야 할지 모르고 도움을 받을 사람이 없어서 못 하는 사람들에게 오픈소스 프로젝트가 어떻게 운영되는지 알려주어 오픈소스를 이해하고 컨트리뷰톤이 끝나도 여유가 된다면 오픈소스에 관심 가지면서 기여할 수 있도록 하는 것이었다.

이런 목표 아래 참가자를 선정했는데 올해는 프로젝트가 더 많아서인지 나도 바쁘다는 핑계로 따로 홍보하거나 하지 못해서인지 작년보다 적은 31명의 신청자가 있었고 작년에는 12명을 선정했는데 실제로 해보니 12명을 지원해주기가 혼자 쉽지 않아서 좀 더 현실적으로 올해는 10명만 선정했다.

작년의 경험이 있어도 참가자 선정은 역시 어려웠다. 경험이 많은 정윤원 님은 여러 가지 기준으로 참가자를 분류한 후에 선정하시던데 나는 그렇게까지는 못했고 참가지원서를 하나씩 읽어보면서 내가 생각하는 조건에 부합하고 끝까지 할 수 있을 것처럼 열정(간절함?)이 있어 보이는 참가자를 열심히 선정했다. 하지만 개별로 만나본 것도 아니고 간단한 자기소개, 지원동기, 프로젝트 개발 경험만으로는 분별력이 높지 않아서 선정하기가 쉽지 않았다. 이력서랑 비슷하게 지원서도 모두가 다 오픈소스를 하고 싶고 열심히 할 거라고 쓰기 때문이다.

작년 Armeria처럼 프로젝트 소개에 mocha 프로젝트를 클론 받아서 환경 설정하고 테스트를 돌려본 경험을 지원서에 써달라는 요청을 했다.

물론 이 요청은 이걸 성공적으로 잘한 사람만 뽑겠다는 것은 아니었고 그 과정에서 익숙도 혹은 문제가 생겼을 때 어떻게 대처하는지, 그리고 지원할 때의 시간을 쓸 정도로 얼마나 관심 있는지를 엿보기 위함이었다. 몇 가지 잘못 생각한 것은 프로젝트 설명에 적어놓은 이 안내를 모두가 따른 건 아니라서 이것만 조건으로 고를 수 없었다는 점이었다. 몇몇 사람은 이 부분이 큰 도움이 되었지만 몇몇은 그렇지 않았다. 그리고 이미 오픈소스 기여에 대해 주변에서 도움을 받을 수 있다고 생각되는 사람은 오히려 뽑지 않았는데 다음에는 프로젝트 설명에 이런 부분도 잘 명시해야겠다는 생각이 들었다. 아주 명확한 기준은 아니었지만, 작년에는 정말 처음 해보는 사람 위주로 뽑으려고 했다면 서로 도움을 주는 것도 꽤 도움이 되는 것 같아서 이번에는 개발 경험이 좀 있는 사람도 약간 섞었다.

컨트리뷰톤 진행

컨트리뷰톤은 8월 1일부터 9월 14일까지 6주간 진행이 되었다. 참가자는 7월 중순에 선정되었는데 회사 일이 바빠서 7월 말 발대식을 하기 전까지는 따로 참가자들과 커뮤니케이션을 하지 못했다. 지나서 생각하면 이때 시간을 더 잘 썼으면 좋았겠다 하는 생각이 들었다.

mocha 발대식 모임

발대식은 올해부터 새로 생긴 오픈소스 소프트웨어 통합지원센터의 Open UP에서 진행이 되었다. 작년에는 발대식도 모든 프로젝트가 모여서 발대식을 했는데 올해는 코로나 이슈로 프로젝트별로 따로 모여서 아무래도 조촐한 느낌이었다. 주최 측에서 예전 컨트리뷰톤에 참가하셨던 멘토들의 컨트리뷰톤 안내에 대한 영상을 2개나 만들어 주어서 행사 자체에 대한 설명이나 동기부여는 여기서 많이 해결되었고 프로젝트에 대해 설명만 했다.

작년의 경험이 있어서 온라인으로만 진행해야지 하는 생각은 하지 않았지만, 초기에 직접 이슈도 찾아보고 문제 해결도 해보는 시간이 필요하다고 생각했기 때문에 정기 미팅은 매주 화요일 저녁 10시에 온라인으로 진행했다. 이 정기 미팅은 컨트리뷰톤이 끝날 때까지 계속 진행했고 한 번에 1시간 반에서 2시간 정도를 진행한 것 같다. 일부러 고생을 시키는 것은 아니지만 직접 해보고 고민하는 시간이 필요하다고 생각하기 때문에 첫 3주는 온라인으로 진행하면서 진행했다. 회사가 바쁜 건 사실이었지만 바빠서 미뤄둔 건 아니었다.

작년처럼 오픈소스의 역사와 거대 담론을 설명하고 이해시켜야지 하는 무모한 생각은 하지 않고 첫 주부터 프로젝트 설명하고 구조와 사용되는 도구들, 어떻게 기여를 할 수 있고 분위기는 어떤지, 이슈는 어떻게 찾아야 하는지, 나랑 어떻게 작업할지 등을 설명하고 주차가 진행되면서 테스트 코드 돌리는 방법이나 로그 보는 법 등을 필요에 따라 설명했다. 처음에는 프로젝트 설명하다 보니 내가 할 말이 많아서 2시간 내내 거의 나 혼자 얘기했지만 3주 정도 지나서부터는 현재 보고 있는 이슈나 작업하는 내용을 돌아가면서 설명하고 거기에 맞춰서 이해 안 된다는 추가 설명하는 방식으로 진행을 했다. 대부분 참석하셨지만, 혹시 참석 못 하는 사람을 위해서 매번 회의는 녹화해서 파일로 공유했다.

참가하신 분들이 시작부터 적극적으로 다양한 Slack 채널도 만들고 mocha를 알아야 하니 사용해 보고 오라는 요청에 별도의 Git 저장소에서 여러 가지 테스트를 만들어 보면서 학습하셨는데 이때 초반에 좀 더 적극적으로 지원했어야 했나 하는 아쉬움도 약간 든다. 이때는 나도 아직 컨트리뷰톤에 몰입하지 못했고 회사 일이 바쁘다 보니 일일이 다 챙기지는 못했다.

스프린트 모임과 코로나 2차 웨이브

절반이 지나는 4주 차부터 오프라인 코딩 스프린트 모임을 진행하면서 속도를 높일 계획이었으나 8월 중순에 코로나 2차 웨이브가 터졌고 오프라인 모임을 할지 말지 고민하다가 오프라인과 온라인을 섞어서 내가 토즈를 예약하고 괜찮으신 분들은 나오고 나오기 어려운 분들은 온라인으로 같이 작업하도록 했다. 1시부터 6시까지 토/일을 모두 예약해 놓고 진행했는데 코로나 때문에 각각 오프라인에 2분, 4분 정도가 참여했고 온라인으로 2~3분이 참석을 하셨다. 확실히 오프라인으로 진행하니까 문제 파악도 쉽고 같이 봐 드리는 게 좋은 점이 많았다.

코로나 이슈가 점점 심각해 지고 있어서 회의에서 오프라인 모임을 어떻게 할지 논의했는데 그래도 오프라인 모임이 있는 게 좋다는 의견이 많아서 그 전주처럼 온라인/오프라인을 섞어서 매주 일요일에 모이기로 했지만 코로나가 2.5단계로 격상되면서 모일 장소가 없어졌기에 온라인 스프린트 모임으로 모두 전환해 버렸다. 체인점이 아닌 카페라면 모일 수도 있었겠지만, 정부에서 모이지 말라고 하는 상황에 모이기도 애매했다.

어떻게 할 수가 없는 상황이라서 약속한 주말 1시~7시 정도까지 작업 시작할 때 공유하고 중간에 질문받거나 작업한 거 공유하고 필요하면 화상채팅을 열어서 도와주는 방식으로 진행했는데 온라인이다 보니 집중력은 좀 떨어진 것 같다. 그래도 마지막까지 잘 따라와 주셔서 마지막 주에는 토/일 모두 스프린트 모임을 하면서 컨트리뷰톤을 마쳤고 지난 26일 최종 발표회까지 끝냈다.

컨트리뷰톤 결과

10분을 선정했지만, 마지막까지 완주하신 분은 7분이었다.

  • 참가자 모두가 1개 이상의 PR을 올리셨고
  • 전체 PR은 19개로 작년과 비슷했다.
  • mocha 외에 프로젝트에도 2개의 PR이 있었는데 단순히 mocha 기여만이 아닌 오픈소스 생태계에 이해라는 목표에 부합하기 때문에 난 이 2개가 아주 소중했다.

    • impro에 올린 PR은 mocha의 문서 문제를 수정하면서 원인을 따라다가 보니 알게 된 문제를 수정한 것이었다. 정확히는 mocha의 의존 라이브러리가 사용하는 의존 라이브러리에서 발생한 문제로 이를 통해 mocha 문제를 해결한 건 아니지만 문제를 발견했으므로 이쪽도 고쳤다.
    • nuxtjs.org에 올린 PR은 다른 작업 하시다가 사이트가 깨지는 것을 보고 그냥 지나치지 않고 PR까지 올려서 수정한 PR이다.
  • 8.1.2 릴리스가 되면서 참가자 중 4분이 Author에 이름을 등록했다.

컨트리뷰톤 최종 수상팀 발표에 mocha는 장려상

시작할 때 항상 상을 받는 게 목표가 아닌 점을 강조하지만, 작년과 마찬가지로 장려상을 받게 되었다. 주객전도가 되는 게 싫을 뿐이지 노력하고 결과도 있는 게 싫은 건 아니니까... 끝나고 참가자분들이 후기에도 좋은 경험을 많이 얘기해 주셔서 나도 기분이 좋았다.

느낀 점

7분이셨지만 역시 mocha 프로젝트에서 적당한 이슈를 계속 찾아서 작업할 수 있게 공급하는 게 제일 어렵긴 했다. 알려진 문제 중 쉬운 것은 금방 해결되기도 하고 몰랐던 이슈를 찾아보려면 시간도 많이 필요하고 난이도까지 알려면 더 많은 시간이 걸려서 더 어려웠다.(힘들게 찾아서 알려드렸는데 금세 해결하면 나는 다시 쫓기는 기분이 들어서.. ㅠ)

가장 아쉬운 건 역시 코로나로 인한 상황이었던 것 같다. 6주간 고생하고 최종발표회 때 다 같이 모여서 mocha의 발표도 보고 다른 프로젝트의 발표도 보면서 배우고 느끼는 게 많을 텐데 이번에는 상황상 심사하는 멘토들만 모이고 발표자만 온라인으로 진행했기 때문에 다른 프로젝트는 커녕 자신이 참가한 프로젝트의 발표도 못 들었기에 컨트리뷰톤이 끝나는 느낌을 깔끔하게 받지 못했을 것 같아서 아쉽다. 다 같이 "짝짝짝 고생하셨습니다."하고 끝냈어야 했는데...

결과를 보면 다들 열심히 해주셔서 결과는 나왔지만, 작년과 비교하면 오프라인으로 만나지 못해서 친밀도 면에서 큰 차이가 나게 느껴진다. 실제로 얼굴을 모두 본 것은 발대식 한 번이었고 다른 분들은 오프라인 모임 2번 모였을 때 나오신 분이다. 화상회의도 카메라를 끄고 참여하시다 보니 몇몇 분은 내가 얼굴을 제대로 외우지 못했다. 작년에는 컨트리뷰톤이 끝나고 개인적인 인간관계도 맺어졌다는 느낌이 있었다면 이번에는 그 부분에서는 부족함이 많이 느껴진다. 이럴 줄 알았으면 발대식한 날 저녁이라도 같이 먹을 걸 그랬다.(그때가 제일 많이 모인 날일 줄은 몰랐다.) 가장 큰 차이가 2019년 참가자분들은 "아싸님"이라고 나를 부르지만, 올해 참가자분들은 "멘토님"이라고 부른다.(이런 호칭 부담스러운데...) 중반이 지나면서 내가 몰입도가 막 올라와서 오프라인 모임을 열심히 진행하려던 찰나에 온라인으로 모두 전환해서 참가자분들이 몰입도를 계속 유지하기 어려웠을 것도 같고...

내 성향이기도 한데 뭔가 하겠다는 분들은 최선을 다해 도와드리지만 그렇지 않은 사람에게는 특별한 액션을 취하지 않는 게 이번에도 고스란히 드러났다. 3분이 컨트리뷰톤 과정 중 이탈했는데 이탈을 막기 위한 액션을 아무것도 하지 않았다. 기본적으로 컨트리뷰톤이 참가자들이 하는 행사이고 나는 그걸 지원해주는 사람이라는 생각을 하고 있긴 하고 내 여력으로 보아도 그 정도까지 챙기기는 어렵다는 생각은 하고 있었지만 끝나고 보니 행사의 취지를 생각했을 때 다른 일로 안 하게 했다면 모를까 뭘 해야 할지 몰라서 뒤처지고 있다면 좀 더 참여할 수 있게 북돋아 주는 행동을 해야 했지 않나 싶긴 하다. 물론 자잘하게 Git에 대한 추가 설명이나 node.js 프로젝트에 대한 설명을 초반에 좀 더 했었으면 좋았겠다 하는 생각도 든다.

나에겐 mocha 메인테이너의 몰입을 계속 유지하는 방법의 하나인데 올해도 즐거운 경험을 했다.

2020/09/29 22:29 2020/09/29 22:29