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

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