AWS API의 동작 방식과 boto3 (python sdk)로 프로그래밍 하는 방법
먼저 vscode 익스텐션에서 boto3 설치 후 cmd + shift + p 로 boto3 검색 후 아래처럼 boto3, ec2 체크 후 ok

vscode에서 py 파일을 하나 작성해주자
import boto3
ec2 = boto3.client("ec2")
boto3.client("aws_service") 형식으로 사용하면 된다. 이제 EBS volume을 생성해보자
EC2 - Boto3 1.34.145 documentation
Previous start_snapshot
boto3.amazonaws.com
해당 링크에 보면 ec2에서 사용할 수 있는 메서드들이 있다. 먼저 volume을 생성해야되니 create_volume을 검색해보자

검색해보면 Request Syntax가 나오고 아래 사용할 수 있는 파라미터들이 나온다. AvailabilityZone만 required이니 해당 파라미터만 사용해서 volume을 생성해보자
import boto3
ec2 = boto3.client("ec2")
ec2.create_volume(
AvailabilityZone="ap-northeast-2a",
Size=1,
)
비용이 나오니 1G로 지정해서 생성하자. 참고로 사전에 자격증명은 되어있어야 한다.

이제 코드를 실행해보면 실제로 volume이 생성된다. 이제 volume을 확인하기 위해 describe_volumes을 사용해보겠다.

describe_volumes의 response syntax를 보니 "Volumes"가 있다. print로 바로 출력해도 되고, 반복문을 돌려도 된다.
나같은 경우엔 보통 필요한 값만 출력하기 위해 반복문을 많이 사용하는 편이다.
from pprint import pprint
import boto3
ec2 = boto3.client("ec2")
# create ebs volume
# ec2.create_volume(
# AvailabilityZone="ap-northeast-2a",
# Size=1,
# )
for volume in ec2.describe_volumes()["Volumes"]:
pprint(volume)
create_volume 부분은 주석처리하고 코드를 실행해보면 아래와 같이 volume에 대한 정보를 얻을 수 있다.

volume 삭제도 마찬가지로 delete_volume 메서드를 사용하면 된다. 참고로 VolumeID는 required 파라미터이다.
콘솔에서 확인할 수도 있지만, describe_volumes에서 volumeID를 가져와서 delete_volume VolumeID에 넘겨줄 수도 있다.
from pprint import pprint
import boto3
ec2 = boto3.client("ec2")
# create ebs volume
# ec2.create_volume(
# AvailabilityZone="ap-northeast-2a",
# Size=1,
# )
# describe volume
# for volume in ec2.describe_volumes()["Volumes"]:
# pprint(volume["VolumeId"])
ec2.delete_volume(VolumeId=ec2.describe_volumes()["Volumes"][0]["VolumeId"])
실행 후 콘솔에서 확인해보면 volume이 삭제된걸 확인할 수 있다.

paginator도 사용해보자
from pprint import pprint
import boto3
ec2 = boto3.client("ec2")
# create ebs volume
ec2.create_volume(
AvailabilityZone="ap-northeast-2a",
Size=1,
)
# describe volume
# for volume in ec2.describe_volumes()["Volumes"]:
# pprint(volume["VolumeId"])
# ec2.delete_volume(VolumeId=ec2.describe_volumes()["Volumes"][0]["VolumeId"])
iterator = ec2.get_paginator("describe_volumes").paginate()
for volumes in iterator:
for volume in volumes["Volumes"]:
print(volume["VolumeId"])
ec2.get_paginator로 호출할 수 있고, iterator 즉 반복할 수 있는 값이 나오게 된다. 다만 for문을 2번 돌아야되는 단점이 있다.
기존에 volume을 삭제했으니 다시 생성해주는 코드 주석을 해제하고 실행해보면 volumeID가 출력된다.
이제 타입에 대해 알아보자. 파이썬에 대한 지식이 없으면 이해하기 어려우니, 그냥 넘어가도 된다.

현재 코드를 보면 ec2 client에 EC2Client가 회색 음영으로 표시되는데, 더블 클릭하면 자동으로 만들어 준다.

이 타입을 알려고 할 때 boto3.client("ec2")에서 client에 커서를 갖다 대면 EC2Client가 나온다.
커맨드 키로 한번 클라이언트를 따라가 보자

그럼 아래처럼 client가 나오게 되는데, 여기서 .client도 따라가보면 BaseClient가 나오게 된다.


하지만 우린 EC2Client가 어딨는지 알고 싶은거지 BaseClient를 알고 싶은건 아니다.
기존 코드에 from mypy_boto3_ec2를 한번 해보고 커서로 따라가서 EC2Client를 검색해보자

그럼 EC2Client가 나오는데, 보면 지금 mypy_boto3_ec2에 바로 EC2Client가 있는걸 볼 수 있다.
그러면 from mypy_boto3_ec2 import EC2Client 이렇게 import 해줄 수가 있다. 그리고 이 EC2Client를 따라가보면

BaseClient를 상속 받는걸 알 수 있다. 한번 더 따라가보면, BaseClient의 위치가 botocore의 client 밑에 있는걸 확인할 수 있다.

그러면 from botocore.client import BaseClient 이렇게 해서 EC2Client 대신 BaseClient를 사용할 수도 있다.

한가지만 더 확인해보자

기존 코드를 약간 수정하여 volumes 변수로 describe_volumes를 빼주었다. 그럼 volumes에 List[VolumeTypeDef] 이라고 나온다.
describe_volumes를 따라가면 DescribeVolumesResultTypeDef이 있고, 얘를 따라가면 TypedDict로 만들어져 있다.

여기서 List[VolumeTypeDef] 을 따라가보면, VolumeTypeDef이 mypy_boto3_ec2 밑에 type_defs에 있는걸 알 수 있다.


from mypy_boto3_ec2.type_defs import VolumeTypeDef 을 해주고, from typing import List 까지 해주면 에러가 사라진다.

하지만 여전히 delete_volume 부분은 에러 상태인데, 위에서 VolumeTypeDef을 살펴 보면 VolumeID도 NotRequired라고 나온다.
mypy가 boto3와 다르게 아주 정확하진 않다.
하지만 이런 경우엔 이렇게 생각해볼 수 있다. volumes에 값이 없으면 어차피 volume까지 오지 않는다.
그렇기 때문에 이런 경우엔 # type: ignore로 에러를 없앨 수도 있다.
아니면 get을 써도 되는데, delete_volume에서 VolumeID는 required인데 get은 none을 반환하니 그냥 편하게 type: ignore을 사용하는게 좋지 않을까 싶다.

'AWS' 카테고리의 다른 글
| [AWS] aws sts & assume role - (2) (0) | 2024.08.12 |
|---|---|
| [AWS] aws sts & assume role - (1) (0) | 2024.07.26 |
| [AWS] Secrets Manager (0) | 2024.06.27 |
| [AWS] Budgets로 비용 모니터링 (0) | 2024.05.29 |
| [AWS] Cloudwatch 로그 슬랙 전송하기 #2 (0) | 2024.05.28 |