목표
Cloud Storage는 GCP에서 오브젝트 스토리지 용도로 다양하게 활용되고 있습니다.
특성상 Dev, Stg, Prd 등 여러 환경에 걸쳐 여러 프로젝트에 분산되어 생성되며, Cloud Run과 같은 PaaS 서비스를 사용할 경우 자동으로 버킷이 생성되기도 합니다.
이처럼 다양한 위치에 버킷이 존재하다 보니, 전체 현황을 한눈에 파악할 수 있는 방법이 필요합니다.
이 문서에서는 webconsole의 GUI를 통해 스토리지 리스트를 조회하는 방법과, 쉘 스크립트를 이용해 각 버킷의 용량 및 메타 정보를 수집하는 방법을 소개합니다.
🧰 방법 1: GUI로 전체 버킷 리스트 확인
GCP 콘솔 접속 → Cloud Asset Inventory 메뉴로 이동
조직 선택 후→ storage.Bucket 으로 리소스 필터
조직 선택 후→ storage.Bucket 으로 리소스 필터


필요 시 CSV로 내보내기
🧰 방법 2: 쉘 스크립트로 전체 버킷 및 사용량/라벨 정보 조회
GUI방법과 큰 차이점은 리스트 후 gsutil du 명령을 통해 사용량을 조회 하는 부분입니다.
⚠️ 유의
gsutil du 명령이 많은 시간과 권한을 요구할 수 있어
장시간 실행이 필요할 수 있습니다.
만약 사용량이 아닌 Stoage 리스트만 필요하다면 방법1을 추천합니다.
GUI방법과 큰 차이점은 리스트 후 gsutil du 명령을 통해 사용량을 조회 하는 부분입니다.
⚠️ 유의
gsutil du 명령이 많은 시간과 권한을 요구할 수 있어
장시간 실행이 필요할 수 있습니다.
만약 사용량이 아닌 Stoage 리스트만 필요하다면 방법1을 추천합니다.
#!/bin/bash
# --- 설정 ---
read -p "대상 조직 ID를 입력하세요 (예: 1234567890): " ORGANIZATION_ID
if [[ -z "$ORGANIZATION_ID" ]]; then
echo "오류: 조직 ID가 입력되지 않았습니다."
exit 1
fi
echo "사용할 조직 ID: $ORGANIZATION_ID"
OUTPUT_CSV_FILE="gcs_bucket_list_with_size_${ORGANIZATION_ID}.csv"
SLEEP_DURATION=1
# --- 설정 끝 ---
# --- 1단계: 프로젝트 ID <-> 프로젝트 이름 매핑 생성 ---
echo "조직 '$ORGANIZATION_ID' 내 모든 활성 프로젝트 목록 및 이름 가져오는 중 (폴더 포함)..."
project_list_json=$(gcloud projects list --filter='lifecycleState=ACTIVE' --format='json' --quiet)
if [[ $? -ne 0 ]] || [[ -z "$project_list_json" ]]; then
echo "오류: 조직 '$ORGANIZATION_ID'에서 활성 프로젝트 목록을 가져오는 데 실패했습니다. (종료 코드: $?)"
exit 1
fi
declare -A project_names
while IFS= read -r project_json || [[ -n "$project_json" ]]; do
if [[ -z "$project_json" ]]; then continue; fi
p_id=$(echo "$project_json" | jq -r '.projectId // empty')
p_name=$(echo "$project_json" | jq -r '.name // empty')
if [[ -n "$p_id" ]] && [[ -n "$p_name" ]]; then
project_names["$p_id"]="$p_name"
fi
done < <(echo "$project_list_json" | jq -c '.[]')
project_count=${#project_names[@]}
echo "프로젝트 이름 매핑 준비 완료 (${project_count}개 프로젝트)."
# --- 1단계 끝 ---
# --- 2단계: 버킷 목록 조회 및 크기 조회 (gsutil 사용), 결과 조합 ---
echo "조직 '$ORGANIZATION_ID' 내 스토리지 버킷 정보 및 사용량 조회 시작..."
echo "*** 경고: 각 버킷의 사용량 조회(gsutil du)로 인해 매우 오랜 시간이 소요될 수 있습니다. ***"
echo '"BucketName","ProjectName","Location","BucketSize"' > "$OUTPUT_CSV_FILE"
echo "BucketName, ProjectName, Location, BucketSize"
echo "--------------------------------------------------"
gcloud asset search-all-resources \
--scope="organizations/$ORGANIZATION_ID" \
--asset-types='storage.googleapis.com/Bucket' \
--page-size=500 \
--format='json' | \
jq -c '.[]' | \
while IFS= read -r bucket_json || [[ -n "$bucket_json" ]]; do
if [[ -z "$bucket_json" ]]; then continue; fi
bucket_name=$(echo "$bucket_json" | jq -r '(.name | split("/") | last) // empty')
project_id=$(echo "$bucket_json" | jq -r '(.parentFullResourceName | split("/") | last) // empty')
location=$(echo "$bucket_json" | jq -r '.location // "N/A"')
if [[ -z "$bucket_name" ]] || [[ -z "$project_id" ]]; then
echo "경고: 잘못된 버킷 정보 (JSON: $bucket_json)" >&2
continue
fi
project_name="${project_names[$project_id]}"
if [[ -z "$project_name" ]]; then
project_name="($project_id - 이름 조회 불가)"
fi
# !!!!! 버킷 크기 조회 (gsutil du 사용) !!!!!
echo " -> 버킷 '$bucket_name' 크기 조회 중 (gsutil du 사용)..."
# '-s' : 합계, '-h' : 사람이 읽기 쉬운 단위
# 오류 발생 시 stderr 로 메시지 출력될 수 있음 -> 2>/dev/null 로 숨김
# gsutil 명령어 자체의 종료 코드 확인
bucket_size_output=$(gsutil du -s -h "gs://$bucket_name" 2>/dev/null)
gsutil_exit_code=$?
bucket_size="N/A" # 기본값
if [[ $gsutil_exit_code -eq 0 ]] && [[ -n "$bucket_size_output" ]]; then
# 성공 시 출력에서 크기 부분만 추출 (첫 번째 필드)
# 출력 예시: "1.23 GiB gs://bucket-name" 또는 "0 B gs://empty-bucket"
# 공백(space/tab) 기준으로 첫번째 필드 추출2
bucket_size=$(echo "$bucket_size_output" | awk '{print $1}')
# 크기가 0일 때 awk가 빈 문자열을 반환할 수도 있으므로, 0 B 로 처리
if [[ -z "$bucket_size" ]] && [[ "$bucket_size_output" == 0* ]]; then
bucket_size="0 B"
elif [[ -z "$bucket_size" ]]; then
# 예상치 못한 출력 형식일 경우 대비
echo " 경고: gsutil du 출력 형식 예상과 다름: $bucket_size_output" >&2
bucket_size="Parse Error"
fi
else
# gsutil du 실패 시
echo " 경고: 버킷 '$bucket_name' 크기 조회 실패 (gsutil 종료 코드: $gsutil_exit_code). 권한 또는 버킷 상태 확인 필요." >&2
# 종료 코드 1은 보통 버킷 없음 또는 권한 문제
if [[ $gsutil_exit_code -eq 1 ]]; then
bucket_size="Access Denied/Not Found"
else
bucket_size="Error ($gsutil_exit_code)"
fi
fi
echo " 크기: $bucket_size"
# !!!!! 버킷 크기 조회 끝 !!!!!
# --- 결과 출력 ---
echo "$bucket_name / $project_name / $location / $bucket_size"
printf '"%s","%s","%s","%s"\n' \
"$(echo "$bucket_name" | sed 's/"/""/g')" \
"$(echo "$project_name" | sed 's/"/""/g')" \
"$(echo "$location" | sed 's/"/""/g')" \
"$(echo "$bucket_size" | sed 's/"/""/g')" >> "$OUTPUT_CSV_FILE"
echo " (${SLEEP_DURATION}초 대기...)"
sleep "$SLEEP_DURATION"
done
pipe_status=("${PIPESTATUS[@]}")
gcloud_asset_exit_code=${pipe_status[0]}
jq_exit_code=${pipe_status[1]}
if [[ $gcloud_asset_exit_code -ne 0 ]]; then
echo "경고: gcloud asset search-all-resources 명령 실행 중 오류 발생 (종료 코드: $gcloud_asset_exit_code)" >&2
fi
if [[ $jq_exit_code -ne 0 ]]; then
echo "경고: jq 명령 실행 중 오류 발생 (종료 코드: $jq_exit_code)" >&2
fi
echo "--------------------------------------------------"
echo "버킷 정보 및 사용량 조회가 완료되었습니다."
echo "결과가 화면에 출력되었고, '$OUTPUT_CSV_FILE' 파일에 저장되었습니다."
# --- 2단계 끝 ---
exit 0
라벨 정보 추가 출력시
#!/bin/bash
# --- 설정 ---
read -p "대상 조직 ID를 입력하세요 (예: 1234567890): " ORGANIZATION_ID
if [[ -z "$ORGANIZATION_ID" ]]; then
echo "오류: 조직 ID가 입력되지 않았습니다."
exit 1
fi
echo "사용할 조직 ID: $ORGANIZATION_ID"
OUTPUT_CSV_FILE="gcs_bucket_list_with_details_${ORGANIZATION_ID}.csv"
SLEEP_DURATION=1
# --- 설정 끝 ---
# --- 1단계: 프로젝트 ID <-> 프로젝트 이름 매핑 생성 ---
echo "조직 '$ORGANIZATION_ID' 내 모든 활성 프로젝트 목록 및 이름 가져오는 중 (폴더 포함)..."
project_list_json=$(gcloud projects list --filter='lifecycleState=ACTIVE' --format='json' --quiet)
if [[ $? -ne 0 ]] || [[ -z "$project_list_json" ]]; then
echo "오류: 조직 '$ORGANIZATION_ID'에서 활성 프로젝트 목록을 가져오는 데 실패했습니다. (종료 코드: $?)"
exit 1
fi
declare -A project_names
while IFS= read -r project_json || [[ -n "$project_json" ]]; do
if [[ -z "$project_json" ]]; then continue; fi
p_id=$(echo "$project_json" | jq -r '.projectId // empty')
p_name=$(echo "$project_json" | jq -r '.name // empty')
if [[ -n "$p_id" ]] && [[ -n "$p_name" ]]; then
project_names["$p_id"]="$p_name"
fi
done < <(echo "$project_list_json" | jq -c '.[]')
project_count=${#project_names[@]}
echo "프로젝트 이름 매핑 준비 완료 (${project_count}개 프로젝트)."
# --- 1단계 끝 ---
# --- 2단계: 버킷 목록 조회, 크기 조회, 라벨 추출, 결과 조합 ---
echo "조직 '$ORGANIZATION_ID' 내 스토리지 버킷 정보, 사용량, 라벨 조회 시작..."
echo "*** 경고: 각 버킷의 사용량 조회(gsutil du)로 인해 매우 오랜 시간이 소요될 수 있습니다. ***"
echo '"BucketName","ProjectName","Location","BucketSize","Labels"' > "$OUTPUT_CSV_FILE"
echo "BucketName, ProjectName, Location, BucketSize, Labels"
echo "---------------------------------------------------------"
gcloud asset search-all-resources \
--scope="organizations/$ORGANIZATION_ID" \
--asset-types='storage.googleapis.com/Bucket' \
--page-size=500 \
--format='json' | \
jq -c '.[]' | \
while IFS= read -r bucket_json || [[ -n "$bucket_json" ]]; do
if [[ -z "$bucket_json" ]]; then continue; fi
bucket_name=$(echo "$bucket_json" | jq -r '(.name | split("/") | last) // empty')
project_id=$(echo "$bucket_json" | jq -r '(.parentFullResourceName | split("/") | last) // empty')
location=$(echo "$bucket_json" | jq -r '.location // "N/A"')
# !!!!! 라벨 정보 추출 (jq 명령어 수정) !!!!!
labels=$(echo "$bucket_json" | jq -r '.labels | if type=="object" then to_entries | map("\(.key)=\(.value|tostring)") | join(";") else "" end')
# !!!!! 라벨 정보 추출 끝 !!!!!
if [[ -z "$bucket_name" ]] || [[ -z "$project_id" ]]; then
echo "경고: 잘못된 버킷 정보 (JSON: $bucket_json)" >&2
continue
fi
project_name="${project_names[$project_id]}"
if [[ -z "$project_name" ]]; then
project_name="($project_id - 이름 조회 불가)"
fi
# 버킷 크기 조회 (gsutil du 사용)
echo " -> 버킷 '$bucket_name' 크기 조회 중 (gsutil du 사용)..."
bucket_size_output=$(gsutil du -s -h "gs://$bucket_name" 2>/dev/null)
gsutil_exit_code=$?
bucket_size="N/A"
if [[ $gsutil_exit_code -eq 0 ]] && [[ -n "$bucket_size_output" ]]; then
bucket_size=$(echo "$bucket_size_output" | awk '{print $1}')
if [[ -z "$bucket_size" ]] && [[ "$bucket_size_output" == 0* ]]; then
bucket_size="0 B"
elif [[ -z "$bucket_size" ]]; then
bucket_size="Parse Error"
fi
else
echo " 경고: 버킷 '$bucket_name' 크기 조회 실패 (gsutil 종료 코드: $gsutil_exit_code)." >&2
if [[ $gsutil_exit_code -eq 1 ]]; then bucket_size="Access Denied/Not Found"; else bucket_size="Error ($gsutil_exit_code)"; fi
fi
echo " 크기: $bucket_size"
# --- 결과 출력 (라벨 포함) ---
echo "$bucket_name / $project_name / $location / $bucket_size / $labels"
printf '"%s","%s","%s","%s","%s"\n' \
"$(echo "$bucket_name" | sed 's/"/""/g')" \
"$(echo "$project_name" | sed 's/"/""/g')" \
"$(echo "$location" | sed 's/"/""/g')" \
"$(echo "$bucket_size" | sed 's/"/""/g')" \
"$(echo "$labels" | sed 's/"/""/g')" >> "$OUTPUT_CSV_FILE"
echo " (${SLEEP_DURATION}초 대기...)"
sleep "$SLEEP_DURATION"
done
pipe_status=("${PIPESTATUS[@]}")
gcloud_asset_exit_code=${pipe_status[0]}
jq_exit_code=${pipe_status[1]}
if [[ $gcloud_asset_exit_code -ne 0 ]]; then
echo "경고: gcloud asset search-all-resources 명령 실행 중 오류 발생 (종료 코드: $gcloud_asset_exit_code)" >&2
fi
# jq 종료 코드는 파이프라인 마지막 요소이므로 pipe_status[1] 대신 $? 로도 확인 가능
if [[ $jq_exit_code -ne 0 ]] && [[ $jq_exit_code -ne 4 ]]; then # jq exit code 4 means no input, which is ok if no buckets found
echo "경고: jq 명령 실행 중 오류 발생 (종료 코드: $jq_exit_code)" >&2
fi
echo "---------------------------------------------------------"
echo "버킷 정보, 사용량, 라벨 조회가 완료되었습니다."
echo "결과가 화면에 출력되었고, '$OUTPUT_CSV_FILE' 파일에 저장되었습니다."
# --- 2단계 끝 ---
exit 0
스크립트 실행 후 CSV 출력형식

📝 마무리
GCP 조직 내 전체 Cloud Storage 버킷을 한눈에 관리하고자 하는 담당자에게 도움이 되길 바랍니다.
GCP 조직 내 전체 Cloud Storage 버킷을 한눈에 관리하고자 하는 담당자에게 도움이 되길 바랍니다.
'Cloud > GCP' 카테고리의 다른 글
[GCP] VM기준으로 방화벽 내용을 조회 하는 스크립트 (0) | 2025.04.19 |
---|---|
GCP Asset Inventory로 내부 자산인 GCE(VM) 확인하기 (0) | 2025.04.09 |
[GCP] STS(Storage Transfer Service) Agent 설치, 설정 (0) | 2025.03.14 |
On-premise 환경에서 GCP의 Private Google Access(PGA) 사용하기 – DNS Forward 방안 (2) | 2025.03.03 |
On-premise 환경에서 GCP의 Private Google Access(PGA) 사용하기 – DNS 설정 가이드 (0) | 2025.02.26 |
[GCP] Cloud Site to Site VPN을 위한 strongswan(openvpn), Cloud VPN 설정방안 (4) | 2025.02.25 |
GCE, GCS, Bigquery Audit Log 확인 (0) | 2025.02.18 |