카테고리 없음

AWS SAM로 AWS Lambda 구축 시 Lambda에서 AWS S3 혹은 AWS DynamoDB에 접속 시 권한 에러가 나는 상황 해결

100억벌면이바닥뜬다 2023. 1. 30. 01:08
728x90

사전지식

aws sam(기본 개념정도만 알아도 이해 가능)

aws lambda

aws cloudformation(기본 개념정도는 알아도 이해 가능)

aws iam(기본 개념정도는 알아도 이해 가능)

aws s3

aws dynamodb

python boto3


 

상황

세 가지 상황을 해결했다.

  1. S3 접근 시 access denied
  2. BucketAlreadyOwnedByYou
  3. S3 버켓의 creation_date속성이 none값

1부터 3까지 차례대로 일어났고 해결하기 위해 이것저것 테스트 하면서 일어난 상황에 대해 기록을 남긴다.


나는 AWS Lambda에 코드를 직접 올리지 않고 Docker로 만든 후 AWS SAM을 통해 AWS ECS로 업로드 후 Lambda는 Docker 이미지를 통해 실행하는 구조다.

그렇기 때문에 테스트 시 Dockerfile에 AWS 환경변수를 저장 후 boto3을 통해 환경변수를 읽어 들여서 S3 혹은 DynamoDB에 접근해서 개발 한 다음 SAM을 이용해 동일한 환경으로 업로드를 하고 Lambda를 실행하니 접근에러(access denied)가 나면서 실패했다.

env AWS_ACCESS_KEY_ID=Here Your Access Key Id \
AWS_SECRET_ACCESS_KEY=Here Your Access Key Password

위와 같이 boto3에서 사용할 키 id와 password를 환경변수로 사용했을 시 테스트 시에는 정상작동 하면서 Lambda에 올라가면 실패가 나는 건지 처음에는 이해가 안 갔다.

https://tech.cloud.nongshim.co.kr/2021/03/12/boto3%EA%B0%80-aws%EC%9D%98-%EC%9E%90%EA%B2%A9%EC%A6%9D%EB%AA%85credentials%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EC%88%9C%EC%84%9C-from-python/

 

[매뉴얼] Boto3가 AWS의 자격증명(Credentials)을 확인하는 순서 .from Python

  I.   개요 이번 포스팅은 'Boto3가 AWS의 자격증명(Credentials)을 확인하는 순서' 인 Credentials — Boto3 Docs 1.17.21 documentation > Configuring credentials

tech.cloud.nongshim.co.kr

위 사이트처럼 자격증명 순서도 맞는데 왜 그런 걸까 생각하며 테스트를 했다.

처음으로 시도해 본 테스트는 S3의 접근권한을 모두 허용(퍼블릭) 속성으로 바꿔봤다.

Lambda를 실행시키니 S3 버켓에 접근은 되지만 접근 후 버켓의 생성날짜를(creation_date) 가져오는 부분에서 가져오지 못하고 none값을 출력했다.

그리고 내가 만든 코드는 Lambda 실행 시 creation_date이 none일 경우 버켓이 생성 안된 상황으로 인식해 코드 내에서 S3 버켓을 생성하는 구문을 실행한다.

그렇기 때문에 중복으로 버켓을 생성할 수 없다는 에러(BucketAlreadyOwnedByYou)가 나면서 실패했다.

한참 동안 S3 권한을 이것저것 건드려 보다가 S3 버켓에는 문제가 없고 다른 부분에 문제가 있는지 확인해 봤다.

 

두 번째로 테스트해본 건 Lambda가 참고하는 AWS 환경변수목록을 출력해 봤다.

그리고 충격을 먹게 됐는데.. 예상한 대로 Lambda가 참고하는 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY값이 내가 Dockerfile에 설정한 값과 다른 값이 출력되었다.

위에 링크에서와 같이 AWS 자격증명을 제대로 하지 못하는 상황이었다.

이런 경우는 처음이라 당황하면서 왜 이런 일이 났을까 생각을 해봤다.

그렇게 생각하니 드는 생각.. SAM 사용 시 SAM에 권한 설정(Role)을 새로 만들어서 Lambda에 권한 연결을 하는데 거기서 생성한 권한이 내가 Dockerfile에 설정한 권한보다 우선순위가 높기 때문에 적용이 안되는가?라는 생각을 하게 됐다.(이 분은 내 생각으로 ECS 및 SAM 도큐먼트를 링크로 남기겠다)

그렇다면 어떻게 해야 S3&DynamoDB에 접속 권한을 추가해서 Lambda에 연결할까?

가장 완벽한 건 SAM으로 생성 시 권한 부분에 추가하는 거지만 아직 거기까지 공부를 안 해서 수동으로 권한을 설정하는 방법으로 테스트해 보기로 했다.

 

AWS Iam에 접속 후 탭에서 역할 선택을 하면 위와 같은 화면이 나온다.

그중에서 SAM으로 생성 시 만든 역할을 선택한다.

권한추가를 누른 다음 AmazonS3 FullAccess, AmazonDynamoDBFullAccess권한을 추가한다(라이브 환경이라면 전체 권한을 주는 것보다 필요한 권한만 주는 게 보안상 좋다) 나는 테스트를 위해 S3, DynamoDB에 대해 전체 권한을 줬다.

위와 같이 설정 후 Lambda를 실행시키니 잘 된다.

SAM과 ECS에 대한 최소한의 개념만 사용하다 보니 권한 부분에서 안일하게 되겠지란 마음으로 Dockerfile에 AWS Key Id, Password 설정하다 삽질로 하루를 날렸다.

근데 위 방법은 임시방편으로 SAM을 통해서 권한 설정을 해주는 방식으로 해야 한다.


참고링크

ESC 환경변수

https://docs.aws.amazon.com/ko_kr/AmazonECS/latest/developerguide/taskdef-envfiles.html

 

컨테이너로 환경 변수 전달 - Amazon Elastic Container Service

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

SAM 

https://docs.aws.amazon.com/ko_kr/serverless-application-model/latest/developerguide/what-is-sam.html

 

AWS Serverless Application Model(AWS SAM) 는 무엇입니까? - AWS Serverless Application Model

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com