2021년 회고 - 이직 후기

원래는 2 편의 글로 2021년을 마무리하려고 했습니다. 다른 글에서는 제가 올 해 겪었던 일들을 써 보려고 했었어요. 예를 들어 작년 10월에 촬영했었던 This is My Architecture 영상이 공개되었다거나, 매월 블로그에 글 하나씩 쓰는 것을 목표로 했는데 목표를 달성했다거나, 낮에는 개발하고 밤에는 복면 쓰고 락 밴드를 하는 사람들을 소재로 소설을 쓰려고 했는데 반 정도만 쓰고 말았다거나, 장롱면허여서 운전 연수를 받았다거나, … 아무튼 여러 일들이 있었습니다. 그러다가 ‘시시콜콜한 이야기를 하는 게 무슨 의미가 있나?

Terraform vs Pulumi

클라우드 환경 내 인프라 구성이 복잡할수록 IaC(Infrastructure as Code) 툴을 고민하게 되는데요. 물론 AWS의 CloudFormation과 같이 클라우드 벤더가 제공하는 서비스가 있지만, 앞으로는 특정 벤더에 종속되는 것을 피하고 싶다는 생각이 들었습니다. 그러다가 알아본 툴 중에 Terraform과 Pulumi가 있는데요. Terraform은 저도 개인적으로 사용해 본 적이 있었고, Pulumi는 익숙한 개발 언어(Python, TypeScript, Golang, …)로 인프라 구성을 구축할 수 있다고 해서 관심을 갖게 되었습니다. 이번 글에서는 AWS에서 EC2, S3 Bucket, IAM Policy, Role 정도를 만드는 정도로 테스트해 보겠습니다.

Python에서 logging으로 로그 만들기

프로그램이 잘 동작하는 지 확인하고 싶다면, print()를 쓸 때가 많습니다. 하지만 프로그램이 복잡하게 바뀌면서 print()만으로는 감당하기 어려운 상황이 발생합니다. 그럴 때 어떻게 로그를 만들고 관리할 지를 고민하게 되는데요. 이번 글에서는 Python에서 logging 모듈을 활용해서 어떻게 로그를 관리할 수 있는지 살펴보려고 합니다. 기본적인 로깅 만들기 logging 모듈을 이용해서 로그를 만드는 방법은 다음과 같습니다. import logging logging.critical('Critical log') logging.error('Error log') logging.warning('Warning log') logging.info('Info log') logging.debug('Debug log') 스크립트를 실행해 보면 다음과 같이 표시됩니다.

AWS Session Manager & Run Command로 외부에서 쉘 스크립트 실행하기

AWS의 Systems Manager에는 Run Command와 Session Manager라는 기능이 있습니다. SSH를 이용하여 EC2 인스턴스에 접근할 때는 SSH 키 페어가 필요하고, SSH 접속을 위한 보안 그룹을 열어야 하는데요. 위 기능을 이용하면 이러한 과정을 생략하고 원격에서 EC2 인스턴스에 접근하여 명령을 실행할 수 있습니다. 먼저, Session Manager로 웹 브라우저에서 쉘을 실행하는 방법부터 설명드리겠습니다. Session Manager로 웹 브라우저에서 쉘 실행하기 Session Manager로 웹 브라우저에서 쉘을 실행하려면, EC2 인스턴스가 Systems Manager와 관련된 작업을 실행할 수 있는 권한을 부여해야 합니다.

CloudFormation과 SAM을 쓰면서 겪었던 일들 모음

최근 인프라 구성을 CloudFormation을 이용해서 조정해 보았습니다. 그 과정에서 여러 Lambda 함수를 쓸 때는 SAM으로, 그 외의 경우는 CloudFormation을 사용했는데요. 이번 작업으로 여러 CloudFormation 스택에 흩어져 있던 리소스를 하나로 모으고, 템플릿의 관리 방식도 좀 더 관리하게 편하도록 설정할 수 있게 되었습니다. 저희 팀이 여러 IaC(Infrastructure as Code) 툴 중에 왜 SAM과 CloudFormation을 사용하는 이유는 이 문서를 참고해 주세요. 이번 글은 CloudFormation과 SAM을 쓰면서 겪었던 일들을 정리해 보려고 합니다. SAM에서 API Gateway 정의를 SAM Template에 넣기 SAM에서 제공하는 AWS::Serverless::Api 리소스는 AWS Gateway의 REST API를 생성해 주는 기능입니다.

EKS 내 NGINX Ingress에서 NLB와 ACM 연동 방법 살펴보기

