Python과 AWS S3연동하기

이정규·2021년 10월 18일
1

버킷 생성

  1. S3에서 버킷을 생성한다.
  2. 버킷을 생성할 때 퍼블릭 엑세스 차단을 해당과 같이 설정한다.

이렇게 하지 않으면 이미지를 s3에 올려도 해당 이미지를 찾을 수 없다는 에러 메시지가 뜰 것이다.
  1. 나머지는 그대로 냅두고 버킷을 생성한다.

버킷 정책

버킷 정책을 설정해줘야 해당 올린 url을 통해 이미지나 동영상을 얻어올 수 있다. 설정해보자!

  1. 만들어둔 버킷을 클릭한다.
  2. 권한을 누르고 내리다보면 버킷 정책이라는게 있다. 거기서 편집을 누르자.
  3. 여기서 정책 생성기 를 누르자.

  1. 여기서 S3 Bucket Policy를 설정한다.

  1. 우리는 이미지를 띄우는 것만 할 것이기 Actions에서는 s3:GetObject 만 설정한다.
  2. ARN에서는 arn:aws:s3:::{자신이 만든 bucket name} 으로 설정한다. 밑에 다음과 같은 그림으로 설정하면 된다.

  1. Add Statment 를 누르고, Generate Policy 를 누른다. 그러면 무슨 json형식에 코드들이 뜰것이다.

해당 코드를 복사한다.

  1. 복사한 코드를 정책에다가 그대로 붙여넣기 한 뒤, 변경 사항을 저장한다. 이제 그러면 이미지를 url에서 접근해도 뜰 것이다!

하지만, 아직 s3를 외부에서 접근하는 것은 불가능하다. 이를 설정하기 위해서는 IAM을 설정해야한다.

IAM 설정

AWS에서는 IAM에서 사용자를 만들어 각각 aws에 있는 리소스에 접근하게 설정하라고 권장한다. aws의 루트 사용자로 모든것을 진행했다가 key가 털리게 되면 현재 해당 계정에 있는 모든 aws의 리소스가 털릴 위험이 있기 때문이다.

그래서 IAM에서 사용자를 만들어 만약 key가 털려도 사용자를 삭제하면 그만이기 때문에 이렇게 사용하도록 권장하고 있다. 이제 설정해보자.

  1. IAM을 검색해 들어간 다음, 사용자 를 클릭한다.
  2. 사용자 추가를 클릭한다.
  3. 사용자 이름을 설정한 뒤, 엑세스 키는 프로그래밍 방식 엑세스를 선택한다.
  4. 권한에서 이제 AWS S3에 접근하는 사용자를 만들어주자. 다음과 같이 클릭해 권한을 넣어준다.

  1. 키는 그냥 넘긴다. 그리고 사용자를 만들어본다.
  2. 그러면 밑에 그림과 같이 엑세스 키ID비밀 엑세스 키 가 뜬다. 이는 현재 화면에서 밖에 뜨지 않고 나중에 다시 볼 수 없다. 꼭꼭!!! 어딘가 저장해두자. 잃어버리면 다시 생성해야한다.

  1. 이제 모든 설정이 끝이났다. s3에 연동해보자.

Flask - S3연동

우리 프로젝트에서는 S3에서 이미지 업로드를 한 번 하고 이미지 url만 가져오는 것이 다이기에 그냥 python과 s3연동이라고 봐도 무방하다.

쨋든, python에서는 s3와 연동하기 위한 라이브러리 boto3 라는게 있다. 이를 설치하자.

pip3 install boto3

이러면 사전 준비는 끝이났다. 연동해보자.

import boto3

def s3_connection():
    try:
        s3 = boto3.client(
            service_name="s3",
            region_name="ap-northeast-2", # 자신이 설정한 bucket region
            aws_access_key_id={엑세스 키 ID},
            aws_secret_access_key={비밀 엑세스 키},
        )
    except Exception as e:
        print(e)
    else:
        print("s3 bucket connected!")
        return s3

s3 = s3_connection()

이러면 s3와 연동이 된다. 이제 upload하는 방식을 알아보자.

def s3_put_object(s3, bucket, filepath, access_key):
    """
    s3 bucket에 지정 파일 업로드
    :param s3: 연결된 s3 객체(boto3 client)
    :param bucket: 버킷명
    :param filepath: 파일 위치
    :param access_key: 저장 파일명
    :return: 성공 시 True, 실패 시 False 반환
    """
    try:
        s3.upload_file(
            Filename=filepath,
            Bucket=bucket,
            Key=access_key,
            ExtraArgs={"ContentType": "image/jpg", "ACL": "public-read"},
        )
    except Exception as e:
        return False
    return True

upload된 이미지 url을 가져오는 방법이다.

def s3_get_image_url(s3, filename):
    """
    s3 : 연결된 s3 객체(boto3 client)
    filename : s3에 저장된 파일 명
    """
    location = s3.get_bucket_location(Bucket={자신이 설정한 버킷 이름})["LocationConstraint"]
    return f"https://{{자신이 설정한 버킷 이름}}.s3.{location}.amazonaws.com/{filename}.jpg"
profile
강한 백엔드 개발자가 되기 위한 여정

0개의 댓글