최근 팀 내에서 외부 서비스와 연동하는 서비스가 증가하면서, 고정된 IP 주소를 요청하는 경우가 많아졌습니다. 한편, 대외 서비스가 늘어나다 보니 관리하는 서버의 수가 증가하였습니다. 그렇지만 생각보다 트래픽이 많지 않아 리소스가 낭비되는 경우가 많은데요. 이러한 상황을 겪으면서 서버의 수를 줄이고, 서비스마다 고정된 IP 주소를 제공할 방법을 찾아보게 되었습니다. 그러다가 Kubernetes와 Kubernetes의 Ingress를 적절히 활용하여 이러한 요건을 충족하는 방법을 찾아보았습니다. 이번 글은 그 과정에서 겪었던 이슈를 정리하기 위해 작성하였습니다. EKS와 NGINX Ingress Controller 사용 저희 팀의 웹 서비스들은 Elastic Beanstalk를 주로 이용하고 있습니다.

Boto3를 쓰면서 겪었던 일들 모음

Python을 이용해서 AWS의 여러 기능을 자동화 할 때 Boto3를 많이들 쓰실 것 같은데요. 이번 달에는 Boto3를 쓰면서 궁금했던 것, 또는 자주 사용할 만한 것들을 정리해 보려고 합니다. 현재 사용 중인 AWS 계정 ID 얻기 여기서 계정 ID라고 하면, 12자리의 숫자로 구성된 계정의 ID를 의미합니다. import boto3 account_id = boto3.client('sts').get_caller_identity().get('Account') 출처: Stack Overflow 에러 다루기 출처: Boto3 Documentation Boto3의 코드를 열어보면, 서비스에 따라 발생할 수 있는 모든 에러를 저장하고 있지 않습니다. Boto3와 AWS CLI의 기반이 되는 Botocore 프로젝트의 코드에서도 모든 종류의 예외를 다루지 않습니다.

Open Badges 소개

저는 초등학생 때 아람단에 가입해서 이런저런 활동들을 해 봤는데요. 열심히 활동하는 편은 아니었지만, 뭔가 활동을 하면 배지를 얻을 수 있었습니다. 적극적으로 활동하는 친구들은 아람단 단복에 정말 많은 배지들을 달고 있었던 기억이 납니다. 이러한 배지 시스템은 스마트 폰의 앱이나 웹 사이트에서도 볼 수 있습니다. 예를 들어 제가 운동할 때 사용하는 앱 중 하나인 Nike Training Club은 특정한 조건을 달성하면 새로운 기록을 만들 수 있는데요. 아래는 Nike Training Club 앱에서 제가 달성한 기록들 중 일부입니다.

데이터 분석 워크플로우를 처음부터 만들어 보기 (2)

2월에 올렸던 데이터 분석 워크플로우를 처음부터 만들어 보기에 이어서 작성하는 두번째 글입니다. 그동안 시도해 봤던 것들은 다음과 같습니다. S3 버킷에 원격으로 로그 올리도록 설정하기 Airflow 2.x 버전에서 KubernetesExecutor를 사용하는 데, DAG이나 Task를 수동으로 실행할 때 에러가 발생하는 이유는? DAG에서 DB 이용하기: DB와 관련된 Operator 이용하기, Hooks 이용하기 S3에서 파일을 가져와서 분석하기: S3Hook 테스트 한 환경은 Airflow 2.0.1, 2.0.2 버전입니다. 전체 내용은 GitHub 저장소에서 확인하실 수 있습니다. S3 버킷에 원격으로 로그를 올리도록 설정하기 지난 글에서 시스템 구성으로 KubernetesExecutor를 이용한다고 말씀드렸습니다.

Locust 1.0 이후 달라진 점들 요약

작년 이맘때에 AWSKRUG에서 ECS+Locust로 부하 테스트 진행하기라는 주제로 발표를 한 적이 있었습니다. 그러다가 5월에 Locust 1.0 버전이 나왔는데요. 최신 버전의 Locust로 부하 테스트를 진행하다 보니 바뀐 부분이 많아서, 새 버전으로 테스트를 수행하기 위해 필요한 내용 위주로 다시 정리해 보려고 합니다. 이 글은 위에 링크한 슬라이드 중 11~19 페이지의 내용을 대체합니다. 지금부터 한 번 살펴보겠습니다. Locust -> User 클래스 이름 변경 한 명의 사용자를 표현하는 Locust 클래스가 ‘User’로 이름을 바꾸었습니다. HTTP를 이용하는 클라이언트는 HttpLocust에서 HttpUser로 클래스 이름을 바꾸었습니다.